@eifi1/ui-kit 0.17.0 → 0.18.0
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/README.md +29 -4
- package/dist/chart.d.ts +10 -1
- package/dist/components/account-chips.d.ts +153 -0
- package/dist/components/account-chips.js +135 -0
- package/dist/components/account-chips.js.map +1 -0
- package/dist/components/account-settings-labels.d.ts +10 -2
- package/dist/components/account-settings-labels.js +3 -0
- package/dist/components/account-settings-labels.js.map +1 -1
- package/dist/components/amount-input.d.ts +10 -1
- package/dist/components/button-group.d.ts +10 -1
- package/dist/components/calculator.d.ts +10 -1
- package/dist/components/chip.d.ts +25 -1
- package/dist/components/chip.js +143 -6
- package/dist/components/chip.js.map +1 -1
- package/dist/components/confirm-dialog.d.ts +42 -1
- package/dist/components/confirm-dialog.js +36 -5
- package/dist/components/confirm-dialog.js.map +1 -1
- package/dist/components/copy-button.d.ts +10 -1
- package/dist/components/danger-confirm.d.ts +55 -4
- package/dist/components/danger-confirm.js +67 -30
- package/dist/components/danger-confirm.js.map +1 -1
- package/dist/components/data-table-cells.d.ts +1 -1
- package/dist/components/data-table-filter-popover.d.ts +1 -1
- package/dist/components/data-table-filters.d.ts +1 -1
- package/dist/components/data-table.d.ts +1 -1
- package/dist/components/data-table.js +2 -0
- package/dist/components/data-table.js.map +1 -1
- package/dist/components/facing-pair.d.ts +10 -1
- package/dist/components/file-button.d.ts +10 -1
- package/dist/components/file-dropzone.d.ts +10 -1
- package/dist/components/form-actions.d.ts +10 -1
- package/dist/components/form-actions.js +3 -0
- package/dist/components/form-actions.js.map +1 -1
- package/dist/components/money-field.d.ts +10 -1
- package/dist/components/number-field.d.ts +11 -2
- package/dist/components/number-field.js +23 -22
- package/dist/components/number-field.js.map +1 -1
- package/dist/components/number-input.d.ts +10 -1
- package/dist/components/numpad-sheet.d.ts +10 -1
- package/dist/components/passkeys-setting.d.ts +27 -1
- package/dist/components/passkeys-setting.js +31 -5
- package/dist/components/passkeys-setting.js.map +1 -1
- package/dist/components/progress-bar.d.ts +15 -1
- package/dist/components/progress-bar.js +8 -1
- package/dist/components/progress-bar.js.map +1 -1
- package/dist/components/reauth-dialog.d.ts +90 -0
- package/dist/components/reauth-dialog.js +158 -0
- package/dist/components/reauth-dialog.js.map +1 -0
- package/dist/components/series-chart.d.ts +10 -1
- package/dist/components/server-wake.d.ts +58 -0
- package/dist/components/server-wake.js +58 -0
- package/dist/components/server-wake.js.map +1 -0
- package/dist/components/settings-fields.d.ts +10 -1
- package/dist/components/share-card.d.ts +61 -0
- package/dist/components/share-card.js +350 -0
- package/dist/components/share-card.js.map +1 -0
- package/dist/components/status-dot.d.ts +2 -0
- package/dist/components/text-link.d.ts +10 -1
- package/dist/components/time-input.d.ts +10 -1
- package/dist/components/toast.d.ts +10 -1
- package/dist/components/toast.js +42 -2
- package/dist/components/toast.js.map +1 -1
- package/dist/components/toggle-group.js +5 -2
- package/dist/components/toggle-group.js.map +1 -1
- package/dist/components/ui.d.ts +10 -1
- package/dist/components/ui.js +43 -28
- package/dist/components/ui.js.map +1 -1
- package/dist/components/use-table-state.d.ts +1 -1
- package/dist/components/user-avatar.d.ts +2 -0
- package/dist/components/write-lock.d.ts +68 -0
- package/dist/components/write-lock.js +33 -0
- package/dist/components/write-lock.js.map +1 -0
- package/dist/{data-table-CpkWUJBY.d.ts → data-table-3mi2R3so.d.ts} +19 -1
- package/dist/data-table.d.ts +1 -1
- package/dist/hooks/use-file-drop.d.ts +10 -1
- package/dist/hooks/use-overlay-history.js +16 -0
- package/dist/hooks/use-overlay-history.js.map +1 -1
- package/dist/i18n/defaults.d.ts +10 -1
- package/dist/i18n/defaults.js +11 -1
- package/dist/i18n/defaults.js.map +1 -1
- package/dist/i18n/german.d.ts +78 -0
- package/dist/i18n/{locales/de.js → german.js} +59 -9
- package/dist/i18n/german.js.map +1 -0
- package/dist/i18n/kit-labels.d.ts +10 -1
- package/dist/i18n/kit-labels.js +5 -0
- package/dist/i18n/kit-labels.js.map +1 -1
- package/dist/i18n/locales/de-CH.d.ts +23 -8
- package/dist/i18n/locales/de-CH.js +7 -3
- package/dist/i18n/locales/de-CH.js.map +1 -1
- package/dist/i18n/locales/en.d.ts +10 -1
- package/dist/i18n/locales/es.d.ts +10 -1
- package/dist/i18n/locales/es.js +51 -1
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.d.ts +10 -1
- package/dist/i18n/locales/fr.js +51 -1
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hu.d.ts +10 -1
- package/dist/i18n/locales/hu.js +54 -1
- package/dist/i18n/locales/hu.js.map +1 -1
- package/dist/i18n/locales/it.d.ts +10 -1
- package/dist/i18n/locales/it.js +51 -1
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/zh.d.ts +10 -1
- package/dist/i18n/locales/zh.js +50 -1
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/i18n/swiss.d.ts +3 -3
- package/dist/i18n/swiss.js.map +1 -1
- package/dist/index.d.ts +9 -4
- package/dist/index.js +33 -1
- package/dist/index.js.map +1 -1
- package/dist/{kit-labels-C4uB_zmg.d.ts → kit-labels-CPbsjlXr.d.ts} +229 -9
- package/dist/lib/server-wake.d.ts +130 -0
- package/dist/lib/server-wake.js +121 -0
- package/dist/lib/server-wake.js.map +1 -0
- package/dist/rhf/fields.d.ts +10 -1
- package/dist/rhf/form.d.ts +10 -1
- package/dist/rhf.d.ts +10 -1
- package/dist/search/global-search.d.ts +3 -1
- package/dist/search/global-search.js.map +1 -1
- package/dist/shell/app-shell.d.ts +10 -1
- package/dist/shell/top-bar-brand.d.ts +10 -1
- package/dist/shell/topbar-action-menu.d.ts +2 -0
- package/dist/shell.d.ts +10 -1
- package/dist/wizard/stepper-nav.d.ts +10 -1
- package/dist/wizard.d.ts +10 -1
- package/package.json +1 -1
- package/src/components/account-chips.tsx +302 -0
- package/src/components/account-settings-labels.ts +16 -2
- package/src/components/chip.tsx +239 -6
- package/src/components/confirm-dialog.tsx +82 -7
- package/src/components/danger-confirm.tsx +118 -33
- package/src/components/data-table.tsx +20 -0
- package/src/components/form-actions.tsx +22 -3
- package/src/components/number-field.tsx +32 -26
- package/src/components/passkeys-setting.tsx +68 -7
- package/src/components/progress-bar.tsx +21 -1
- package/src/components/reauth-dialog.tsx +273 -0
- package/src/components/server-wake.tsx +124 -0
- package/src/components/share-card.tsx +615 -0
- package/src/components/toast.tsx +72 -2
- package/src/components/toggle-group.tsx +5 -2
- package/src/components/ui.tsx +89 -32
- package/src/components/write-lock.tsx +96 -0
- package/src/hooks/use-overlay-history.ts +51 -0
- package/src/i18n/defaults.ts +10 -0
- package/src/i18n/{locales/de.ts → german.ts} +68 -13
- package/src/i18n/kit-labels.tsx +22 -2
- package/src/i18n/locales/de-CH.ts +17 -8
- package/src/i18n/locales/es.ts +51 -0
- package/src/i18n/locales/fr.ts +52 -0
- package/src/i18n/locales/hu.ts +55 -0
- package/src/i18n/locales/it.ts +51 -0
- package/src/i18n/locales/zh.ts +50 -0
- package/src/i18n/swiss.ts +3 -3
- package/src/index.ts +23 -1
- package/src/lib/server-wake.ts +270 -0
- package/src/search/global-search.tsx +3 -1
- package/dist/i18n/locales/de-CH-informal.d.ts +0 -61
- package/dist/i18n/locales/de-CH-informal.js +0 -8
- package/dist/i18n/locales/de-CH-informal.js.map +0 -1
- package/dist/i18n/locales/de-informal.d.ts +0 -82
- package/dist/i18n/locales/de-informal.js +0 -37
- package/dist/i18n/locales/de-informal.js.map +0 -1
- package/dist/i18n/locales/de.d.ts +0 -66
- package/dist/i18n/locales/de.js.map +0 -1
- package/src/i18n/locales/de-CH-informal.ts +0 -10
- package/src/i18n/locales/de-informal.ts +0 -61
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Is the server asleep, or is the app broken?" — the cold-start watchdog, lifted
|
|
3
|
+
* from keksdose (feedback #199) so kastlan and Kurvenschmiede get it too.
|
|
4
|
+
*
|
|
5
|
+
* All three backends run on Cloud Run with `--min-instances=0`: after an idle
|
|
6
|
+
* period the container is gone and the first request has to start it, which takes
|
|
7
|
+
* several seconds and occasionally more. Nothing in the UI said so, and none of the
|
|
8
|
+
* axios instances has a timeout, so the honest experience was a spinner that looked
|
|
9
|
+
* stuck. This counts the in-flight requests a cold start would actually delay and
|
|
10
|
+
* escalates in two steps, so a merely slow response says "still loading" and only a
|
|
11
|
+
* genuinely long wait blames the sleeping server.
|
|
12
|
+
*
|
|
13
|
+
* Framework-free on purpose (no zustand, no axios, no React): a counter, two timers
|
|
14
|
+
* and a listener set, read by `useServerWakeStage` through `useSyncExternalStore`.
|
|
15
|
+
* The adapters below take the app's axios instance / fetch as an ARGUMENT, so the
|
|
16
|
+
* kit never imports either.
|
|
17
|
+
*
|
|
18
|
+
* WHAT ARMS IT, and why the default is narrow:
|
|
19
|
+
* - reads (GET) — what every page does on open — always;
|
|
20
|
+
* - writes only when the app says so (`watchReadsAnd(/\/auth\/login\b/)`): the
|
|
21
|
+
* auth POSTs that gate the app are the only writes a user waits on before the
|
|
22
|
+
* app exists at all, so a cold start there looks exactly like a broken login.
|
|
23
|
+
* An UPLOAD must never be watched — a statement PDF or a photo takes seconds on a
|
|
24
|
+
* perfectly warm server, and "the server is waking up" during a 4 s upload would
|
|
25
|
+
* simply be false. With the default that holds by itself (an upload is a POST);
|
|
26
|
+
* an app widening `shouldWatch` keeps its upload routes out of it.
|
|
27
|
+
*
|
|
28
|
+
* It never arms while the browser is offline, whatever `shouldWatch` says: that state
|
|
29
|
+
* has its own, truthful indicator, and a request that never left the device is not
|
|
30
|
+
* evidence of anything about the server.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/** `slow` = longer than a warm server ever takes; `waking` = long enough that a cold
|
|
34
|
+
* start is the only sensible explanation. */
|
|
35
|
+
export type ServerWakeStage = "idle" | "slow" | "waking";
|
|
36
|
+
|
|
37
|
+
/** Decides which requests count. `method` arrives lower-cased (`"get"` when the
|
|
38
|
+
* request named none — axios's and fetch's default); `url` as the client had it. */
|
|
39
|
+
export type ServerWakeFilter = (method: string, url: string) => boolean;
|
|
40
|
+
|
|
41
|
+
export interface ServerWakeOptions {
|
|
42
|
+
/** Past this, a warm round trip is out of the question (a cold database query on a
|
|
43
|
+
* free tier can still take a second, so it is not tighter). Default 2000 ms. */
|
|
44
|
+
slowMs?: number;
|
|
45
|
+
/** Past this, the container was almost certainly scaled to zero. Default 7000 ms. */
|
|
46
|
+
wakingMs?: number;
|
|
47
|
+
/** Which requests count. Default {@link watchReadsAnd}`()` — GETs only. The offline
|
|
48
|
+
* guard runs before it and cannot be overridden. */
|
|
49
|
+
shouldWatch?: ServerWakeFilter;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** What a request is, for {@link ServerWakeWatcher.track}. */
|
|
53
|
+
export interface ServerWakeRequest {
|
|
54
|
+
method?: string;
|
|
55
|
+
url?: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface ServerWakeWatcher {
|
|
59
|
+
/**
|
|
60
|
+
* Count a request that is going out, and arm the escalation if it is the first.
|
|
61
|
+
* Returns whether it was counted — the caller MUST call {@link end} exactly once
|
|
62
|
+
* for every `true`, or the counter never returns to zero and the notice sticks.
|
|
63
|
+
* (The axios adapter stashes it on the request config for that reason.)
|
|
64
|
+
*/
|
|
65
|
+
start(method?: string, url?: string): boolean;
|
|
66
|
+
/** A counted request settled — either way: an error still proves the server
|
|
67
|
+
* answered or gave up. When the last one does, the notice goes away. Never takes
|
|
68
|
+
* the counter below zero. */
|
|
69
|
+
end(): void;
|
|
70
|
+
/** `start` + `end` around a promise (or a function returning one), for a request
|
|
71
|
+
* that does not go through an adapter. Resolves and rejects as the work does. */
|
|
72
|
+
track<T>(work: PromiseLike<T> | (() => PromiseLike<T>), request?: ServerWakeRequest): Promise<T>;
|
|
73
|
+
/** Back to a pristine watchdog — for tests, which share an instance across cases. */
|
|
74
|
+
reset(): void;
|
|
75
|
+
/** `useSyncExternalStore`'s pair. Listeners hear stage changes only. */
|
|
76
|
+
subscribe(listener: () => void): () => void;
|
|
77
|
+
getStage(): ServerWakeStage;
|
|
78
|
+
/** Counted requests currently outstanding. */
|
|
79
|
+
getInFlight(): number;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* The usual filter: every GET, plus any other request whose URL matches `writes` —
|
|
84
|
+
* keksdose's `/\/auth\/(login|register|demo-session)\b/`. Keep upload routes out of
|
|
85
|
+
* the pattern (see the module comment).
|
|
86
|
+
*/
|
|
87
|
+
export function watchReadsAnd(writes?: RegExp): ServerWakeFilter {
|
|
88
|
+
return (method, url) => method === "get" || (writes !== undefined && writes.test(url));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function isOffline(): boolean {
|
|
92
|
+
return typeof navigator !== "undefined" && navigator.onLine === false;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function createServerWake({
|
|
96
|
+
slowMs = 2000,
|
|
97
|
+
wakingMs = 7000,
|
|
98
|
+
shouldWatch = watchReadsAnd(),
|
|
99
|
+
}: ServerWakeOptions = {}): ServerWakeWatcher {
|
|
100
|
+
let inFlight = 0;
|
|
101
|
+
let stage: ServerWakeStage = "idle";
|
|
102
|
+
let slowTimer: ReturnType<typeof setTimeout> | null = null;
|
|
103
|
+
let wakingTimer: ReturnType<typeof setTimeout> | null = null;
|
|
104
|
+
const listeners = new Set<() => void>();
|
|
105
|
+
|
|
106
|
+
const setStage = (next: ServerWakeStage) => {
|
|
107
|
+
if (next === stage) return;
|
|
108
|
+
stage = next;
|
|
109
|
+
for (const listener of listeners) listener();
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const clearTimers = () => {
|
|
113
|
+
if (slowTimer !== null) clearTimeout(slowTimer);
|
|
114
|
+
if (wakingTimer !== null) clearTimeout(wakingTimer);
|
|
115
|
+
slowTimer = null;
|
|
116
|
+
wakingTimer = null;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
const start = (method?: string, url?: string): boolean => {
|
|
120
|
+
if (isOffline()) return false;
|
|
121
|
+
if (!shouldWatch((method ?? "get").toLowerCase(), url ?? "")) return false;
|
|
122
|
+
inFlight += 1;
|
|
123
|
+
// The clock runs from the FIRST outstanding request: a page firing a second read
|
|
124
|
+
// at 1.9 s is still waiting on the same sleeping server, not starting afresh.
|
|
125
|
+
if (inFlight === 1) {
|
|
126
|
+
clearTimers();
|
|
127
|
+
slowTimer = setTimeout(() => setStage("slow"), slowMs);
|
|
128
|
+
wakingTimer = setTimeout(() => setStage("waking"), wakingMs);
|
|
129
|
+
}
|
|
130
|
+
return true;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
const end = () => {
|
|
134
|
+
inFlight = Math.max(0, inFlight - 1);
|
|
135
|
+
if (inFlight > 0) return;
|
|
136
|
+
clearTimers();
|
|
137
|
+
setStage("idle");
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
start,
|
|
142
|
+
end,
|
|
143
|
+
track<T>(work: PromiseLike<T> | (() => PromiseLike<T>), request: ServerWakeRequest = {}) {
|
|
144
|
+
const counted = start(request.method, request.url);
|
|
145
|
+
let promise: Promise<T>;
|
|
146
|
+
try {
|
|
147
|
+
promise = Promise.resolve(typeof work === "function" ? work() : work);
|
|
148
|
+
} catch (error) {
|
|
149
|
+
// A thunk that throws before it returns a promise settled too.
|
|
150
|
+
promise = Promise.reject(error);
|
|
151
|
+
}
|
|
152
|
+
return counted ? promise.finally(end) : promise;
|
|
153
|
+
},
|
|
154
|
+
reset() {
|
|
155
|
+
inFlight = 0;
|
|
156
|
+
clearTimers();
|
|
157
|
+
setStage("idle");
|
|
158
|
+
},
|
|
159
|
+
subscribe(listener) {
|
|
160
|
+
listeners.add(listener);
|
|
161
|
+
return () => {
|
|
162
|
+
listeners.delete(listener);
|
|
163
|
+
};
|
|
164
|
+
},
|
|
165
|
+
getStage: () => stage,
|
|
166
|
+
getInFlight: () => inFlight,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* The shared instance: what `<ServerWakeNotice />`, `useServerWakeStage()`,
|
|
172
|
+
* {@link attachServerWake} and {@link wrapFetch} use when no watcher is passed. GETs
|
|
173
|
+
* only, default timings — an app that also watches its login POST creates its own
|
|
174
|
+
* with {@link createServerWake} and passes it to both ends.
|
|
175
|
+
*/
|
|
176
|
+
export const serverWake: ServerWakeWatcher = createServerWake();
|
|
177
|
+
|
|
178
|
+
// ── axios ─────────────────────────────────────────────────────────────────────
|
|
179
|
+
|
|
180
|
+
/** The two config fields the watchdog reads — what axios's request config has. */
|
|
181
|
+
export interface ServerWakeAxiosConfig {
|
|
182
|
+
method?: string;
|
|
183
|
+
url?: string;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/** The slice of an interceptor manager the adapter uses. A method (not a function
|
|
187
|
+
* property) so axios's wider `use(onFulfilled?, onRejected?, options?)` fits it. */
|
|
188
|
+
interface InterceptorManagerLike<V> {
|
|
189
|
+
use(onFulfilled: (value: V) => V | Promise<V>, onRejected: (error: unknown) => unknown): number;
|
|
190
|
+
eject(id: number): void;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/** An axios instance, structurally — so the kit types the adapter without importing
|
|
194
|
+
* axios. `axios.create()`'s result fits it as is. */
|
|
195
|
+
export interface AxiosLikeInstance<C extends ServerWakeAxiosConfig, R extends { config: C }> {
|
|
196
|
+
interceptors: {
|
|
197
|
+
request: InterceptorManagerLike<C>;
|
|
198
|
+
response: InterceptorManagerLike<R>;
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** Whether the watchdog counted this request — the response side owes a matching
|
|
203
|
+
* `end()` only then. On the config, as keksdose's `_wake` was: it travels with the
|
|
204
|
+
* request onto the response and onto an error. Cleared once settled, so a 401 replay
|
|
205
|
+
* of the same config re-enters the request interceptor and is counted afresh — the
|
|
206
|
+
* pairing stays balanced. */
|
|
207
|
+
const COUNTED = "_serverWake";
|
|
208
|
+
type Marked = { [COUNTED]?: boolean };
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Drive a watcher from an axios instance's interceptors: `attachServerWake(api)`.
|
|
212
|
+
* Returns a function that ejects both interceptors again.
|
|
213
|
+
*
|
|
214
|
+
* Attach it BEFORE the app's own response interceptors: axios runs those in the order
|
|
215
|
+
* they were added, so the wake one ends the wait before a 401 handler awaits a token
|
|
216
|
+
* refresh — otherwise the notice would keep counting a request that has already been
|
|
217
|
+
* answered. (Request-side order does not matter.)
|
|
218
|
+
*/
|
|
219
|
+
export function attachServerWake<C extends ServerWakeAxiosConfig, R extends { config: C }>(
|
|
220
|
+
instance: AxiosLikeInstance<C, R>,
|
|
221
|
+
watcher: ServerWakeWatcher = serverWake,
|
|
222
|
+
): () => void {
|
|
223
|
+
const settle = (config: unknown) => {
|
|
224
|
+
const marked = config as Marked | undefined;
|
|
225
|
+
if (marked?.[COUNTED]) {
|
|
226
|
+
marked[COUNTED] = false;
|
|
227
|
+
watcher.end();
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
const request = instance.interceptors.request.use(
|
|
231
|
+
(config) => {
|
|
232
|
+
(config as C & Marked)[COUNTED] = watcher.start(config.method, config.url);
|
|
233
|
+
return config;
|
|
234
|
+
},
|
|
235
|
+
(error) => Promise.reject(error),
|
|
236
|
+
);
|
|
237
|
+
const response = instance.interceptors.response.use(
|
|
238
|
+
(res) => {
|
|
239
|
+
settle(res.config);
|
|
240
|
+
return res;
|
|
241
|
+
},
|
|
242
|
+
(error) => {
|
|
243
|
+
settle((error as { config?: unknown } | null)?.config);
|
|
244
|
+
return Promise.reject(error);
|
|
245
|
+
},
|
|
246
|
+
);
|
|
247
|
+
return () => {
|
|
248
|
+
instance.interceptors.request.eject(request);
|
|
249
|
+
instance.interceptors.response.eject(response);
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// ── fetch ─────────────────────────────────────────────────────────────────────
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* A `fetch` that drives a watcher: `const apiFetch = wrapFetch(fetch)`. The wait ends
|
|
257
|
+
* when the response's HEADERS arrive (or the call fails) — the server is awake by then,
|
|
258
|
+
* however long the body takes.
|
|
259
|
+
*/
|
|
260
|
+
export function wrapFetch(
|
|
261
|
+
fetchImpl: typeof fetch = globalThis.fetch,
|
|
262
|
+
watcher: ServerWakeWatcher = serverWake,
|
|
263
|
+
): typeof fetch {
|
|
264
|
+
return (input, init) => {
|
|
265
|
+
const request = typeof Request !== "undefined" && input instanceof Request ? input : undefined;
|
|
266
|
+
const method = init?.method ?? request?.method;
|
|
267
|
+
const url = typeof input === "string" ? input : input instanceof URL ? input.href : (request?.url ?? "");
|
|
268
|
+
return watcher.track(() => fetchImpl(input, init), { method, url });
|
|
269
|
+
};
|
|
270
|
+
}
|
|
@@ -43,7 +43,9 @@ export interface GlobalSearchSource {
|
|
|
43
43
|
/** Stable key — the effect that runs the source is keyed by it, not by identity. */
|
|
44
44
|
id: string;
|
|
45
45
|
/** The group its results are shown under (an entry's own `group` is ignored) — unless
|
|
46
|
-
* `groups` is set, where it is only the home of entries that name no declared group.
|
|
46
|
+
* `groups` is set, where it is only the home of entries that name no declared group.
|
|
47
|
+
* If every entry names a declared group, it is never shown: a catch-all heading such
|
|
48
|
+
* as "Other" is the honest value, so a stray type would still surface, labelled. */
|
|
47
49
|
group: string;
|
|
48
50
|
/**
|
|
49
51
|
* Split ONE request into several groups — kastlan's record search answers with
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { a$ as UiKitLabels } from '../../kit-labels-C4uB_zmg.js';
|
|
2
|
-
import 'react';
|
|
3
|
-
import '../../components/data-table-labels.js';
|
|
4
|
-
import '../../components/mini-calendar.js';
|
|
5
|
-
import '../../components/calendar-heatmap.js';
|
|
6
|
-
import '../../components/popover.js';
|
|
7
|
-
import '../../components/chip.js';
|
|
8
|
-
import 'lucide-react';
|
|
9
|
-
import '../../components/field-sync.js';
|
|
10
|
-
import '../../components/tooltip.js';
|
|
11
|
-
import '../../hooks/use-anchored-rect.js';
|
|
12
|
-
import '../../lib/clipping.js';
|
|
13
|
-
import '../../wizard/types.js';
|
|
14
|
-
import '../../tour/tour.js';
|
|
15
|
-
import '../../search/command-palette.js';
|
|
16
|
-
import '../../search/global-search.js';
|
|
17
|
-
import '../../search/search-index.js';
|
|
18
|
-
import '../../components/month-picker.js';
|
|
19
|
-
import '../../components/page-contents.js';
|
|
20
|
-
import '../../components/series-chart-labels.js';
|
|
21
|
-
import '../../components/pie-chart-labels.js';
|
|
22
|
-
import '../../components/sparkline.js';
|
|
23
|
-
import '../../components/stat-tile.js';
|
|
24
|
-
import '../../components/signature-pad.js';
|
|
25
|
-
import '../../components/password-strength.js';
|
|
26
|
-
import '../../components/danger-confirm.js';
|
|
27
|
-
import '../../components/swatch-picker.js';
|
|
28
|
-
import '../../components/tile-radio.js';
|
|
29
|
-
import '../../components/icon-picker.js';
|
|
30
|
-
import '../../components/dialog-frame.js';
|
|
31
|
-
import '../../components/modal.js';
|
|
32
|
-
import '../../hooks/use-search-param-state.js';
|
|
33
|
-
import '../../components/measured-grid.js';
|
|
34
|
-
import '../../feedback-attachment-WFiXJ8We.js';
|
|
35
|
-
import '../../feedback/feedback-thread.js';
|
|
36
|
-
import '../../feedback/feedback-inbox.js';
|
|
37
|
-
import '../../components/account-settings-labels.js';
|
|
38
|
-
import '../../components/confirm-dialog.js';
|
|
39
|
-
import '../../components/floating-panel.js';
|
|
40
|
-
import '../../components/bulk-action-bar.js';
|
|
41
|
-
import '../../components/list.js';
|
|
42
|
-
import '../../components/signed-amount.js';
|
|
43
|
-
import '../../components/breadcrumbs.js';
|
|
44
|
-
import '../../components/toast.js';
|
|
45
|
-
import '../../components/description-list.js';
|
|
46
|
-
import '../../components/line-items.js';
|
|
47
|
-
import '../../components/progress-bar.js';
|
|
48
|
-
import '../../components/error-boundary.js';
|
|
49
|
-
import '../../components/authed-image.js';
|
|
50
|
-
import '../../hooks/use-authed-src.js';
|
|
51
|
-
import '../../components/image-grid.js';
|
|
52
|
-
import '../../components/lightbox.js';
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Swiss Standard German, informal ("du"): the informal German labels with Swiss
|
|
56
|
-
* spelling ("ss" for every "ß") and `de-CH` number formatting (1’234.5) — derived the
|
|
57
|
-
* same way `de-CH` is from `de`, so both stay in sync with their source.
|
|
58
|
-
*/
|
|
59
|
-
declare const UI_KIT_LABELS_DE_CH_INFORMAL: UiKitLabels;
|
|
60
|
-
|
|
61
|
-
export { UI_KIT_LABELS_DE_CH_INFORMAL };
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { swiss } from "../swiss.js";
|
|
3
|
-
import { uiKitLabelsDeInformal } from "./de-informal.js";
|
|
4
|
-
const UI_KIT_LABELS_DE_CH_INFORMAL = swiss(uiKitLabelsDeInformal("de-CH"));
|
|
5
|
-
export {
|
|
6
|
-
UI_KIT_LABELS_DE_CH_INFORMAL
|
|
7
|
-
};
|
|
8
|
-
//# sourceMappingURL=de-CH-informal.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/i18n/locales/de-CH-informal.ts"],"sourcesContent":["import type { UiKitLabels } from \"../kit-labels\";\nimport { swiss } from \"../swiss\";\nimport { uiKitLabelsDeInformal } from \"./de-informal\";\n\n/**\n * Swiss Standard German, informal (\"du\"): the informal German labels with Swiss\n * spelling (\"ss\" for every \"ß\") and `de-CH` number formatting (1’234.5) — derived the\n * same way `de-CH` is from `de`, so both stay in sync with their source.\n */\nexport const UI_KIT_LABELS_DE_CH_INFORMAL: UiKitLabels = swiss(uiKitLabelsDeInformal(\"de-CH\"));\n"],"mappings":";AACA,SAAS,aAAa;AACtB,SAAS,6BAA6B;AAO/B,MAAM,+BAA4C,MAAM,sBAAsB,OAAO,CAAC;","names":[]}
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { a$ as UiKitLabels } from '../../kit-labels-C4uB_zmg.js';
|
|
2
|
-
import 'react';
|
|
3
|
-
import '../../components/data-table-labels.js';
|
|
4
|
-
import '../../components/mini-calendar.js';
|
|
5
|
-
import '../../components/calendar-heatmap.js';
|
|
6
|
-
import '../../components/popover.js';
|
|
7
|
-
import '../../components/chip.js';
|
|
8
|
-
import 'lucide-react';
|
|
9
|
-
import '../../components/field-sync.js';
|
|
10
|
-
import '../../components/tooltip.js';
|
|
11
|
-
import '../../hooks/use-anchored-rect.js';
|
|
12
|
-
import '../../lib/clipping.js';
|
|
13
|
-
import '../../wizard/types.js';
|
|
14
|
-
import '../../tour/tour.js';
|
|
15
|
-
import '../../search/command-palette.js';
|
|
16
|
-
import '../../search/global-search.js';
|
|
17
|
-
import '../../search/search-index.js';
|
|
18
|
-
import '../../components/month-picker.js';
|
|
19
|
-
import '../../components/page-contents.js';
|
|
20
|
-
import '../../components/series-chart-labels.js';
|
|
21
|
-
import '../../components/pie-chart-labels.js';
|
|
22
|
-
import '../../components/sparkline.js';
|
|
23
|
-
import '../../components/stat-tile.js';
|
|
24
|
-
import '../../components/signature-pad.js';
|
|
25
|
-
import '../../components/password-strength.js';
|
|
26
|
-
import '../../components/danger-confirm.js';
|
|
27
|
-
import '../../components/swatch-picker.js';
|
|
28
|
-
import '../../components/tile-radio.js';
|
|
29
|
-
import '../../components/icon-picker.js';
|
|
30
|
-
import '../../components/dialog-frame.js';
|
|
31
|
-
import '../../components/modal.js';
|
|
32
|
-
import '../../hooks/use-search-param-state.js';
|
|
33
|
-
import '../../components/measured-grid.js';
|
|
34
|
-
import '../../feedback-attachment-WFiXJ8We.js';
|
|
35
|
-
import '../../feedback/feedback-thread.js';
|
|
36
|
-
import '../../feedback/feedback-inbox.js';
|
|
37
|
-
import '../../components/account-settings-labels.js';
|
|
38
|
-
import '../../components/confirm-dialog.js';
|
|
39
|
-
import '../../components/floating-panel.js';
|
|
40
|
-
import '../../components/bulk-action-bar.js';
|
|
41
|
-
import '../../components/list.js';
|
|
42
|
-
import '../../components/signed-amount.js';
|
|
43
|
-
import '../../components/breadcrumbs.js';
|
|
44
|
-
import '../../components/toast.js';
|
|
45
|
-
import '../../components/description-list.js';
|
|
46
|
-
import '../../components/line-items.js';
|
|
47
|
-
import '../../components/progress-bar.js';
|
|
48
|
-
import '../../components/error-boundary.js';
|
|
49
|
-
import '../../components/authed-image.js';
|
|
50
|
-
import '../../hooks/use-authed-src.js';
|
|
51
|
-
import '../../components/image-grid.js';
|
|
52
|
-
import '../../components/lightbox.js';
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* The kit's words in informal German ("du"), for apps that address their users that way
|
|
56
|
-
* everywhere else: `<UiKitProvider labels={UI_KIT_LABELS_DE_INFORMAL}>`.
|
|
57
|
-
*
|
|
58
|
-
* Built on the formal catalogue ({@link uiKitLabelsDe}) rather than beside it: most of
|
|
59
|
-
* the kit's German never addresses anyone — buttons are infinitives ("Speichern"),
|
|
60
|
-
* status lines are impersonal ("Wird geladen…"), hints use the infinitive
|
|
61
|
-
* ("Mindestens 3 Zeichen eingeben", "Bitte erneut versuchen") — so it is the same text
|
|
62
|
-
* in both registers and stays in sync with `de.ts` by construction. Only the sentences
|
|
63
|
-
* that speak TO the user are rewritten here, by hand: du/Sie is grammar (verb forms,
|
|
64
|
-
* imperatives, possessives), not a substitution a regex could do.
|
|
65
|
-
*
|
|
66
|
-
* Every key of `de.ts` was reviewed. The overridden ones — the complete list of
|
|
67
|
-
* sentences that say "Sie" / "Ihr" / a Sie-imperative in the formal catalogue:
|
|
68
|
-
* - `miniCalendar.startSelected`, `miniCalendar.rangeSelected`
|
|
69
|
-
* - `dangerConfirm.phrase`
|
|
70
|
-
* - `wizard.confirmCancel`, `wizard.missingRequired`
|
|
71
|
-
* - `tour.awaitClickHint`
|
|
72
|
-
* - `signaturePad.instructions`, `signaturePad.typedFallbackHint`
|
|
73
|
-
*
|
|
74
|
-
* A key added to `de.ts` later is inherited as is; if it addresses the user, add its
|
|
75
|
-
* du form here (the "no formal address" test in locales.test.ts catches a "Sie").
|
|
76
|
-
* Conventions as in `de.ts`: „…“ quotes, `Intl` digits (via the `numberLocale`
|
|
77
|
-
* argument, e.g. `"de-AT"`), number agreement.
|
|
78
|
-
*/
|
|
79
|
-
declare function uiKitLabelsDeInformal(numberLocale?: string): UiKitLabels;
|
|
80
|
-
declare const UI_KIT_LABELS_DE_INFORMAL: UiKitLabels;
|
|
81
|
-
|
|
82
|
-
export { UI_KIT_LABELS_DE_INFORMAL, uiKitLabelsDeInformal };
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { uiKitLabelsDe } from "./de.js";
|
|
3
|
-
function uiKitLabelsDeInformal(numberLocale = "de-DE") {
|
|
4
|
-
const de = uiKitLabelsDe(numberLocale);
|
|
5
|
-
return {
|
|
6
|
-
...de,
|
|
7
|
-
miniCalendar: {
|
|
8
|
-
...de.miniCalendar,
|
|
9
|
-
startSelected: (date) => `${date} als Startdatum gew\xE4hlt. W\xE4hle jetzt ein Enddatum.`,
|
|
10
|
-
rangeSelected: (from, to) => `Zeitraum ${from} bis ${to} gew\xE4hlt. W\xE4hle ein Startdatum, um neu zu beginnen.`
|
|
11
|
-
},
|
|
12
|
-
dangerConfirm: {
|
|
13
|
-
...de.dangerConfirm,
|
|
14
|
-
phrase: (phrase) => `Gib zur Best\xE4tigung \u201E${phrase}\u201C ein`
|
|
15
|
-
},
|
|
16
|
-
wizard: {
|
|
17
|
-
...de.wizard,
|
|
18
|
-
confirmCancel: "Deine Eingaben gehen verloren.",
|
|
19
|
-
missingRequired: "Bitte f\xFClle alle Pflichtfelder aus."
|
|
20
|
-
},
|
|
21
|
-
tour: {
|
|
22
|
-
...de.tour,
|
|
23
|
-
awaitClickHint: "Klick auf das hervorgehobene Element, um fortzufahren"
|
|
24
|
-
},
|
|
25
|
-
signaturePad: {
|
|
26
|
-
...de.signaturePad,
|
|
27
|
-
instructions: "Unterschreibe im Feld mit der Maus, dem Finger oder einem Stift.",
|
|
28
|
-
typedFallbackHint: "Wenn du nicht zeichnen kannst, gib stattdessen deinen Namen ein."
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
const UI_KIT_LABELS_DE_INFORMAL = uiKitLabelsDeInformal();
|
|
33
|
-
export {
|
|
34
|
-
UI_KIT_LABELS_DE_INFORMAL,
|
|
35
|
-
uiKitLabelsDeInformal
|
|
36
|
-
};
|
|
37
|
-
//# sourceMappingURL=de-informal.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/i18n/locales/de-informal.ts"],"sourcesContent":["import type { UiKitLabels } from \"../kit-labels\";\nimport { uiKitLabelsDe } from \"./de\";\n\n/**\n * The kit's words in informal German (\"du\"), for apps that address their users that way\n * everywhere else: `<UiKitProvider labels={UI_KIT_LABELS_DE_INFORMAL}>`.\n *\n * Built on the formal catalogue ({@link uiKitLabelsDe}) rather than beside it: most of\n * the kit's German never addresses anyone — buttons are infinitives (\"Speichern\"),\n * status lines are impersonal (\"Wird geladen…\"), hints use the infinitive\n * (\"Mindestens 3 Zeichen eingeben\", \"Bitte erneut versuchen\") — so it is the same text\n * in both registers and stays in sync with `de.ts` by construction. Only the sentences\n * that speak TO the user are rewritten here, by hand: du/Sie is grammar (verb forms,\n * imperatives, possessives), not a substitution a regex could do.\n *\n * Every key of `de.ts` was reviewed. The overridden ones — the complete list of\n * sentences that say \"Sie\" / \"Ihr\" / a Sie-imperative in the formal catalogue:\n * - `miniCalendar.startSelected`, `miniCalendar.rangeSelected`\n * - `dangerConfirm.phrase`\n * - `wizard.confirmCancel`, `wizard.missingRequired`\n * - `tour.awaitClickHint`\n * - `signaturePad.instructions`, `signaturePad.typedFallbackHint`\n *\n * A key added to `de.ts` later is inherited as is; if it addresses the user, add its\n * du form here (the \"no formal address\" test in locales.test.ts catches a \"Sie\").\n * Conventions as in `de.ts`: „…“ quotes, `Intl` digits (via the `numberLocale`\n * argument, e.g. `\"de-AT\"`), number agreement.\n */\nexport function uiKitLabelsDeInformal(numberLocale = \"de-DE\"): UiKitLabels {\n const de = uiKitLabelsDe(numberLocale);\n\n return {\n ...de,\n miniCalendar: {\n ...de.miniCalendar,\n startSelected: (date) => `${date} als Startdatum gewählt. Wähle jetzt ein Enddatum.`,\n rangeSelected: (from, to) =>\n `Zeitraum ${from} bis ${to} gewählt. Wähle ein Startdatum, um neu zu beginnen.`,\n },\n dangerConfirm: {\n ...de.dangerConfirm,\n phrase: (phrase) => `Gib zur Bestätigung „${phrase}“ ein`,\n },\n wizard: {\n ...de.wizard,\n confirmCancel: \"Deine Eingaben gehen verloren.\",\n missingRequired: \"Bitte fülle alle Pflichtfelder aus.\",\n },\n tour: {\n ...de.tour,\n awaitClickHint: \"Klick auf das hervorgehobene Element, um fortzufahren\",\n },\n signaturePad: {\n ...de.signaturePad,\n instructions: \"Unterschreibe im Feld mit der Maus, dem Finger oder einem Stift.\",\n typedFallbackHint: \"Wenn du nicht zeichnen kannst, gib stattdessen deinen Namen ein.\",\n },\n };\n}\n\nexport const UI_KIT_LABELS_DE_INFORMAL: UiKitLabels = uiKitLabelsDeInformal();\n"],"mappings":";AACA,SAAS,qBAAqB;AA2BvB,SAAS,sBAAsB,eAAe,SAAsB;AACzE,QAAM,KAAK,cAAc,YAAY;AAErC,SAAO;AAAA,IACL,GAAG;AAAA,IACH,cAAc;AAAA,MACZ,GAAG,GAAG;AAAA,MACN,eAAe,CAAC,SAAS,GAAG,IAAI;AAAA,MAChC,eAAe,CAAC,MAAM,OACpB,YAAY,IAAI,QAAQ,EAAE;AAAA,IAC9B;AAAA,IACA,eAAe;AAAA,MACb,GAAG,GAAG;AAAA,MACN,QAAQ,CAAC,WAAW,gCAAwB,MAAM;AAAA,IACpD;AAAA,IACA,QAAQ;AAAA,MACN,GAAG,GAAG;AAAA,MACN,eAAe;AAAA,MACf,iBAAiB;AAAA,IACnB;AAAA,IACA,MAAM;AAAA,MACJ,GAAG,GAAG;AAAA,MACN,gBAAgB;AAAA,IAClB;AAAA,IACA,cAAc;AAAA,MACZ,GAAG,GAAG;AAAA,MACN,cAAc;AAAA,MACd,mBAAmB;AAAA,IACrB;AAAA,EACF;AACF;AAEO,MAAM,4BAAyC,sBAAsB;","names":[]}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { a$ as UiKitLabels } from '../../kit-labels-C4uB_zmg.js';
|
|
2
|
-
import 'react';
|
|
3
|
-
import '../../components/data-table-labels.js';
|
|
4
|
-
import '../../components/mini-calendar.js';
|
|
5
|
-
import '../../components/calendar-heatmap.js';
|
|
6
|
-
import '../../components/popover.js';
|
|
7
|
-
import '../../components/chip.js';
|
|
8
|
-
import 'lucide-react';
|
|
9
|
-
import '../../components/field-sync.js';
|
|
10
|
-
import '../../components/tooltip.js';
|
|
11
|
-
import '../../hooks/use-anchored-rect.js';
|
|
12
|
-
import '../../lib/clipping.js';
|
|
13
|
-
import '../../wizard/types.js';
|
|
14
|
-
import '../../tour/tour.js';
|
|
15
|
-
import '../../search/command-palette.js';
|
|
16
|
-
import '../../search/global-search.js';
|
|
17
|
-
import '../../search/search-index.js';
|
|
18
|
-
import '../../components/month-picker.js';
|
|
19
|
-
import '../../components/page-contents.js';
|
|
20
|
-
import '../../components/series-chart-labels.js';
|
|
21
|
-
import '../../components/pie-chart-labels.js';
|
|
22
|
-
import '../../components/sparkline.js';
|
|
23
|
-
import '../../components/stat-tile.js';
|
|
24
|
-
import '../../components/signature-pad.js';
|
|
25
|
-
import '../../components/password-strength.js';
|
|
26
|
-
import '../../components/danger-confirm.js';
|
|
27
|
-
import '../../components/swatch-picker.js';
|
|
28
|
-
import '../../components/tile-radio.js';
|
|
29
|
-
import '../../components/icon-picker.js';
|
|
30
|
-
import '../../components/dialog-frame.js';
|
|
31
|
-
import '../../components/modal.js';
|
|
32
|
-
import '../../hooks/use-search-param-state.js';
|
|
33
|
-
import '../../components/measured-grid.js';
|
|
34
|
-
import '../../feedback-attachment-WFiXJ8We.js';
|
|
35
|
-
import '../../feedback/feedback-thread.js';
|
|
36
|
-
import '../../feedback/feedback-inbox.js';
|
|
37
|
-
import '../../components/account-settings-labels.js';
|
|
38
|
-
import '../../components/confirm-dialog.js';
|
|
39
|
-
import '../../components/floating-panel.js';
|
|
40
|
-
import '../../components/bulk-action-bar.js';
|
|
41
|
-
import '../../components/list.js';
|
|
42
|
-
import '../../components/signed-amount.js';
|
|
43
|
-
import '../../components/breadcrumbs.js';
|
|
44
|
-
import '../../components/toast.js';
|
|
45
|
-
import '../../components/description-list.js';
|
|
46
|
-
import '../../components/line-items.js';
|
|
47
|
-
import '../../components/progress-bar.js';
|
|
48
|
-
import '../../components/error-boundary.js';
|
|
49
|
-
import '../../components/authed-image.js';
|
|
50
|
-
import '../../hooks/use-authed-src.js';
|
|
51
|
-
import '../../components/image-grid.js';
|
|
52
|
-
import '../../components/lightbox.js';
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* The kit's words in German: every namespace of {@link UiKitLabels}, for
|
|
56
|
-
* `<UiKitProvider labels={UI_KIT_LABELS_DE}>`.
|
|
57
|
-
*
|
|
58
|
-
* Self-contained on purpose — nothing but the kit's own `formatFileSize` — so it works
|
|
59
|
-
* as a starting point to copy and adjust. Counts and sizes are formatted with
|
|
60
|
-
* `de-DE` digits; {@link uiKitLabelsDe} takes another number locale
|
|
61
|
-
* (e.g. `"de-CH"` for 1’234) without touching the words.
|
|
62
|
-
*/
|
|
63
|
-
declare function uiKitLabelsDe(numberLocale?: string): UiKitLabels;
|
|
64
|
-
declare const UI_KIT_LABELS_DE: UiKitLabels;
|
|
65
|
-
|
|
66
|
-
export { UI_KIT_LABELS_DE, uiKitLabelsDe };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/i18n/locales/de.ts"],"sourcesContent":["import { formatFileSize } from \"../kit-labels\";\nimport type { UiKitLabels } from \"../kit-labels\";\n\n/**\n * The kit's words in German: every namespace of {@link UiKitLabels}, for\n * `<UiKitProvider labels={UI_KIT_LABELS_DE}>`.\n *\n * Self-contained on purpose — nothing but the kit's own `formatFileSize` — so it works\n * as a starting point to copy and adjust. Counts and sizes are formatted with\n * `de-DE` digits; {@link uiKitLabelsDe} takes another number locale\n * (e.g. `\"de-CH\"` for 1’234) without touching the words.\n */\nexport function uiKitLabelsDe(numberLocale = \"de-DE\"): UiKitLabels {\n const num = new Intl.NumberFormat(numberLocale);\n const n = (value: number) => num.format(value);\n\n return {\n feedbackAttachment: {\n attachmentAdd: \"Bild anhängen\",\n attachmentCapture: \"Screenshot aufnehmen\",\n attachmentPaste: \"…oder einen Screenshot aus der Zwischenablage einfügen.\",\n attachmentRemove: \"Anhang entfernen\",\n attachmentList: \"Anhänge\",\n attachmentScreenshot: \"Screenshot\",\n attachmentRemoveFile: (name) => `${name} entfernen`,\n attachmentLimit: (max) => `Maximal ${n(max)} ${max === 1 ? \"Anhang\" : \"Anhänge\"} – zum Hinzufügen erst einen entfernen.`,\n },\n feedbackDialog: {\n title: \"Feedback senden\",\n category: \"Kategorie\",\n subject: \"Betreff\",\n body: \"Was ist passiert?\",\n bodyOptional: \"Was ist passiert? (optional)\",\n attachment: \"Screenshot\",\n submitHint: \"Strg/⌘ + Enter zum Senden\",\n cancel: \"Abbrechen\",\n save: \"Senden\",\n },\n feedbackThread: {\n thread: \"Kommentare\",\n empty: \"Noch keine Kommentare\",\n loading: \"Kommentare werden geladen…\",\n // The reader's own messages. \"Ich\" rather than \"Sie\"/\"Du\": it is the same word in\n // both registers, so the informal catalogue inherits it unchanged.\n you: \"Ich\",\n staff: \"Team\",\n attachments: \"Anhänge\",\n },\n feedbackComposer: {\n field: \"Kommentar schreiben\",\n placeholder: \"Kommentar schreiben…\",\n send: \"Senden\",\n // German keyboards label the key \"Strg\".\n sendHint: (modifier) => `${modifier === \"Ctrl\" ? \"Strg\" : modifier} + Enter zum Senden`,\n // \"Umschalt\", the German key label, as in the table's sort hint.\n sendHintEnter: \"Enter zum Senden, Umschalt + Enter für neue Zeile\",\n },\n accountSettings: {\n profile: {\n title: \"Profil\",\n email: \"E-Mail\",\n role: \"Rolle\",\n memberSince: \"Mitglied seit\",\n displayName: \"Anzeigename\",\n save: \"Speichern\",\n },\n password: {\n title: \"Passwort ändern\",\n current: \"Aktuelles Passwort\",\n next: \"Neues Passwort\",\n confirm: \"Neues Passwort bestätigen\",\n submit: \"Passwort ändern\",\n tooShort: \"Das neue Passwort ist zu kurz.\",\n mismatch: \"Die Passwörter stimmen nicht überein.\",\n },\n twoFactor: {\n status: \"Zwei-Faktor-Authentifizierung\",\n enabledText: \"Aktiv\",\n disabledText: \"Inaktiv\",\n enable: \"Zwei-Faktor-Authentifizierung einrichten\",\n scanHint: \"Diesen Code mit der Authenticator-App scannen und den angezeigten Code eingeben.\",\n codeLabel: \"Bestätigungscode\",\n verify: \"Bestätigen und aktivieren\",\n disableSection: \"Zwei-Faktor-Authentifizierung deaktivieren\",\n password: \"Aktuelles Passwort\",\n disable: \"Deaktivieren\",\n qrAlt: \"QR-Code für die Authenticator-App\",\n secretHint: \"Scannen nicht möglich? Stattdessen diesen Schlüssel in der App eingeben:\",\n copySecret: \"Schlüssel kopieren\",\n },\n passkeys: {\n title: \"Passkeys\",\n description: \"Mit Fingerabdruck, Gesichtserkennung oder Geräte-PIN statt Passwort anmelden.\",\n empty: \"Noch keine Passkeys\",\n loading: \"Passkeys werden geladen…\",\n list: \"Registrierte Passkeys\",\n nameLabel: \"Name (optional)\",\n namePlaceholder: \"z. B. Laptop, Handy\",\n add: \"Passkey hinzufügen\",\n adding: \"Warten auf das Gerät…\",\n rename: \"Umbenennen\",\n renameItem: (name) => `${name} umbenennen`,\n renameField: (name) => `Neuer Name für ${name}`,\n save: \"Speichern\",\n cancel: \"Abbrechen\",\n delete: \"Löschen\",\n deleteItem: (name) => `${name} löschen`,\n deleteConfirm: (name) => `„${name}“ löschen? Eine Anmeldung damit ist dann nicht mehr möglich.`,\n confirmDelete: \"Passkey löschen\",\n created: (date) => `Hinzugefügt am ${date}`,\n lastUsed: (date) => `Zuletzt verwendet am ${date}`,\n neverUsed: \"Noch nie verwendet\",\n },\n },\n measuredGrid: {\n view: \"Tabellenansicht\",\n cellsView: \"Zellen\",\n textView: \"Text\",\n addRow: \"Zeile hinzufügen\",\n removeRow: (row) => `Zeile ${row} entfernen`,\n clear: \"Tabelle leeren\",\n pasteHint: \"Einen Block aus einer Tabellenkalkulation in eine beliebige Zelle einfügen\",\n cell: (column, row) => `${column}, Zeile ${row}`,\n rowNumber: \"Zeile\",\n rowActions: \"Zeilenaktionen\",\n keyboardHint:\n \"Pfeiltasten wechseln zwischen Zellen. Tippen ersetzt eine Zelle, F2 bearbeitet sie, Escape macht die Bearbeitung rückgängig. Enter geht nach unten und fügt am Ende eine Zeile hinzu.\",\n lineError: (line) => `Zeile ${line} konnte nicht gelesen werden`,\n points: (count) => (count === 1 ? \"1 Punkt\" : `${count} Punkte`),\n problems: (count) =>\n count === 1 ? \"1 Zelle ist keine Zahl\" : `${count} Zellen sind keine Zahlen`,\n },\n pageContents: { title: \"Auf dieser Seite\" },\n common: {\n dismiss: \"Schließen\",\n close: \"Schließen\",\n clear: \"Leeren\",\n search: \"Suchen\",\n done: \"Fertig\",\n cancel: \"Abbrechen\",\n save: \"Speichern\",\n back: \"Zurück\",\n next: \"Weiter\",\n remove: \"Entfernen\",\n loading: \"Wird geladen…\",\n noResults: \"Keine Ergebnisse\",\n fieldValue: (field, value) => `${field}: ${value}`,\n opensInNewTab: \"öffnet in einem neuen Tab\",\n },\n dataTable: {\n columns: \"Spalten\",\n selectAllRows: \"Alle Zeilen auswählen\",\n sortHint: \"Klicken zum Sortieren · Umschalt-Klick für weitere Sortierung\",\n filter: \"Filter\",\n close: \"Schließen\",\n selectRow: \"Zeile auswählen\",\n autoSize: \"Spaltenbreiten anpassen\",\n loading: \"Wird geladen…\",\n filters: \"Filter\",\n // Resets every active filter; \"Alle löschen\" would read as deleting the filters.\n clearAll: \"Alle zurücksetzen\",\n done: \"Fertig\",\n pageSize: \"Zeilen pro Seite\",\n // Sits among 10 / 25 / 50 counting \"Zeilen\", so the plural \"Alle\", not \"Alles\".\n pageSizeAll: \"Alle\",\n prevPage: \"Vorherige Seite\",\n nextPage: \"Nächste Seite\",\n clearFilter: \"Filter zurücksetzen\",\n filterPlaceholder: \"Filtern…\",\n selectFilter: \"Auswählen\",\n selectAll: \"Alle\",\n selectNone: \"Keine\",\n dateFrom: \"Von\",\n dateTo: \"Bis\",\n numberMin: \"Min.\",\n numberMax: \"Max.\",\n numberAbs: \"Betrag\",\n presets: {\n today: \"Heute\",\n yesterday: \"Gestern\",\n this_week: \"Diese Woche\",\n last_week: \"Letzte Woche\",\n last_7_days: \"Letzte 7 Tage\",\n last_30_days: \"Letzte 30 Tage\",\n this_month: \"Dieser Monat\",\n last_month: \"Letzter Monat\",\n last_3_months: \"Letzte 3 Monate\",\n ytd: \"Seit Jahresbeginn\",\n last_year: \"Letztes Jahr\",\n },\n table: \"Datentabelle\",\n filterResults: (shown, total) =>\n `${n(shown)} von ${n(total)} ${total === 1 ? \"Zeile\" : \"Zeilen\"}`,\n sortedAscending: (column) => `Sortiert nach ${column}, aufsteigend`,\n sortedDescending: (column) => `Sortiert nach ${column}, absteigend`,\n sortCleared: (column) => `Sortierung nach ${column} aufgehoben`,\n pageChanged: (page, totalPages) => `Seite ${n(page)} von ${n(totalPages)}`,\n pageRange: (from, to, total) => `${n(from)}–${n(to)} / ${n(total)}`,\n rowCount: (total) => n(total),\n columnsCount: (visible, total) => `Spalten (${n(visible)}/${n(total)})`,\n empty: \"Keine Einträge\",\n actions: \"Aktionen\",\n edit: \"Bearbeiten\",\n delete: \"Löschen\",\n booleanTrue: \"Ja\",\n booleanFalse: \"Nein\",\n booleanUnset: \"Nicht festgelegt\",\n },\n miniCalendar: {\n previousMonth: \"Vorheriger Monat\",\n nextMonth: \"Nächster Monat\",\n // Already formatted in the provider's locale (\"Montag, 14. September 2026\").\n day: (date) => date,\n chooseStart: \"Startdatum wählen\",\n chooseEnd: \"Enddatum wählen\",\n startSelected: (date) => `${date} als Startdatum gewählt. Wählen Sie jetzt ein Enddatum.`,\n rangeSelected: (from, to) =>\n `Zeitraum ${from} bis ${to} gewählt. Wählen Sie ein Startdatum, um neu zu beginnen.`,\n },\n calendarHeatmap: {\n grid: \"Tageswerte\",\n day: (date, value) => `${date}: ${value}`,\n less: \"Weniger\",\n more: \"Mehr\",\n truncated: (count) =>\n `Die neuesten Tage werden angezeigt; ${n(count)} ${count === 1 ? \"früherer Tag wird\" : \"frühere Tage werden\"} nicht angezeigt.`,\n },\n datePicker: {\n apply: \"Übernehmen\",\n cancel: \"Abbrechen\",\n presets: \"Schnellauswahl\",\n panel: \"Datum wählen\",\n rangePanel: \"Zeitraum wählen\",\n clear: \"Leeren\",\n previousDay: \"Vorheriger Tag\",\n nextDay: \"Nächster Tag\",\n today: \"Heute\",\n },\n monthPicker: {\n previousYear: \"Vorheriges Jahr\",\n nextYear: \"Nächstes Jahr\",\n panel: \"Monat wählen\",\n month: (monthYear) => monthYear,\n previousMonth: \"Vorheriger Monat\",\n nextMonth: \"Nächster Monat\",\n today: \"Heute\",\n },\n popover: {\n panel: \"Aufklappfenster\",\n },\n combobox: {\n search: \"Suchen\",\n noResults: \"Keine Ergebnisse\",\n clear: \"Leeren\",\n loading: \"Wird geladen…\",\n create: (query) => `„${query}“ anlegen`,\n selectedCount: (count) => `${n(count)} ausgewählt`,\n loadError: \"Ergebnisse konnten nicht geladen werden\",\n resultCount: (count) => `${n(count)} ${count === 1 ? \"Ergebnis\" : \"Ergebnisse\"}`,\n // \"Zeichen\" is the same in singular and plural.\n minChars: (count) => `Mindestens ${n(count)} Zeichen eingeben`,\n },\n multiSelect: {\n search: \"Suchen\",\n selectAll: \"Alle auswählen\",\n clear: \"Leeren\",\n all: \"Alle\",\n // The bare count, as in English: the trigger has always shown just the number.\n selectedCount: (count) => n(count),\n },\n calculator: {\n open: \"Taschenrechner öffnen\",\n panel: \"Taschenrechner\",\n calculation: \"Rechnung\",\n backspace: \"Rücktaste\",\n clear: \"Löschen\",\n equals: \"Ist gleich\",\n done: \"Fertig\",\n plus: \"Plus\",\n minus: \"Minus\",\n times: \"Mal\",\n divide: \"Geteilt durch\",\n decimal: \"Dezimaltrennzeichen\",\n },\n currency: {\n currency: \"Währung\",\n search: \"Währung suchen\",\n },\n chipInput: {\n // The value is arbitrary user text, quoted as a citation, so the participle agrees\n // with the implied \"Eintrag\" whatever the chip says.\n added: (value) => `„${value}“ hinzugefügt`,\n removed: (value) => `„${value}“ entfernt`,\n remove: \"Entfernen\",\n // `von` governs the dative, visible only in the plural: \"von 1 Eintrag\", \"von 2 Einträgen\".\n atLimit: (max) => `Grenze von ${n(max)} ${max === 1 ? \"Eintrag\" : \"Einträgen\"} erreicht`,\n duplicate: (value) => `„${value}“ steht bereits in der Liste`,\n },\n swatchPicker: {\n none: \"Keine Farbe\",\n mixed: \"Gemischt: Die ausgewählten Elemente haben unterschiedliche Farben\",\n },\n iconPicker: {\n none: \"Kein Symbol\",\n mixed: \"Gemischt: Die ausgewählten Elemente haben unterschiedliche Symbole\",\n search: \"Symbole suchen\",\n noResults: \"Keine passenden Symbole\",\n resultCount: (count) => `${n(count)} ${count === 1 ? \"Symbol\" : \"Symbole\"}`,\n },\n fieldSync: {\n synced: \"Gespeichert\",\n edited: \"Nicht gespeicherte Änderungen\",\n pending: \"Wird gespeichert…\",\n error: \"Speichern fehlgeschlagen\",\n retry: \"Erneut versuchen\",\n },\n passwordReveal: {\n show: \"Passwort anzeigen\",\n hide: \"Passwort verbergen\",\n },\n dangerConfirm: {\n arm: \"Löschen…\",\n confirm: \"Löschen\",\n cancel: \"Abbrechen\",\n prompt: \"Dies kann nicht rückgängig gemacht werden.\",\n password: \"Passwort\",\n phrase: (phrase) => `Geben Sie zur Bestätigung „${phrase}“ ein`,\n },\n tabs: {\n // \"Tab\" is what German UIs say; \"Registerkarte\" reads like a 1990s manual.\n add: \"Tab hinzufügen\",\n remove: (tab) => `${tab} entfernen`,\n },\n appShell: {\n collapse: \"Seitenleiste einklappen\",\n expand: \"Seitenleiste ausklappen\",\n toggleGroup: (groupLabel) => `${groupLabel}: Seiten`,\n },\n topBar: {\n theme: \"Theme wechseln\",\n palette: \"Darstellungsvorlage\",\n language: \"Sprache\",\n switchRole: \"Rolle wechseln\",\n role: (value) => `Rolle: ${value}`,\n },\n pickerSheet: {\n close: \"Schließen\",\n },\n dialogFrame: {\n close: \"Schließen\",\n },\n bulkActionBar: {\n selected: (count) => `${n(count)} ausgewählt`,\n clear: \"Auswahl aufheben\",\n cleared: \"Auswahl aufgehoben\",\n },\n swipeableRow: {\n actions: \"Zeilenaktionen\",\n },\n file: {\n // The kit's own `Intl` unit formatting, pinned to this locale (\"3,4 MB\").\n size: (bytes) => formatFileSize(bytes, numberLocale),\n },\n filePicker: {\n dropzone: \"Datei-Upload\",\n browse: \"Durchsuchen\",\n empty: \"Datei hier ablegen\",\n emptyMultiple: \"Dateien hier ablegen\",\n hint: (accept) => (accept ? `Erlaubt: ${accept}` : \"Beliebiger Dateityp\"),\n busy: \"Wird hochgeladen…\",\n rejectedPick: (count) =>\n count === 1\n ? \"Die Datei wurde nicht hinzugefügt\"\n : `Keine der ${count} Dateien wurde hinzugefügt`,\n rejectedType: (name) => `„${name}“ hat einen nicht unterstützten Dateityp`,\n rejectedTypeOnly: (accept) => `Nur ${accept}-Dateien`,\n rejectedSize: (name, maxSize) => `„${name}“ ist größer als ${maxSize}`,\n rejectedCount: (name, maxFiles) =>\n `„${name}“ wurde nicht hinzugefügt: höchstens ${n(maxFiles)} ${maxFiles === 1 ? \"Datei\" : \"Dateien\"}`,\n rejectedInvalid: (name) => `„${name}“ kann hier nicht verwendet werden`,\n rejectedMany: (count) =>\n count === 1\n ? \"1 Datei wurde nicht hinzugefügt\"\n : `${n(count)} Dateien wurden nicht hinzugefügt`,\n selected: (count, firstName) =>\n count === 1 ? `„${firstName}“ ausgewählt` : `${n(count)} Dateien ausgewählt`,\n remove: (name) => `„${name}“ entfernen`,\n clearAll: \"Alle Dateien entfernen\",\n removed: (name) => `„${name}“ entfernt`,\n cleared: \"Alle Dateien entfernt\",\n },\n wizard: {\n done: \"Fertig\",\n cancel: \"Abbrechen\",\n back: \"Zurück\",\n next: \"Weiter\",\n skip: \"Überspringen\",\n finish: \"Abschließen\",\n submitting: \"Wird erstellt…\",\n steps: \"Schritte\",\n step: (current, total) => `Schritt ${n(current)} von ${n(total)}`,\n cancelTitle: \"Formular verwerfen?\",\n confirmCancel: \"Ihre Eingaben gehen verloren.\",\n cancelConfirmLabel: \"Verwerfen\",\n cancelDismissLabel: \"Weiter bearbeiten\",\n reviewTitle: \"Überprüfen\",\n edit: \"Bearbeiten\",\n missingRequired: \"Bitte füllen Sie alle Pflichtfelder aus.\",\n genericError: \"Ein Fehler ist aufgetreten\",\n },\n tour: {\n next: \"Weiter\",\n back: \"Zurück\",\n skip: \"Überspringen\",\n done: \"Fertig\",\n awaitClickHint: \"Klicken Sie auf das hervorgehobene Element, um fortzufahren\",\n step: (current, total) => `${n(current)} / ${n(total)}`,\n },\n commandPalette: {\n clear: \"Suche löschen\",\n submit: \"Suchen\",\n close: \"Schließen\",\n placeholder: \"Suchen…\",\n empty: \"Keine Ergebnisse\",\n loading: \"Wird gesucht…\",\n dialog: \"Suche\",\n error: \"Die Suche ist fehlgeschlagen. Bitte erneut versuchen.\",\n },\n globalSearch: {\n trigger: \"Suche\",\n placeholder: \"Suchen oder springen zu…\",\n shortcut: (keys) => `Suche (${keys})`,\n suggestions: \"Vorschläge\",\n results: \"Ergebnisse\",\n },\n sparkline: {\n rising: (first, last) => `Steigend von ${first} auf ${last}`,\n falling: (first, last) => `Fallend von ${first} auf ${last}`,\n flat: (value) => `Unverändert bei ${value}`,\n single: (value) => `Ein Wert: ${value}`,\n noData: \"Keine Daten\",\n named: (name, summary) => `${name}: ${summary}`,\n },\n statTile: {\n // `amount` arrives formatted and unsigned (\"5 %\", \"1.200 €\").\n increase: (amount) => `Um ${amount} gestiegen`,\n decrease: (amount) => `Um ${amount} gesunken`,\n unchanged: \"Keine Veränderung\",\n better: (change) => `${change} (besser)`,\n worse: (change) => `${change} (schlechter)`,\n noValue: \"Keine Daten\",\n loading: \"Wird geladen…\",\n },\n signaturePad: {\n label: \"Unterschrift\",\n instructions: \"Unterschreiben Sie im Feld mit der Maus, dem Finger oder einem Stift.\",\n typedFallbackHint: \"Wenn Sie nicht zeichnen können, geben Sie stattdessen Ihren Namen ein.\",\n empty: \"Noch nichts gezeichnet\",\n signed: \"Unterschrift gezeichnet\",\n undo: \"Letzten Strich rückgängig machen\",\n clear: \"Leeren\",\n save: \"Unterschrift speichern\",\n useTyped: \"Stattdessen Namen eingeben\",\n useDrawn: \"Stattdessen zeichnen\",\n typedName: \"Vollständiger Name\",\n cleared: \"Unterschrift gelöscht\",\n undone: \"Letzter Strich entfernt\",\n viewEmpty: \"Nicht unterschrieben\",\n viewDrawn: \"Handschriftliche Unterschrift\",\n viewTyped: (name) => `Unterschrieben mit dem eingegebenen Namen ${name}`,\n },\n passwordStrength: {\n tooShort: \"Zu kurz\",\n weak: \"Schwach\",\n fair: \"Mittel\",\n good: \"Gut\",\n strong: \"Stark\",\n announcement: (level) => `Passwortstärke: ${level}`,\n // \"Zeichen\" is the same in singular and plural. The English default does not\n // format these counts, so neither does this file.\n ruleLength: (minLength) => `Mindestens ${minLength} Zeichen`,\n ruleCase: \"Groß- und Kleinbuchstaben\",\n ruleDigit: \"Eine Ziffer\",\n ruleSymbol: \"Ein Sonderzeichen\",\n optional: (rule) => `${rule} (optional)`,\n met: \"Erfüllt:\",\n notMet: \"Nicht erfüllt:\",\n tooLong: (maxBytes) =>\n `Höchstens ${maxBytes} Zeichen (Buchstaben mit Akzent und Emojis zählen mehrfach).`,\n },\n seriesChart: {\n resetZoom: \"Zoom zurücksetzen\",\n zoomHint:\n \"Zum Zoomen ziehen: Eine annähernd quadratische Auswahl zoomt beide Achsen, eine lange, schmale nur ihre eigene. Doppelklick setzt zurück.\",\n empty: \"Keine Daten\",\n legend: \"Datenreihen\",\n points: \"Diagrammwerte\",\n },\n pieChart: {\n slices: \"Diagrammsegmente\",\n slice: (label, value, percent) => `${label}: ${value} (${percent})`,\n total: \"Gesamt\",\n empty: \"Keine Daten\",\n legend: \"Kategorien\",\n },\n confirmDialog: {\n confirm: \"Bestätigen\",\n cancel: \"Abbrechen\",\n },\n floatingPanel: {\n close: \"Schließen\",\n badge: (count) => `${n(count)} neu`,\n },\n copyButton: {\n copy: \"Kopieren\",\n copied: \"Kopiert\",\n failed: \"Kopieren fehlgeschlagen\",\n copiedAnnouncement: \"In die Zwischenablage kopiert\",\n failedAnnouncement: \"Kopieren in die Zwischenablage fehlgeschlagen\",\n },\n list: {\n unread: \"Ungelesen\",\n opensInNewTab: \"öffnet in einem neuen Tab\",\n },\n breadcrumbs: {\n label: \"Brotkrümelnavigation\",\n showAll: \"Vollständigen Pfad anzeigen\",\n },\n toast: {\n close: \"Benachrichtigung schließen\",\n notifications: \"Benachrichtigungen\",\n undo: \"Rückgängig\",\n redo: \"Wiederholen\",\n },\n form: {\n save: \"Speichern\",\n cancel: \"Abbrechen\",\n },\n descriptionList: {\n empty: \"—\",\n },\n lineItems: {\n add: \"Zeile hinzufügen\",\n remove: (row) => `Zeile ${row} entfernen`,\n confirmRemove: (row) => `Zeile ${row} entfernen? Zum Bestätigen erneut drücken`,\n row: (row) => `Zeile ${row}`,\n cell: (column, row) => `${column}, Zeile ${row}`,\n totals: \"Summe\",\n },\n progressBar: {\n unlimited: \"Unbegrenzt\",\n overLimit: (amount) => `${amount} über dem Limit`,\n },\n signedAmount: {\n positive: (amount) => `plus ${amount}`,\n negative: (amount) => `minus ${amount}`,\n },\n errorBoundary: {\n title: \"Etwas ist schiefgelaufen\",\n message: \"Dieser Teil der Seite konnte nicht angezeigt werden. Bitte erneut versuchen oder die Seite neu laden.\",\n retry: \"Erneut versuchen\",\n details: \"Fehlerdetails\",\n reload: \"Neu laden\",\n updateTitle: \"Eine neue Version ist verfügbar\",\n updateMessage: \"Ein Teil der App hat sich seit dem Laden dieser Seite geändert. Zum Aktualisieren die Seite neu laden.\",\n offlineTitle: \"Keine Internetverbindung\",\n offlineMessage: \"Diese Seite konnte ohne Verbindung nicht geladen werden. Nach dem Wiederherstellen der Verbindung die Seite neu laden.\",\n copyReport: \"Fehlerbericht kopieren\",\n reported: \"Der Fehler wurde automatisch gemeldet.\",\n reportedAs: (reference) => `Gemeldet unter ${reference}`,\n },\n authedImage: {\n loading: \"Bild wird geladen…\",\n loadError: \"Bild konnte nicht geladen werden\",\n failedImage: (alt) => `${alt}: Bild konnte nicht geladen werden`,\n },\n imageGrid: {\n list: \"Bilder\",\n item: (index, count) => `Bild ${n(index)} von ${n(count)}`,\n actions: (name) => `Aktionen für ${name}`,\n },\n lightbox: {\n dialog: \"Bildansicht\",\n close: \"Schließen\",\n previous: \"Vorheriges Bild\",\n next: \"Nächstes Bild\",\n counter: (index, count) => `${n(index)} / ${n(count)}`,\n position: (index, count) => `Bild ${n(index)} von ${n(count)}`,\n download: \"Herunterladen\",\n zoom: \"Zoomen\",\n noPreview: \"Für diese Datei ist keine Vorschau verfügbar\",\n openInNewTab: \"In neuem Tab öffnen\",\n },\n };\n}\n\nexport const UI_KIT_LABELS_DE: UiKitLabels = uiKitLabelsDe();\n"],"mappings":"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","names":[]}
|