@antontranelis/money-printer 1.0.2 → 1.0.4

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/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
- import { jsxs as m, jsx as o, Fragment as z } from "react/jsx-runtime";
2
- import { create as le } from "zustand";
3
- import { persist as se } from "zustand/middleware";
4
- import { useState as C, useCallback as E, useRef as A, useEffect as O } from "react";
5
- import ce from "jspdf";
6
- const Y = {
1
+ import { jsxs as g, jsx as i, Fragment as $ } from "react/jsx-runtime";
2
+ import { create as me } from "zustand";
3
+ import { persist as ue } from "zustand/middleware";
4
+ import { useState as N, useCallback as S, useRef as L, useEffect as V } from "react";
5
+ import ge from "jspdf";
6
+ const G = {
7
7
  personalInfo: {
8
8
  name: "",
9
9
  email: "",
@@ -23,27 +23,27 @@ const Y = {
23
23
  currentSide: "front",
24
24
  isEnhancing: !1,
25
25
  isExporting: !1
26
- }, g = le()(
27
- se(
26
+ }, w = me()(
27
+ ue(
28
28
  (e) => ({
29
- ...Y,
30
- setPersonalInfo: (t) => e((n) => ({
31
- personalInfo: { ...n.personalInfo, ...t }
29
+ ...G,
30
+ setPersonalInfo: (t) => e((a) => ({
31
+ personalInfo: { ...a.personalInfo, ...t }
32
32
  })),
33
- setVoucherConfig: (t) => e((n) => ({
34
- voucherConfig: { ...n.voucherConfig, ...t }
33
+ setVoucherConfig: (t) => e((a) => ({
34
+ voucherConfig: { ...a.voucherConfig, ...t }
35
35
  })),
36
- setPortrait: (t, n = null) => e({
36
+ setPortrait: (t, a = null) => e({
37
37
  portrait: {
38
38
  original: t,
39
- enhanced: n,
39
+ enhanced: a,
40
40
  useEnhanced: !1,
41
41
  zoom: 1
42
42
  }
43
43
  }),
44
- setEnhancedPortrait: (t) => e((n) => ({
44
+ setEnhancedPortrait: (t) => e((a) => ({
45
45
  portrait: {
46
- ...n.portrait,
46
+ ...a.portrait,
47
47
  enhanced: t,
48
48
  useEnhanced: t !== null
49
49
  }
@@ -54,9 +54,9 @@ const Y = {
54
54
  useEnhanced: t.portrait.enhanced ? !t.portrait.useEnhanced : !1
55
55
  }
56
56
  })),
57
- setPortraitZoom: (t) => e((n) => ({
57
+ setPortraitZoom: (t) => e((a) => ({
58
58
  portrait: {
59
- ...n.portrait,
59
+ ...a.portrait,
60
60
  zoom: t
61
61
  }
62
62
  })),
@@ -66,13 +66,13 @@ const Y = {
66
66
  })),
67
67
  setIsEnhancing: (t) => e({ isEnhancing: t }),
68
68
  setIsExporting: (t) => e({ isExporting: t }),
69
- setLanguage: (t) => e((n) => ({
70
- voucherConfig: { ...n.voucherConfig, language: t }
69
+ setLanguage: (t) => e((a) => ({
70
+ voucherConfig: { ...a.voucherConfig, language: t }
71
71
  })),
72
- setHours: (t) => e((n) => ({
73
- voucherConfig: { ...n.voucherConfig, hours: t }
72
+ setHours: (t) => e((a) => ({
73
+ voucherConfig: { ...a.voucherConfig, hours: t }
74
74
  })),
75
- reset: () => e(Y)
75
+ reset: () => e(G)
76
76
  }),
77
77
  {
78
78
  name: "money-generator-storage",
@@ -82,7 +82,7 @@ const Y = {
82
82
  })
83
83
  }
84
84
  )
85
- ), de = {
85
+ ), fe = {
86
86
  header: {
87
87
  title: "Money Generator",
88
88
  subtitle: "Erstelle deinen persönlichen Zeitgutschein"
@@ -129,7 +129,7 @@ const Y = {
129
129
  bill: {
130
130
  descriptionText: "Für diesen Schein erhältst du {hours} {hourLabel} meiner Zeit oder ein gleichwertiges Dankeschön"
131
131
  }
132
- }, he = {
132
+ }, be = {
133
133
  header: {
134
134
  title: "Money Generator",
135
135
  subtitle: "Create your personal time voucher"
@@ -176,161 +176,236 @@ const Y = {
176
176
  bill: {
177
177
  descriptionText: "This voucher entitles you to {hours} {hourLabel} of my time or an equivalent thank you"
178
178
  }
179
- }, pe = { de, en: he };
179
+ }, we = { de: fe, en: be };
180
180
  function _(e) {
181
- return pe[e];
181
+ return we[e];
182
182
  }
183
- function G(e, t, n) {
184
- if (n && n.trim())
185
- return n;
186
- const a = _(e), r = t === 1 ? a.form.voucher.hourLabel : a.form.voucher.hoursLabel;
187
- return a.bill.descriptionText.replace("{hours}", t.toString()).replace("{hourLabel}", r);
183
+ function ee(e, t, a) {
184
+ if (a && a.trim())
185
+ return a;
186
+ const n = _(e), r = t === 1 ? n.form.voucher.hourLabel : n.form.voucher.hoursLabel;
187
+ return n.bill.descriptionText.replace("{hours}", t.toString()).replace("{hourLabel}", r);
188
188
  }
189
- function ze() {
190
- const e = g((r) => r.voucherConfig.language), t = g((r) => r.personalInfo), n = g((r) => r.setPersonalInfo), a = _(e);
191
- return /* @__PURE__ */ m("div", { className: "space-y-4", children: [
192
- /* @__PURE__ */ m("div", { className: "form-control", children: [
193
- /* @__PURE__ */ o("label", { className: "label", children: /* @__PURE__ */ o("span", { className: "label-text font-medium", children: a.form.personalInfo.name }) }),
194
- /* @__PURE__ */ o(
189
+ function je() {
190
+ const e = w((r) => r.voucherConfig.language), t = w((r) => r.personalInfo), a = w((r) => r.setPersonalInfo), n = _(e);
191
+ return /* @__PURE__ */ g("div", { className: "space-y-4", children: [
192
+ /* @__PURE__ */ g("div", { className: "form-control", children: [
193
+ /* @__PURE__ */ i("label", { className: "label", children: /* @__PURE__ */ i("span", { className: "label-text font-medium", children: n.form.personalInfo.name }) }),
194
+ /* @__PURE__ */ i(
195
195
  "input",
196
196
  {
197
197
  type: "text",
198
- placeholder: a.form.personalInfo.namePlaceholder,
198
+ placeholder: n.form.personalInfo.namePlaceholder,
199
199
  className: "input input-bordered w-full",
200
200
  value: t.name,
201
- onChange: (r) => n({ name: r.target.value })
201
+ onChange: (r) => a({ name: r.target.value })
202
202
  }
203
203
  )
204
204
  ] }),
205
- /* @__PURE__ */ m("div", { className: "form-control", children: [
206
- /* @__PURE__ */ o("label", { className: "label", children: /* @__PURE__ */ o("span", { className: "label-text font-medium", children: a.form.personalInfo.email }) }),
207
- /* @__PURE__ */ o(
205
+ /* @__PURE__ */ g("div", { className: "form-control", children: [
206
+ /* @__PURE__ */ i("label", { className: "label", children: /* @__PURE__ */ i("span", { className: "label-text font-medium", children: n.form.personalInfo.email }) }),
207
+ /* @__PURE__ */ i(
208
208
  "input",
209
209
  {
210
210
  type: "email",
211
- placeholder: a.form.personalInfo.emailPlaceholder,
211
+ placeholder: n.form.personalInfo.emailPlaceholder,
212
212
  className: "input input-bordered w-full",
213
213
  value: t.email,
214
- onChange: (r) => n({ email: r.target.value })
214
+ onChange: (r) => a({ email: r.target.value })
215
215
  }
216
216
  )
217
217
  ] }),
218
- /* @__PURE__ */ m("div", { className: "form-control", children: [
219
- /* @__PURE__ */ o("label", { className: "label", children: /* @__PURE__ */ o("span", { className: "label-text font-medium", children: a.form.personalInfo.phone }) }),
220
- /* @__PURE__ */ o(
218
+ /* @__PURE__ */ g("div", { className: "form-control", children: [
219
+ /* @__PURE__ */ i("label", { className: "label", children: /* @__PURE__ */ i("span", { className: "label-text font-medium", children: n.form.personalInfo.phone }) }),
220
+ /* @__PURE__ */ i(
221
221
  "input",
222
222
  {
223
223
  type: "tel",
224
- placeholder: a.form.personalInfo.phonePlaceholder,
224
+ placeholder: n.form.personalInfo.phonePlaceholder,
225
225
  className: "input input-bordered w-full",
226
226
  value: t.phone,
227
- onChange: (r) => n({ phone: r.target.value })
227
+ onChange: (r) => a({ phone: r.target.value })
228
228
  }
229
229
  )
230
230
  ] })
231
231
  ] });
232
232
  }
233
- const F = {}, ue = "https://api.stability.ai/v1/generation", me = {
233
+ const K = {}, ye = "https://api.stability.ai/v1/generation", ve = "https://api.stability.ai/v2beta/stable-image/edit/remove-background", te = "stability_api_key", xe = {
234
234
  vintage: "portrait in the style of vintage currency engraving, fine line work, crosshatching, sepia tones, detailed stippling, classic bank note portrait style",
235
235
  engraved: "portrait as detailed intaglio engraving, currency bill style, fine parallel lines, high contrast, official government portrait",
236
236
  currency: "portrait rendered as US dollar bill engraving, official currency portrait style, green tint, fine line engraving technique"
237
- };
238
- function ge(e) {
239
- var s;
240
- const t = e.split(","), n = ((s = t[0].match(/:(.*?);/)) == null ? void 0 : s[1]) || "image/png", a = atob(t[1]), r = a.length, l = new Uint8Array(r);
241
- for (let d = 0; d < r; d++)
242
- l[d] = a.charCodeAt(d);
243
- return new Blob([l], { type: n });
237
+ }, Z = [
238
+ { width: 1024, height: 1024 },
239
+ { width: 1152, height: 896 },
240
+ { width: 1216, height: 832 },
241
+ { width: 1344, height: 768 },
242
+ { width: 1536, height: 640 },
243
+ { width: 640, height: 1536 },
244
+ { width: 768, height: 1344 },
245
+ { width: 832, height: 1216 },
246
+ { width: 896, height: 1152 }
247
+ ];
248
+ function ke(e, t) {
249
+ const a = e / t;
250
+ let n = Z[0], r = 1 / 0;
251
+ for (const o of Z) {
252
+ const d = o.width / o.height, l = Math.abs(a - d);
253
+ l < r && (r = l, n = o);
254
+ }
255
+ return n;
244
256
  }
245
- function X() {
257
+ function Ie(e) {
258
+ return new Promise((t, a) => {
259
+ const n = new Image();
260
+ n.onload = () => {
261
+ const r = ke(n.width, n.height), o = document.createElement("canvas");
262
+ o.width = r.width, o.height = r.height;
263
+ const d = o.getContext("2d");
264
+ if (!d) {
265
+ a(new Error("Failed to get canvas context"));
266
+ return;
267
+ }
268
+ const l = n.width / n.height, s = r.width / r.height;
269
+ let c = 0, m = 0, f = n.width, b = n.height;
270
+ l > s ? (f = n.height * s, c = (n.width - f) / 2) : (b = n.width / s, m = (n.height - b) / 2), d.drawImage(n, c, m, f, b, 0, 0, r.width, r.height), t(o.toDataURL("image/png"));
271
+ }, n.onerror = () => a(new Error("Failed to load image")), n.src = e;
272
+ });
273
+ }
274
+ function ne(e) {
275
+ var d;
276
+ const t = e.split(","), a = ((d = t[0].match(/:(.*?);/)) == null ? void 0 : d[1]) || "image/png", n = atob(t[1]), r = n.length, o = new Uint8Array(r);
277
+ for (let l = 0; l < r; l++)
278
+ o[l] = n.charCodeAt(l);
279
+ return new Blob([o], { type: a });
280
+ }
281
+ function Y() {
246
282
  var t;
247
- const e = typeof import.meta < "u" && (F == null ? void 0 : F.VITE_STABILITY_API_KEY) || typeof process < "u" && ((t = process.env) == null ? void 0 : t.NEXT_PUBLIC_STABILITY_API_KEY);
248
- return e && e !== "your-api-key-here" ? e : typeof localStorage < "u" ? localStorage.getItem("stability_api_key") : null;
283
+ const e = typeof import.meta < "u" && (K == null ? void 0 : K.VITE_STABILITY_API_KEY) || typeof process < "u" && ((t = process.env) == null ? void 0 : t.NEXT_PUBLIC_STABILITY_API_KEY);
284
+ return e && e !== "your-api-key-here" ? e : typeof localStorage < "u" ? localStorage.getItem(te) : null;
249
285
  }
250
- function fe(e) {
251
- localStorage.setItem("stability_api_key", e);
286
+ function Ee(e) {
287
+ localStorage.setItem(te, e);
252
288
  }
253
- function q() {
254
- return X() !== null;
289
+ function X() {
290
+ return Y() !== null;
255
291
  }
256
- async function be(e) {
257
- const t = X();
292
+ async function Pe(e) {
293
+ const t = Y();
258
294
  if (!t)
259
295
  throw new Error("No Stability AI API key configured");
260
- const { imageDataUrl: n, style: a, strength: r = 0.35 } = e, l = ge(n), s = new FormData();
261
- s.append("init_image", l, "portrait.png"), s.append("init_image_mode", "IMAGE_STRENGTH"), s.append("image_strength", String(1 - r)), s.append("text_prompts[0][text]", me[a]), s.append("text_prompts[0][weight]", "1"), s.append("cfg_scale", "7"), s.append("samples", "1"), s.append("steps", "30");
262
- const i = await fetch(`${ue}/stable-diffusion-xl-1024-v1-0/image-to-image`, {
296
+ const { imageDataUrl: a, style: n, strength: r = 0.35 } = e, o = await Ie(a), d = ne(o), l = new FormData();
297
+ l.append("init_image", d, "portrait.png"), l.append("init_image_mode", "IMAGE_STRENGTH"), l.append("image_strength", String(1 - r)), l.append("text_prompts[0][text]", xe[n]), l.append("text_prompts[0][weight]", "1"), l.append("cfg_scale", "7"), l.append("samples", "1"), l.append("steps", "30");
298
+ const c = await fetch(`${ye}/stable-diffusion-xl-1024-v1-0/image-to-image`, {
263
299
  method: "POST",
264
300
  headers: {
265
301
  Authorization: `Bearer ${t}`,
266
302
  Accept: "application/json"
267
303
  },
268
- body: s
304
+ body: l
269
305
  });
270
- if (!i.ok) {
271
- const f = await i.text();
272
- throw console.error("Stability AI error:", f), i.status === 401 ? new Error("Invalid API key") : i.status === 402 ? new Error("Insufficient credits") : i.status === 429 ? new Error("Rate limit exceeded. Please try again later.") : new Error(`API error: ${i.status}`);
306
+ if (!c.ok) {
307
+ const f = await c.text();
308
+ throw console.error("Stability AI error:", f), c.status === 401 ? new Error("Invalid API key") : c.status === 402 ? new Error("Insufficient credits") : c.status === 429 ? new Error("Rate limit exceeded. Please try again later.") : new Error(`API error: ${c.status}`);
273
309
  }
274
- const c = await i.json();
275
- if (!c.artifacts || c.artifacts.length === 0)
310
+ const m = await c.json();
311
+ if (!m.artifacts || m.artifacts.length === 0)
276
312
  throw new Error("No image generated");
277
- return `data:image/png;base64,${c.artifacts[0].base64}`;
313
+ return `data:image/png;base64,${m.artifacts[0].base64}`;
278
314
  }
279
- async function V(e) {
280
- return new Promise((t, n) => {
281
- const a = new Image();
282
- a.onload = () => {
283
- const r = document.createElement("canvas"), l = r.getContext("2d");
284
- if (!l) {
285
- n(new Error("Failed to get canvas context"));
315
+ async function Ne(e) {
316
+ const t = Y();
317
+ if (!t)
318
+ throw new Error("No Stability AI API key configured");
319
+ const a = ne(e), n = new FormData();
320
+ n.append("image", a, "image.png"), n.append("output_format", "png");
321
+ const r = await fetch(ve, {
322
+ method: "POST",
323
+ headers: {
324
+ Authorization: `Bearer ${t}`,
325
+ Accept: "image/*"
326
+ },
327
+ body: n
328
+ });
329
+ if (!r.ok) {
330
+ const d = await r.text();
331
+ throw console.error("Stability AI remove background error:", d), r.status === 401 ? new Error("Invalid API key") : r.status === 402 ? new Error("Insufficient credits") : r.status === 429 ? new Error("Rate limit exceeded. Please try again later.") : new Error(`API error: ${r.status}`);
332
+ }
333
+ const o = await r.blob();
334
+ return new Promise((d, l) => {
335
+ const s = new FileReader();
336
+ s.onload = () => d(s.result), s.onerror = () => l(new Error("Failed to read result")), s.readAsDataURL(o);
337
+ });
338
+ }
339
+ async function J(e) {
340
+ return new Promise((t, a) => {
341
+ const n = new Image();
342
+ n.onload = () => {
343
+ const r = document.createElement("canvas"), o = r.getContext("2d");
344
+ if (!o) {
345
+ a(new Error("Failed to get canvas context"));
286
346
  return;
287
347
  }
288
- r.width = a.width, r.height = a.height, l.filter = "sepia(0.3) contrast(1.1) saturate(0.9)", l.drawImage(a, 0, 0), t(r.toDataURL("image/png"));
289
- }, a.onerror = () => n(new Error("Failed to load image")), a.src = e;
348
+ r.width = n.width, r.height = n.height, o.filter = "sepia(0.3) contrast(1.1) saturate(0.9)", o.drawImage(n, 0, 0), t(r.toDataURL("image/png"));
349
+ }, n.onerror = () => a(new Error("Failed to load image")), n.src = e;
290
350
  });
291
351
  }
292
- function ye() {
293
- const [e, t] = C(!1), [n, a] = C(null), [r, l] = C(q()), s = E(() => a(null), []), d = E((c) => {
294
- fe(c), l(!0), a(null);
295
- }, []);
352
+ function Se() {
353
+ const [e, t] = N(!1), [a, n] = N(!1), [r, o] = N(null), [d, l] = N(X()), s = S(() => o(null), []), c = S((b) => {
354
+ Ee(b), l(!0), o(null);
355
+ }, []), m = S(
356
+ async (b, u = "vintage") => {
357
+ t(!0), o(null);
358
+ try {
359
+ return X() ? await Pe({
360
+ imageDataUrl: b,
361
+ style: u,
362
+ strength: 0.35
363
+ }) : await J(b);
364
+ } catch (h) {
365
+ const k = h instanceof Error ? h.message : "Enhancement failed";
366
+ if (o(k), k.includes("API") || k.includes("key"))
367
+ try {
368
+ return await J(b);
369
+ } catch {
370
+ throw h;
371
+ }
372
+ throw h;
373
+ } finally {
374
+ t(!1);
375
+ }
376
+ },
377
+ []
378
+ ), f = S(
379
+ async (b) => {
380
+ n(!0), o(null);
381
+ try {
382
+ return await Ne(b);
383
+ } catch (u) {
384
+ const h = u instanceof Error ? u.message : "Background removal failed";
385
+ throw o(h), u;
386
+ } finally {
387
+ n(!1);
388
+ }
389
+ },
390
+ []
391
+ );
296
392
  return {
297
- enhance: E(
298
- async (c, f = "vintage") => {
299
- t(!0), a(null);
300
- try {
301
- return q() ? await be({
302
- imageDataUrl: c,
303
- style: f,
304
- strength: 0.35
305
- }) : await V(c);
306
- } catch (p) {
307
- const b = p instanceof Error ? p.message : "Enhancement failed";
308
- if (a(b), b.includes("API") || b.includes("key"))
309
- try {
310
- return await V(c);
311
- } catch {
312
- throw p;
313
- }
314
- throw p;
315
- } finally {
316
- t(!1);
317
- }
318
- },
319
- []
320
- ),
393
+ enhance: m,
394
+ removeBg: f,
321
395
  isEnhancing: e,
322
- error: n,
323
- hasKey: r,
324
- setApiKey: d,
396
+ isRemovingBg: a,
397
+ error: r,
398
+ hasKey: d,
399
+ setApiKey: c,
325
400
  clearError: s
326
401
  };
327
402
  }
328
- function ve({ isOpen: e, onClose: t, onSubmit: n }) {
329
- const a = g((c) => c.voucherConfig.language), [r, l] = C("");
403
+ function Ce({ isOpen: e, onClose: t, onSubmit: a }) {
404
+ const n = w((c) => c.voucherConfig.language), [r, o] = N("");
330
405
  if (!e) return null;
331
- const s = (c) => {
332
- c.preventDefault(), r.trim() && (n(r.trim()), l(""), t());
333
- }, i = {
406
+ const d = (c) => {
407
+ c.preventDefault(), r.trim() && (a(r.trim()), o(""), t());
408
+ }, s = {
334
409
  de: {
335
410
  title: "Stability AI API Key",
336
411
  description: "Um die AI-Bildverbesserung zu nutzen, benötigst du einen Stability AI API Key. Du kannst ihn auf platform.stability.ai erhalten.",
@@ -347,108 +422,116 @@ function ve({ isOpen: e, onClose: t, onSubmit: n }) {
347
422
  cancel: "Cancel",
348
423
  hint: "The key is stored locally in your browser."
349
424
  }
350
- }[a];
351
- return /* @__PURE__ */ m("dialog", { className: "modal modal-open", children: [
352
- /* @__PURE__ */ m("div", { className: "modal-box", children: [
353
- /* @__PURE__ */ o("h3", { className: "font-bold text-lg", children: i.title }),
354
- /* @__PURE__ */ o("p", { className: "py-4 text-sm opacity-80", children: i.description }),
355
- /* @__PURE__ */ m("form", { onSubmit: s, children: [
356
- /* @__PURE__ */ m("div", { className: "form-control", children: [
357
- /* @__PURE__ */ o(
425
+ }[n];
426
+ return /* @__PURE__ */ g("dialog", { className: "modal modal-open", children: [
427
+ /* @__PURE__ */ g("div", { className: "modal-box", children: [
428
+ /* @__PURE__ */ i("h3", { className: "font-bold text-lg", children: s.title }),
429
+ /* @__PURE__ */ i("p", { className: "py-4 text-sm opacity-80", children: s.description }),
430
+ /* @__PURE__ */ g("form", { onSubmit: d, children: [
431
+ /* @__PURE__ */ g("div", { className: "form-control", children: [
432
+ /* @__PURE__ */ i(
358
433
  "input",
359
434
  {
360
435
  type: "password",
361
- placeholder: i.placeholder,
436
+ placeholder: s.placeholder,
362
437
  className: "input input-bordered w-full",
363
438
  value: r,
364
- onChange: (c) => l(c.target.value),
439
+ onChange: (c) => o(c.target.value),
365
440
  autoFocus: !0
366
441
  }
367
442
  ),
368
- /* @__PURE__ */ o("label", { className: "label", children: /* @__PURE__ */ o("span", { className: "label-text-alt", children: i.hint }) })
443
+ /* @__PURE__ */ i("label", { className: "label", children: /* @__PURE__ */ i("span", { className: "label-text-alt", children: s.hint }) })
369
444
  ] }),
370
- /* @__PURE__ */ m("div", { className: "modal-action", children: [
371
- /* @__PURE__ */ o("button", { type: "button", className: "btn btn-ghost", onClick: t, children: i.cancel }),
372
- /* @__PURE__ */ o("button", { type: "submit", className: "btn btn-primary", disabled: !r.trim(), children: i.submit })
445
+ /* @__PURE__ */ g("div", { className: "modal-action", children: [
446
+ /* @__PURE__ */ i("button", { type: "button", className: "btn btn-ghost", onClick: t, children: s.cancel }),
447
+ /* @__PURE__ */ i("button", { type: "submit", className: "btn btn-primary", disabled: !r.trim(), children: s.submit })
373
448
  ] })
374
449
  ] })
375
450
  ] }),
376
- /* @__PURE__ */ o("form", { method: "dialog", className: "modal-backdrop", children: /* @__PURE__ */ o("button", { onClick: t, children: "close" }) })
451
+ /* @__PURE__ */ i("form", { method: "dialog", className: "modal-backdrop", children: /* @__PURE__ */ i("button", { onClick: t, children: "close" }) })
377
452
  ] });
378
453
  }
379
- function Re() {
380
- const e = g((h) => h.voucherConfig.language), t = g((h) => h.portrait), n = g((h) => h.setPortrait), a = g((h) => h.setEnhancedPortrait), r = g((h) => h.toggleUseEnhanced), l = g((h) => h.setPortraitZoom), { enhance: s, isEnhancing: d, error: i, hasKey: c, setApiKey: f } = ye(), p = _(e), b = A(null), [v, u] = C(!1), [N, I] = C(!1), k = E(
381
- (h) => {
382
- if (!h.type.startsWith("image/"))
454
+ function Ye() {
455
+ const e = w((p) => p.voucherConfig.language), t = w((p) => p.portrait), a = w((p) => p.setPortrait), n = w((p) => p.setEnhancedPortrait), r = w((p) => p.toggleUseEnhanced), o = w((p) => p.setPortraitZoom), { enhance: d, removeBg: l, isEnhancing: s, isRemovingBg: c, error: m, hasKey: f, setApiKey: b } = Se(), u = _(e), h = L(null), [k, I] = N(!1), [E, C] = N(!1), y = S(
456
+ async (p) => {
457
+ if (!p.type.startsWith("image/"))
383
458
  return;
384
- const w = new FileReader();
385
- w.onload = (B) => {
386
- var K;
387
- const ie = (K = B.target) == null ? void 0 : K.result;
388
- n(ie);
389
- }, w.readAsDataURL(h);
459
+ const v = new FileReader();
460
+ v.onload = async (R) => {
461
+ var q;
462
+ const F = (q = R.target) == null ? void 0 : q.result;
463
+ if (f)
464
+ try {
465
+ const W = await l(F);
466
+ a(W);
467
+ } catch (W) {
468
+ console.error("Background removal failed, using original:", W), a(F);
469
+ }
470
+ else
471
+ a(F);
472
+ }, v.readAsDataURL(p);
390
473
  },
391
- [n]
392
- ), S = E(
393
- (h) => {
394
- h.preventDefault(), u(!1);
395
- const w = h.dataTransfer.files[0];
396
- w && k(w);
474
+ [a, f, l]
475
+ ), P = S(
476
+ (p) => {
477
+ p.preventDefault(), I(!1);
478
+ const v = p.dataTransfer.files[0];
479
+ v && y(v);
397
480
  },
398
- [k]
399
- ), y = E((h) => {
400
- h.preventDefault(), u(!0);
401
- }, []), P = E((h) => {
402
- h.preventDefault(), u(!1);
403
- }, []), D = () => {
404
- var h;
405
- (h = b.current) == null || h.click();
406
- }, $ = (h) => {
407
- var B;
408
- const w = (B = h.target.files) == null ? void 0 : B[0];
409
- w && k(w);
410
- }, M = async () => {
481
+ [y]
482
+ ), D = S((p) => {
483
+ p.preventDefault(), I(!0);
484
+ }, []), B = S((p) => {
485
+ p.preventDefault(), I(!1);
486
+ }, []), M = () => {
487
+ var p;
488
+ (p = h.current) == null || p.click();
489
+ }, U = (p) => {
490
+ var R;
491
+ const v = (R = p.target.files) == null ? void 0 : R[0];
492
+ v && y(v);
493
+ }, ce = async () => {
411
494
  if (t.original) {
412
- if (!c) {
413
- I(!0);
495
+ if (!f) {
496
+ C(!0);
414
497
  return;
415
498
  }
416
499
  try {
417
- const h = await s(t.original, "vintage");
418
- a(h);
419
- } catch (h) {
420
- console.error("Enhancement failed:", h);
500
+ const p = await d(t.original, "vintage");
501
+ n(p);
502
+ } catch (p) {
503
+ console.error("Enhancement failed:", p);
421
504
  }
422
505
  }
423
- }, U = async (h) => {
424
- if (f(h), t.original)
506
+ }, de = async (p) => {
507
+ if (b(p), t.original)
425
508
  try {
426
- const w = await s(t.original, "vintage");
427
- a(w);
428
- } catch (w) {
429
- console.error("Enhancement failed:", w);
509
+ const v = await d(t.original, "vintage");
510
+ n(v);
511
+ } catch (v) {
512
+ console.error("Enhancement failed:", v);
430
513
  }
431
- }, re = () => {
432
- n(null);
433
- }, oe = t.useEnhanced && t.enhanced ? t.enhanced : t.original;
434
- return /* @__PURE__ */ m("div", { className: "space-y-4", children: [
435
- t.original ? /* @__PURE__ */ m("div", { className: "space-y-4", children: [
436
- /* @__PURE__ */ o("div", { className: "flex justify-center", children: /* @__PURE__ */ m("div", { className: "relative", children: [
437
- /* @__PURE__ */ o("div", { className: "w-32 h-32 rounded-full overflow-hidden border-4 border-currency-gold shadow-lg", children: /* @__PURE__ */ o(
514
+ }, he = () => {
515
+ a(null);
516
+ }, pe = t.useEnhanced && t.enhanced ? t.enhanced : t.original;
517
+ return /* @__PURE__ */ g("div", { className: "space-y-4", children: [
518
+ t.original ? /* @__PURE__ */ g("div", { className: "space-y-4", children: [
519
+ /* @__PURE__ */ i("div", { className: "flex justify-center", children: /* @__PURE__ */ g("div", { className: "relative", children: [
520
+ /* @__PURE__ */ i("div", { className: "w-32 h-32 rounded-full overflow-hidden border-4 border-currency-gold shadow-lg", children: /* @__PURE__ */ i(
438
521
  "img",
439
522
  {
440
- src: oe || "",
523
+ src: pe || "",
441
524
  alt: "Portrait",
442
525
  className: "w-full h-full object-cover",
443
526
  style: { transform: `scale(${t.zoom})` }
444
527
  }
445
528
  ) }),
446
- /* @__PURE__ */ o(
529
+ /* @__PURE__ */ i(
447
530
  "button",
448
531
  {
449
532
  className: "btn btn-circle btn-xs btn-error absolute -top-1 -right-1",
450
- onClick: re,
451
- children: /* @__PURE__ */ o(
533
+ onClick: he,
534
+ children: /* @__PURE__ */ i(
452
535
  "svg",
453
536
  {
454
537
  xmlns: "http://www.w3.org/2000/svg",
@@ -456,7 +539,7 @@ function Re() {
456
539
  fill: "none",
457
540
  viewBox: "0 0 24 24",
458
541
  stroke: "currentColor",
459
- children: /* @__PURE__ */ o(
542
+ children: /* @__PURE__ */ i(
460
543
  "path",
461
544
  {
462
545
  strokeLinecap: "round",
@@ -470,15 +553,15 @@ function Re() {
470
553
  }
471
554
  )
472
555
  ] }) }),
473
- /* @__PURE__ */ m("div", { className: "form-control", children: [
474
- /* @__PURE__ */ m("label", { className: "label", children: [
475
- /* @__PURE__ */ o("span", { className: "label-text", children: p.form.portrait.zoom }),
476
- /* @__PURE__ */ m("span", { className: "label-text-alt", children: [
556
+ /* @__PURE__ */ g("div", { className: "form-control", children: [
557
+ /* @__PURE__ */ g("label", { className: "label", children: [
558
+ /* @__PURE__ */ i("span", { className: "label-text", children: u.form.portrait.zoom }),
559
+ /* @__PURE__ */ g("span", { className: "label-text-alt", children: [
477
560
  Math.round(t.zoom * 100),
478
561
  "%"
479
562
  ] })
480
563
  ] }),
481
- /* @__PURE__ */ o(
564
+ /* @__PURE__ */ i(
482
565
  "input",
483
566
  {
484
567
  type: "range",
@@ -486,23 +569,23 @@ function Re() {
486
569
  max: "2",
487
570
  step: "0.05",
488
571
  value: t.zoom,
489
- onChange: (h) => l(parseFloat(h.target.value)),
572
+ onChange: (p) => o(parseFloat(p.target.value)),
490
573
  className: "range range-primary range-sm"
491
574
  }
492
575
  )
493
576
  ] }),
494
- c && /* @__PURE__ */ m("div", { className: "flex flex-col gap-2", children: [
495
- /* @__PURE__ */ o(
577
+ f && /* @__PURE__ */ g("div", { className: "flex flex-col gap-2", children: [
578
+ /* @__PURE__ */ i(
496
579
  "button",
497
580
  {
498
- className: `btn btn-secondary ${d ? "loading" : ""}`,
499
- onClick: M,
500
- disabled: d,
501
- children: d ? /* @__PURE__ */ m(z, { children: [
502
- /* @__PURE__ */ o("span", { className: "loading loading-spinner loading-sm" }),
503
- p.form.portrait.enhancing
504
- ] }) : /* @__PURE__ */ m(z, { children: [
505
- /* @__PURE__ */ o(
581
+ className: `btn btn-secondary ${s ? "loading" : ""}`,
582
+ onClick: ce,
583
+ disabled: s,
584
+ children: s ? /* @__PURE__ */ g($, { children: [
585
+ /* @__PURE__ */ i("span", { className: "loading loading-spinner loading-sm" }),
586
+ u.form.portrait.enhancing
587
+ ] }) : /* @__PURE__ */ g($, { children: [
588
+ /* @__PURE__ */ i(
506
589
  "svg",
507
590
  {
508
591
  xmlns: "http://www.w3.org/2000/svg",
@@ -510,7 +593,7 @@ function Re() {
510
593
  fill: "none",
511
594
  viewBox: "0 0 24 24",
512
595
  stroke: "currentColor",
513
- children: /* @__PURE__ */ o(
596
+ children: /* @__PURE__ */ i(
514
597
  "path",
515
598
  {
516
599
  strokeLinecap: "round",
@@ -521,16 +604,16 @@ function Re() {
521
604
  )
522
605
  }
523
606
  ),
524
- p.form.portrait.enhance
607
+ u.form.portrait.enhance
525
608
  ] })
526
609
  }
527
610
  ),
528
- i && /* @__PURE__ */ m("div", { className: "alert alert-warning text-sm py-2", children: [
529
- /* @__PURE__ */ o("svg", { xmlns: "http://www.w3.org/2000/svg", className: "stroke-current shrink-0 h-5 w-5", fill: "none", viewBox: "0 0 24 24", children: /* @__PURE__ */ o("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" }) }),
530
- /* @__PURE__ */ o("span", { children: i })
611
+ m && /* @__PURE__ */ g("div", { className: "alert alert-warning text-sm py-2", children: [
612
+ /* @__PURE__ */ i("svg", { xmlns: "http://www.w3.org/2000/svg", className: "stroke-current shrink-0 h-5 w-5", fill: "none", viewBox: "0 0 24 24", children: /* @__PURE__ */ i("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "2", d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" }) }),
613
+ /* @__PURE__ */ i("span", { children: m })
531
614
  ] }),
532
- t.enhanced && /* @__PURE__ */ o("div", { className: "form-control", children: /* @__PURE__ */ m("label", { className: "label cursor-pointer justify-start gap-3", children: [
533
- /* @__PURE__ */ o(
615
+ t.enhanced && /* @__PURE__ */ i("div", { className: "form-control", children: /* @__PURE__ */ g("label", { className: "label cursor-pointer justify-start gap-3", children: [
616
+ /* @__PURE__ */ i(
534
617
  "input",
535
618
  {
536
619
  type: "checkbox",
@@ -539,30 +622,33 @@ function Re() {
539
622
  onChange: r
540
623
  }
541
624
  ),
542
- /* @__PURE__ */ o("span", { className: "label-text", children: t.useEnhanced ? p.form.portrait.useEnhanced : p.form.portrait.useOriginal })
625
+ /* @__PURE__ */ i("span", { className: "label-text", children: t.useEnhanced ? u.form.portrait.useEnhanced : u.form.portrait.useOriginal })
543
626
  ] }) })
544
627
  ] })
545
- ] }) : /* @__PURE__ */ m(
628
+ ] }) : /* @__PURE__ */ g(
546
629
  "div",
547
630
  {
548
- className: `border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${v ? "border-primary bg-primary/10" : "border-base-300 hover:border-primary hover:bg-base-200"}`,
549
- onDrop: S,
550
- onDragOver: y,
551
- onDragLeave: P,
552
- onClick: D,
631
+ className: `border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${c ? "border-primary bg-primary/10 pointer-events-none" : k ? "border-primary bg-primary/10" : "border-base-300 hover:border-primary hover:bg-base-200"}`,
632
+ onDrop: P,
633
+ onDragOver: D,
634
+ onDragLeave: B,
635
+ onClick: M,
553
636
  children: [
554
- /* @__PURE__ */ o(
637
+ /* @__PURE__ */ i(
555
638
  "input",
556
639
  {
557
- ref: b,
640
+ ref: h,
558
641
  type: "file",
559
642
  accept: "image/*",
560
643
  className: "hidden",
561
- onChange: $
644
+ onChange: U
562
645
  }
563
646
  ),
564
- /* @__PURE__ */ m("div", { className: "flex flex-col items-center gap-2", children: [
565
- /* @__PURE__ */ o(
647
+ c ? /* @__PURE__ */ g("div", { className: "flex flex-col items-center gap-2", children: [
648
+ /* @__PURE__ */ i("span", { className: "loading loading-spinner loading-lg text-primary" }),
649
+ /* @__PURE__ */ i("p", { className: "font-medium", children: e === "de" ? "Hintergrund wird entfernt..." : "Removing background..." })
650
+ ] }) : /* @__PURE__ */ g("div", { className: "flex flex-col items-center gap-2", children: [
651
+ /* @__PURE__ */ i(
566
652
  "svg",
567
653
  {
568
654
  xmlns: "http://www.w3.org/2000/svg",
@@ -570,7 +656,7 @@ function Re() {
570
656
  fill: "none",
571
657
  viewBox: "0 0 24 24",
572
658
  stroke: "currentColor",
573
- children: /* @__PURE__ */ o(
659
+ children: /* @__PURE__ */ i(
574
660
  "path",
575
661
  {
576
662
  strokeLinecap: "round",
@@ -581,26 +667,26 @@ function Re() {
581
667
  )
582
668
  }
583
669
  ),
584
- /* @__PURE__ */ o("p", { className: "font-medium", children: p.form.portrait.upload }),
585
- /* @__PURE__ */ o("p", { className: "text-sm text-base-content/60", children: p.form.portrait.dragDrop })
670
+ /* @__PURE__ */ i("p", { className: "font-medium", children: u.form.portrait.upload }),
671
+ /* @__PURE__ */ i("p", { className: "text-sm text-base-content/60", children: u.form.portrait.dragDrop })
586
672
  ] })
587
673
  ]
588
674
  }
589
675
  ),
590
- /* @__PURE__ */ o(
591
- ve,
676
+ /* @__PURE__ */ i(
677
+ Ce,
592
678
  {
593
- isOpen: N,
594
- onClose: () => I(!1),
595
- onSubmit: U
679
+ isOpen: E,
680
+ onClose: () => C(!1),
681
+ onSubmit: de
596
682
  }
597
683
  )
598
684
  ] });
599
685
  }
600
- function He() {
686
+ function qe() {
601
687
  return null;
602
688
  }
603
- const x = typeof import.meta < "u" && "/" || "/", we = {
689
+ const x = typeof import.meta < "u" && "/" || "/", Ae = {
604
690
  en: {
605
691
  1: {
606
692
  front: `${x}templates/front_ldpi_en.png`,
@@ -641,7 +727,7 @@ const x = typeof import.meta < "u" && "/" || "/", we = {
641
727
  height: 3200
642
728
  }
643
729
  }
644
- }, T = {
730
+ }, A = {
645
731
  front: {
646
732
  portrait: {
647
733
  x: 768,
@@ -687,7 +773,7 @@ const x = typeof import.meta < "u" && "/" || "/", we = {
687
773
  align: "center"
688
774
  }
689
775
  }
690
- }, L = {
776
+ }, T = {
691
777
  front: {
692
778
  portrait: {
693
779
  x: 3074,
@@ -734,140 +820,140 @@ const x = typeof import.meta < "u" && "/" || "/", we = {
734
820
  }
735
821
  }
736
822
  };
737
- function J(e) {
738
- return e === "de" ? L : T;
823
+ function ae(e) {
824
+ return e === "de" ? T : A;
739
825
  }
740
- function Q(e, t) {
741
- return we[e][t];
826
+ function re(e, t) {
827
+ return Ae[e][t];
742
828
  }
743
- const W = /* @__PURE__ */ new Map();
829
+ const O = /* @__PURE__ */ new Map();
744
830
  async function j(e) {
745
- return W.has(e) ? W.get(e) : new Promise((t, n) => {
746
- const a = new Image();
747
- a.crossOrigin = "anonymous", a.onload = () => {
748
- W.set(e, a), t(a);
749
- }, a.onerror = n, a.src = e;
831
+ return O.has(e) ? O.get(e) : new Promise((t, a) => {
832
+ const n = new Image();
833
+ n.crossOrigin = "anonymous", n.onload = () => {
834
+ O.set(e, n), t(n);
835
+ }, n.onerror = a, n.src = e;
750
836
  });
751
837
  }
752
- function ee(e, t, n, a) {
753
- e.drawImage(t, 0, 0, n, a);
838
+ function oe(e, t, a, n) {
839
+ e.drawImage(t, 0, 0, a, n);
754
840
  }
755
- function xe(e, t, n, a, r, l, s = 1) {
756
- e.save(), e.beginPath(), e.ellipse(n, a, r, l, 0, 0, Math.PI * 2), e.closePath(), e.clip();
757
- const d = t.width / t.height, i = r / l, c = r * 2, f = l * 2;
758
- let p, b;
759
- d > i ? (b = f, p = f * d) : (p = c, b = c / d), p *= s, b *= s;
760
- const v = n - p / 2, u = a - b / 2;
761
- e.drawImage(t, v, u, p, b), e.restore();
841
+ function Te(e, t, a, n, r, o, d = 1) {
842
+ e.save(), e.beginPath(), e.ellipse(a, n, r, o, 0, 0, Math.PI * 2), e.closePath(), e.clip();
843
+ const l = t.width / t.height, s = r / o, c = r * 2, m = o * 2;
844
+ let f, b;
845
+ l > s ? (b = m, f = m * l) : (f = c, b = c / l), f *= d, b *= d;
846
+ const u = a - f / 2, h = n - b / 2;
847
+ e.drawImage(t, u, h, f, b), e.restore();
762
848
  }
763
- function te(e, t, n, a = "#2a3a2a") {
764
- e.save(), e.font = `${n.fontSize}px "Times New Roman", serif`, e.textAlign = n.align || "center", e.textBaseline = "middle", e.fillStyle = a, n.maxWidth ? e.fillText(t, n.x, n.y, n.maxWidth) : e.fillText(t, n.x, n.y), e.restore();
849
+ function ie(e, t, a, n = "#2a3a2a") {
850
+ e.save(), e.font = `${a.fontSize}px "Times New Roman", serif`, e.textAlign = a.align || "center", e.textBaseline = "middle", e.fillStyle = n, a.maxWidth ? e.fillText(t, a.x, a.y, a.maxWidth) : e.fillText(t, a.x, a.y), e.restore();
765
851
  }
766
- function ke(e, t, n, a = "#2a3a2a") {
767
- e.save(), e.font = `${n.fontSize}px "Times New Roman", serif`, e.textAlign = n.align || "center", e.textBaseline = "top", e.fillStyle = a;
768
- const r = n.maxWidth || 400, l = n.lineHeight || n.fontSize * 1.4, s = t.split(" "), d = [];
769
- let i = "";
770
- for (const p of s) {
771
- const b = i ? `${i} ${p}` : p;
772
- e.measureText(b).width > r && i ? (d.push(i), i = p) : i = b;
852
+ function Le(e, t, a, n = "#2a3a2a") {
853
+ e.save(), e.font = `${a.fontSize}px "Times New Roman", serif`, e.textAlign = a.align || "center", e.textBaseline = "top", e.fillStyle = n;
854
+ const r = a.maxWidth || 400, o = a.lineHeight || a.fontSize * 1.4, d = t.split(" "), l = [];
855
+ let s = "";
856
+ for (const f of d) {
857
+ const b = s ? `${s} ${f}` : f;
858
+ e.measureText(b).width > r && s ? (l.push(s), s = f) : s = b;
773
859
  }
774
- i && d.push(i);
775
- const c = d.length * l;
776
- let f = n.y - c / 2;
777
- for (const p of d)
778
- e.fillText(p, n.x, f), f += l;
860
+ s && l.push(s);
861
+ const c = l.length * o;
862
+ let m = a.y - c / 2;
863
+ for (const f of l)
864
+ e.fillText(f, a.x, m), m += o;
779
865
  e.restore();
780
866
  }
781
- function Ie(e, t, n, a, r, l = "#2a3a2a") {
782
- e.save(), e.font = `${r.fontSize}px "Times New Roman", serif`, e.textAlign = r.align || "center", e.textBaseline = "middle", e.fillStyle = l;
783
- const s = r.lineHeight || r.fontSize * 1.8, d = [t, n, a].filter(Boolean), i = (d.length - 1) * s;
784
- let c = r.y - i / 2;
785
- for (const f of d)
786
- f && (e.fillText(f, r.x, c), c += s);
867
+ function _e(e, t, a, n, r, o = "#2a3a2a") {
868
+ e.save(), e.font = `${r.fontSize}px "Times New Roman", serif`, e.textAlign = r.align || "center", e.textBaseline = "middle", e.fillStyle = o;
869
+ const d = r.lineHeight || r.fontSize * 1.8, l = [t, a, n].filter(Boolean), s = (l.length - 1) * d;
870
+ let c = r.y - s / 2;
871
+ for (const m of l)
872
+ m && (e.fillText(m, r.x, c), c += d);
787
873
  e.restore();
788
874
  }
789
- async function ne(e, t, n, a, r, l, s, d = 1) {
790
- const i = e.getContext("2d");
791
- if (!i) return;
792
- e.width = l, e.height = s, i.clearRect(0, 0, l, s);
875
+ async function se(e, t, a, n, r, o, d, l = 1) {
876
+ const s = e.getContext("2d");
877
+ if (!s) return;
878
+ e.width = o, e.height = d, s.clearRect(0, 0, o, d);
793
879
  const c = await j(t);
794
- if (ee(i, c, l, s), n)
880
+ if (oe(s, c, o, d), a)
795
881
  try {
796
- const f = await j(n);
797
- xe(
798
- i,
799
- f,
882
+ const m = await j(a);
883
+ Te(
884
+ s,
885
+ m,
800
886
  r.portrait.x,
801
887
  r.portrait.y,
802
888
  r.portrait.radiusX,
803
889
  r.portrait.radiusY,
804
- d
890
+ l
805
891
  );
806
- } catch (f) {
807
- console.error("Failed to load portrait:", f);
892
+ } catch (m) {
893
+ console.error("Failed to load portrait:", m);
808
894
  }
809
- a && te(i, a, r.namePlate);
895
+ n && ie(s, n, r.namePlate);
810
896
  }
811
- async function ae(e, t, n, a, r, l, s, d, i) {
897
+ async function le(e, t, a, n, r, o, d, l, s) {
812
898
  const c = e.getContext("2d");
813
899
  if (!c) return;
814
- e.width = d, e.height = i, c.clearRect(0, 0, d, i);
815
- const f = await j(t);
816
- ee(c, f, d, i), s.contactInfo && (n || a || r) && Ie(c, n, a, r, s.contactInfo), s.description && l && ke(c, l, s.description), n && te(c, n, s.namePlate);
900
+ e.width = l, e.height = s, c.clearRect(0, 0, l, s);
901
+ const m = await j(t);
902
+ oe(c, m, l, s), d.contactInfo && (a || n || r) && _e(c, a, n, r, d.contactInfo), d.description && o && Le(c, o, d.description), a && ie(c, a, d.namePlate);
817
903
  }
818
- function Me() {
819
- const e = g((y) => y.voucherConfig.language), t = g((y) => y.voucherConfig.hours), n = g((y) => y.voucherConfig.description), a = g((y) => y.personalInfo), r = g((y) => y.portrait), l = g((y) => y.currentSide), s = g((y) => y.flipSide), d = _(e), i = A(null), c = A(null), f = A(null), [p, b] = C(!1), v = Q(e, t), u = J(e), N = r.useEnhanced && r.enhanced ? r.enhanced : r.original, I = G(e, t, n);
820
- O(() => {
821
- i.current && ne(
822
- i.current,
823
- v.front,
824
- N,
825
- a.name,
904
+ function Ve() {
905
+ const e = w((y) => y.voucherConfig.language), t = w((y) => y.voucherConfig.hours), a = w((y) => y.voucherConfig.description), n = w((y) => y.personalInfo), r = w((y) => y.portrait), o = w((y) => y.currentSide), d = w((y) => y.flipSide), l = _(e), s = L(null), c = L(null), m = L(null), [f, b] = N(!1), u = re(e, t), h = ae(e), k = r.useEnhanced && r.enhanced ? r.enhanced : r.original, I = ee(e, t, a);
906
+ V(() => {
907
+ s.current && se(
908
+ s.current,
826
909
  u.front,
827
- v.width,
828
- v.height,
910
+ k,
911
+ n.name,
912
+ h.front,
913
+ u.width,
914
+ u.height,
829
915
  r.zoom
830
916
  );
831
- }, [v, N, a.name, u, r.zoom]), O(() => {
832
- c.current && ae(
917
+ }, [u, k, n.name, h, r.zoom]), V(() => {
918
+ c.current && le(
833
919
  c.current,
834
- v.back,
835
- a.name,
836
- a.email,
837
- a.phone,
838
- I,
839
920
  u.back,
840
- v.width,
841
- v.height
921
+ n.name,
922
+ n.email,
923
+ n.phone,
924
+ I,
925
+ h.back,
926
+ u.width,
927
+ u.height
842
928
  );
843
- }, [v, a, I, u]);
844
- const k = () => {
929
+ }, [u, n, I, h]);
930
+ const E = () => {
845
931
  b(!0), setTimeout(() => {
846
- s(), b(!1);
932
+ d(), b(!1);
847
933
  }, 150);
848
- }, S = v.width / v.height;
849
- return /* @__PURE__ */ m("div", { className: "space-y-4", children: [
850
- /* @__PURE__ */ m("div", { className: "flex justify-between items-center", children: [
851
- /* @__PURE__ */ m("div", { className: "tabs tabs-boxed bg-base-200", children: [
852
- /* @__PURE__ */ o(
934
+ }, C = u.width / u.height;
935
+ return /* @__PURE__ */ g("div", { className: "space-y-4", children: [
936
+ /* @__PURE__ */ g("div", { className: "flex justify-between items-center", children: [
937
+ /* @__PURE__ */ g("div", { className: "tabs tabs-boxed bg-base-200", children: [
938
+ /* @__PURE__ */ i(
853
939
  "button",
854
940
  {
855
- className: `tab ${l === "front" ? "tab-active bg-primary text-primary-content font-semibold" : ""}`,
856
- onClick: () => l !== "front" && k(),
857
- children: d.preview.front
941
+ className: `tab ${o === "front" ? "tab-active bg-primary text-primary-content font-semibold" : ""}`,
942
+ onClick: () => o !== "front" && E(),
943
+ children: l.preview.front
858
944
  }
859
945
  ),
860
- /* @__PURE__ */ o(
946
+ /* @__PURE__ */ i(
861
947
  "button",
862
948
  {
863
- className: `tab ${l === "back" ? "tab-active bg-primary text-primary-content font-semibold" : ""}`,
864
- onClick: () => l !== "back" && k(),
865
- children: d.preview.back
949
+ className: `tab ${o === "back" ? "tab-active bg-primary text-primary-content font-semibold" : ""}`,
950
+ onClick: () => o !== "back" && E(),
951
+ children: l.preview.back
866
952
  }
867
953
  )
868
954
  ] }),
869
- /* @__PURE__ */ m("button", { className: "btn btn-ghost btn-sm", onClick: k, children: [
870
- /* @__PURE__ */ o(
955
+ /* @__PURE__ */ g("button", { className: "btn btn-ghost btn-sm", onClick: E, children: [
956
+ /* @__PURE__ */ i(
871
957
  "svg",
872
958
  {
873
959
  xmlns: "http://www.w3.org/2000/svg",
@@ -875,7 +961,7 @@ function Me() {
875
961
  fill: "none",
876
962
  viewBox: "0 0 24 24",
877
963
  stroke: "currentColor",
878
- children: /* @__PURE__ */ o(
964
+ children: /* @__PURE__ */ i(
879
965
  "path",
880
966
  {
881
967
  strokeLinecap: "round",
@@ -886,28 +972,28 @@ function Me() {
886
972
  )
887
973
  }
888
974
  ),
889
- d.preview.flip
975
+ l.preview.flip
890
976
  ] })
891
977
  ] }),
892
- /* @__PURE__ */ m(
978
+ /* @__PURE__ */ g(
893
979
  "div",
894
980
  {
895
- ref: f,
981
+ ref: m,
896
982
  className: "relative w-full overflow-hidden shadow-lg",
897
- style: { aspectRatio: S },
983
+ style: { aspectRatio: C },
898
984
  children: [
899
- /* @__PURE__ */ o(
985
+ /* @__PURE__ */ i(
900
986
  "canvas",
901
987
  {
902
- ref: i,
903
- className: `absolute inset-0 w-full h-full transition-all duration-300 ${l === "front" ? p ? "opacity-0 scale-95" : "opacity-100 scale-100" : "opacity-0 scale-95 pointer-events-none"}`
988
+ ref: s,
989
+ className: `absolute inset-0 w-full h-full transition-all duration-300 ${o === "front" ? f ? "opacity-0 scale-95" : "opacity-100 scale-100" : "opacity-0 scale-95 pointer-events-none"}`
904
990
  }
905
991
  ),
906
- /* @__PURE__ */ o(
992
+ /* @__PURE__ */ i(
907
993
  "canvas",
908
994
  {
909
995
  ref: c,
910
- className: `absolute inset-0 w-full h-full transition-all duration-300 ${l === "back" ? p ? "opacity-0 scale-95" : "opacity-100 scale-100" : "opacity-0 scale-95 pointer-events-none"}`
996
+ className: `absolute inset-0 w-full h-full transition-all duration-300 ${o === "back" ? f ? "opacity-0 scale-95" : "opacity-100 scale-100" : "opacity-0 scale-95 pointer-events-none"}`
911
997
  }
912
998
  )
913
999
  ]
@@ -915,86 +1001,86 @@ function Me() {
915
1001
  )
916
1002
  ] });
917
1003
  }
918
- function Ue() {
919
- const e = A(null), t = A(null);
1004
+ function Ge() {
1005
+ const e = L(null), t = L(null);
920
1006
  return { frontCanvasRef: e, backCanvasRef: t };
921
1007
  }
922
- async function Pe(e) {
1008
+ async function De(e) {
923
1009
  const {
924
1010
  frontTemplateSrc: t,
925
- backTemplateSrc: n,
926
- templateWidth: a,
1011
+ backTemplateSrc: a,
1012
+ templateWidth: n,
927
1013
  templateHeight: r,
928
- layout: l,
929
- portrait: s,
930
- portraitZoom: d = 1,
931
- name: i,
1014
+ layout: o,
1015
+ portrait: d,
1016
+ portraitZoom: l = 1,
1017
+ name: s,
932
1018
  email: c,
933
- phone: f,
934
- description: p
935
- } = e, b = document.createElement("canvas"), v = document.createElement("canvas");
1019
+ phone: m,
1020
+ description: f
1021
+ } = e, b = document.createElement("canvas"), u = document.createElement("canvas");
936
1022
  await Promise.all([
937
- ne(b, t, s, i, l.front, a, r, d),
938
- ae(v, n, i, c, f, p, l.back, a, r)
1023
+ se(b, t, d, s, o.front, n, r, l),
1024
+ le(u, a, s, c, m, f, o.back, n, r)
939
1025
  ]);
940
- const u = new ce({
1026
+ const h = new ge({
941
1027
  orientation: "landscape",
942
1028
  unit: "mm",
943
1029
  format: "a4"
944
- }), N = 297, I = 210, k = 10, S = a / r;
945
- let y = N - k * 2, P = y / S;
946
- P > I - k * 2 && (P = I - k * 2, y = P * S);
947
- const D = (N - y) / 2, $ = (I - P) / 2, M = b.toDataURL("image/jpeg", 0.95);
948
- u.addImage(M, "JPEG", D, $, y, P), u.addPage();
949
- const U = v.toDataURL("image/jpeg", 0.95);
950
- return u.addImage(U, "JPEG", D, $, y, P), u.output("blob");
1030
+ }), k = 297, I = 210, E = 10, C = n / r;
1031
+ let y = k - E * 2, P = y / C;
1032
+ P > I - E * 2 && (P = I - E * 2, y = P * C);
1033
+ const D = (k - y) / 2, B = (I - P) / 2, M = b.toDataURL("image/jpeg", 0.95);
1034
+ h.addImage(M, "JPEG", D, B, y, P), h.addPage();
1035
+ const U = u.toDataURL("image/jpeg", 0.95);
1036
+ return h.addImage(U, "JPEG", D, B, y, P), h.output("blob");
951
1037
  }
952
- function Ne(e, t) {
953
- const n = URL.createObjectURL(e), a = document.createElement("a");
954
- a.href = n, a.download = t, document.body.appendChild(a), a.click(), document.body.removeChild(a), URL.revokeObjectURL(n);
1038
+ function Be(e, t) {
1039
+ const a = URL.createObjectURL(e), n = document.createElement("a");
1040
+ n.href = a, n.download = t, document.body.appendChild(n), n.click(), document.body.removeChild(n), URL.revokeObjectURL(a);
955
1041
  }
956
- async function Ee(e) {
957
- const t = await Pe(e);
958
- Ne(t, e.filename);
1042
+ async function Re(e) {
1043
+ const t = await De(e);
1044
+ Be(t, e.filename);
959
1045
  }
960
- function Fe() {
961
- const e = g((u) => u.voucherConfig.language), t = g((u) => u.voucherConfig.hours), n = g((u) => u.voucherConfig.description), a = g((u) => u.personalInfo), r = g((u) => u.portrait), l = g((u) => u.isExporting), s = g((u) => u.setIsExporting), d = _(e), i = Q(e, t), c = J(e), f = r.useEnhanced && r.enhanced ? r.enhanced : r.original, p = G(e, t, n), b = a.name.trim().length > 0 && a.email.trim().length > 0 && a.phone.trim().length > 0 && r.original !== null;
962
- return /* @__PURE__ */ o(
1046
+ function Ze() {
1047
+ const e = w((h) => h.voucherConfig.language), t = w((h) => h.voucherConfig.hours), a = w((h) => h.voucherConfig.description), n = w((h) => h.personalInfo), r = w((h) => h.portrait), o = w((h) => h.isExporting), d = w((h) => h.setIsExporting), l = _(e), s = re(e, t), c = ae(e), m = r.useEnhanced && r.enhanced ? r.enhanced : r.original, f = ee(e, t, a), b = n.name.trim().length > 0 && n.email.trim().length > 0 && n.phone.trim().length > 0 && r.original !== null;
1048
+ return /* @__PURE__ */ i(
963
1049
  "button",
964
1050
  {
965
- className: `btn btn-primary flex-1 ${l ? "loading" : ""}`,
1051
+ className: `btn btn-primary flex-1 ${o ? "loading" : ""}`,
966
1052
  onClick: async () => {
967
- if (!(!b || l)) {
968
- s(!0);
1053
+ if (!(!b || o)) {
1054
+ d(!0);
969
1055
  try {
970
- const u = `zeitgutschein-${t}h-${a.name.replace(/\s+/g, "-").toLowerCase()}.pdf`;
971
- await Ee({
972
- frontTemplateSrc: i.front,
973
- backTemplateSrc: i.back,
974
- templateWidth: i.width,
975
- templateHeight: i.height,
1056
+ const h = `zeitgutschein-${t}h-${n.name.replace(/\s+/g, "-").toLowerCase()}.pdf`;
1057
+ await Re({
1058
+ frontTemplateSrc: s.front,
1059
+ backTemplateSrc: s.back,
1060
+ templateWidth: s.width,
1061
+ templateHeight: s.height,
976
1062
  layout: c,
977
- portrait: f,
1063
+ portrait: m,
978
1064
  portraitZoom: r.zoom,
979
- name: a.name,
980
- email: a.email,
981
- phone: a.phone,
982
- description: p,
983
- filename: u
1065
+ name: n.name,
1066
+ email: n.email,
1067
+ phone: n.phone,
1068
+ description: f,
1069
+ filename: h
984
1070
  });
985
- } catch (u) {
986
- console.error("PDF export failed:", u);
1071
+ } catch (h) {
1072
+ console.error("PDF export failed:", h);
987
1073
  } finally {
988
- s(!1);
1074
+ d(!1);
989
1075
  }
990
1076
  }
991
1077
  },
992
- disabled: !b || l,
993
- children: l ? /* @__PURE__ */ m(z, { children: [
994
- /* @__PURE__ */ o("span", { className: "loading loading-spinner loading-sm" }),
995
- d.export.exporting
996
- ] }) : /* @__PURE__ */ m(z, { children: [
997
- /* @__PURE__ */ o(
1078
+ disabled: !b || o,
1079
+ children: o ? /* @__PURE__ */ g($, { children: [
1080
+ /* @__PURE__ */ i("span", { className: "loading loading-spinner loading-sm" }),
1081
+ l.export.exporting
1082
+ ] }) : /* @__PURE__ */ g($, { children: [
1083
+ /* @__PURE__ */ i(
998
1084
  "svg",
999
1085
  {
1000
1086
  xmlns: "http://www.w3.org/2000/svg",
@@ -1002,7 +1088,7 @@ function Fe() {
1002
1088
  fill: "none",
1003
1089
  viewBox: "0 0 24 24",
1004
1090
  stroke: "currentColor",
1005
- children: /* @__PURE__ */ o(
1091
+ children: /* @__PURE__ */ i(
1006
1092
  "path",
1007
1093
  {
1008
1094
  strokeLinecap: "round",
@@ -1013,50 +1099,50 @@ function Fe() {
1013
1099
  )
1014
1100
  }
1015
1101
  ),
1016
- d.export.button
1102
+ l.export.button
1017
1103
  ] })
1018
1104
  }
1019
1105
  );
1020
1106
  }
1021
- function Ce() {
1022
- const e = g((a) => a.voucherConfig.language), t = g((a) => a.setLanguage), n = (a) => {
1023
- t(a);
1107
+ function $e() {
1108
+ const e = w((n) => n.voucherConfig.language), t = w((n) => n.setLanguage), a = (n) => {
1109
+ t(n);
1024
1110
  };
1025
- return /* @__PURE__ */ m("div", { className: "join", children: [
1026
- /* @__PURE__ */ o(
1111
+ return /* @__PURE__ */ g("div", { className: "join", children: [
1112
+ /* @__PURE__ */ i(
1027
1113
  "button",
1028
1114
  {
1029
1115
  className: `join-item btn btn-sm ${e === "de" ? "btn-active btn-primary" : "btn-ghost"}`,
1030
- onClick: () => n("de"),
1116
+ onClick: () => a("de"),
1031
1117
  children: "DE"
1032
1118
  }
1033
1119
  ),
1034
- /* @__PURE__ */ o(
1120
+ /* @__PURE__ */ i(
1035
1121
  "button",
1036
1122
  {
1037
1123
  className: `join-item btn btn-sm ${e === "en" ? "btn-active btn-primary" : "btn-ghost"}`,
1038
- onClick: () => n("en"),
1124
+ onClick: () => a("en"),
1039
1125
  children: "EN"
1040
1126
  }
1041
1127
  )
1042
1128
  ] });
1043
1129
  }
1044
- function We() {
1045
- const e = g((n) => n.voucherConfig.language), t = _(e);
1046
- return /* @__PURE__ */ m("div", { className: "navbar bg-currency-green text-currency-cream shadow-lg", children: [
1047
- /* @__PURE__ */ o("div", { className: "navbar-start", children: /* @__PURE__ */ o("a", { className: "btn btn-ghost text-xl font-currency font-bold", children: t.header.title }) }),
1048
- /* @__PURE__ */ o("div", { className: "navbar-center hidden sm:flex", children: /* @__PURE__ */ o("span", { className: "text-sm opacity-80", children: t.header.subtitle }) }),
1049
- /* @__PURE__ */ o("div", { className: "navbar-end", children: /* @__PURE__ */ o(Ce, {}) })
1130
+ function Xe() {
1131
+ const e = w((a) => a.voucherConfig.language), t = _(e);
1132
+ return /* @__PURE__ */ g("div", { className: "navbar bg-currency-green text-currency-cream shadow-lg", children: [
1133
+ /* @__PURE__ */ i("div", { className: "navbar-start", children: /* @__PURE__ */ i("a", { className: "btn btn-ghost text-xl font-currency font-bold", children: t.header.title }) }),
1134
+ /* @__PURE__ */ i("div", { className: "navbar-center hidden sm:flex", children: /* @__PURE__ */ i("span", { className: "text-sm opacity-80", children: t.header.subtitle }) }),
1135
+ /* @__PURE__ */ i("div", { className: "navbar-end", children: /* @__PURE__ */ i($e, {}) })
1050
1136
  ] });
1051
1137
  }
1052
- const R = "/", Se = {
1138
+ const z = "/", ze = {
1053
1139
  id: "time-voucher-classic-de",
1054
1140
  name: "Zeitgutschein Classic",
1055
1141
  type: "time-voucher",
1056
1142
  category: "classic",
1057
1143
  images: {
1058
- front: `${R}templates/front_hdpi_de.jpg`,
1059
- back: `${R}templates/back_hdpi_de.jpg`,
1144
+ front: `${z}templates/front_hdpi_de.jpg`,
1145
+ back: `${z}templates/back_hdpi_de.jpg`,
1060
1146
  width: 6144,
1061
1147
  height: 4096
1062
1148
  },
@@ -1103,24 +1189,24 @@ const R = "/", Se = {
1103
1189
  ],
1104
1190
  layout: {
1105
1191
  front: {
1106
- portrait: L.front.portrait,
1107
- name: L.front.namePlate
1192
+ portrait: T.front.portrait,
1193
+ name: T.front.namePlate
1108
1194
  },
1109
1195
  back: {
1110
- name: L.back.namePlate,
1111
- contactInfo: L.back.contactInfo,
1112
- description: L.back.description
1196
+ name: T.back.namePlate,
1197
+ contactInfo: T.back.contactInfo,
1198
+ description: T.back.description
1113
1199
  }
1114
1200
  },
1115
1201
  languages: ["de"]
1116
- }, Te = {
1202
+ }, He = {
1117
1203
  id: "time-voucher-classic-en",
1118
1204
  name: "Time Voucher Classic",
1119
1205
  type: "time-voucher",
1120
1206
  category: "classic",
1121
1207
  images: {
1122
- front: `${R}templates/front_ldpi_en.png`,
1123
- back: `${R}templates/back_ldpi_en.png`,
1208
+ front: `${z}templates/front_ldpi_en.png`,
1209
+ back: `${z}templates/back_ldpi_en.png`,
1124
1210
  width: 1536,
1125
1211
  height: 1024
1126
1212
  },
@@ -1167,85 +1253,86 @@ const R = "/", Se = {
1167
1253
  ],
1168
1254
  layout: {
1169
1255
  front: {
1170
- portrait: T.front.portrait,
1171
- name: T.front.namePlate
1256
+ portrait: A.front.portrait,
1257
+ name: A.front.namePlate
1172
1258
  },
1173
1259
  back: {
1174
- name: T.back.namePlate,
1175
- contactInfo: T.back.contactInfo,
1176
- description: T.back.description
1260
+ name: A.back.namePlate,
1261
+ contactInfo: A.back.contactInfo,
1262
+ description: A.back.description
1177
1263
  }
1178
1264
  },
1179
1265
  languages: ["en"]
1180
- }, Z = [
1181
- Se,
1182
- Te
1183
- ], Le = {
1266
+ }, Q = [
1267
+ ze,
1268
+ He
1269
+ ], Me = {
1184
1270
  async listTemplates(e) {
1185
- let t = [...Z];
1186
- return e != null && e.type && (t = t.filter((n) => n.type === e.type)), e != null && e.category && (t = t.filter((n) => n.category === e.category)), e != null && e.language && (t = t.filter((n) => n.languages.includes(e.language))), t;
1271
+ let t = [...Q];
1272
+ return e != null && e.type && (t = t.filter((a) => a.type === e.type)), e != null && e.category && (t = t.filter((a) => a.category === e.category)), e != null && e.language && (t = t.filter((a) => a.languages.includes(e.language))), t;
1187
1273
  },
1188
1274
  async getTemplate(e) {
1189
- const t = Z.find((n) => n.id === e);
1275
+ const t = Q.find((a) => a.id === e);
1190
1276
  if (!t)
1191
1277
  throw new Error(`Template not found: ${e}`);
1192
1278
  return t;
1193
1279
  }
1194
1280
  };
1195
- function je(e) {
1281
+ function Je(e) {
1196
1282
  return e === "de" ? "time-voucher-classic-de" : "time-voucher-classic-en";
1197
1283
  }
1198
- let H = Le;
1199
- function Ke(e) {
1284
+ let H = Me;
1285
+ function Qe(e) {
1200
1286
  H = e;
1201
1287
  }
1202
- function Oe() {
1288
+ function et() {
1203
1289
  return H;
1204
1290
  }
1205
- async function Ye(e) {
1291
+ async function tt(e) {
1206
1292
  return H.listTemplates(e);
1207
1293
  }
1208
- async function qe(e) {
1294
+ async function nt(e) {
1209
1295
  return H.getTemplate(e);
1210
1296
  }
1211
1297
  export {
1212
- ve as ApiKeyModal,
1213
- Me as BillPreview,
1214
- Fe as ExportButton,
1215
- We as Header,
1216
- L as LAYOUT_HDPI,
1217
- T as LAYOUT_LDPI,
1218
- Ce as LanguageToggle,
1219
- ze as PersonalInfoForm,
1220
- Re as PortraitUpload,
1221
- we as TEMPLATES,
1222
- He as VoucherConfig,
1223
- Ne as downloadBlob,
1224
- Ie as drawContactInfo,
1225
- ke as drawMultilineText,
1226
- xe as drawOvalPortrait,
1227
- ee as drawTemplate,
1228
- te as drawText,
1229
- be as enhancePortrait,
1230
- V as enhancePortraitFallback,
1231
- Ee as exportBillAsPDF,
1232
- G as formatDescription,
1233
- Pe as generateBillPDF,
1234
- X as getApiKey,
1235
- je as getDefaultTemplateId,
1236
- J as getLayout,
1237
- Q as getTemplate,
1238
- qe as getTemplateById,
1239
- Oe as getTemplateProvider,
1240
- q as hasApiKey,
1241
- Ye as listTemplates,
1298
+ Ce as ApiKeyModal,
1299
+ Ve as BillPreview,
1300
+ Ze as ExportButton,
1301
+ Xe as Header,
1302
+ T as LAYOUT_HDPI,
1303
+ A as LAYOUT_LDPI,
1304
+ $e as LanguageToggle,
1305
+ je as PersonalInfoForm,
1306
+ Ye as PortraitUpload,
1307
+ Ae as TEMPLATES,
1308
+ qe as VoucherConfig,
1309
+ Be as downloadBlob,
1310
+ _e as drawContactInfo,
1311
+ Le as drawMultilineText,
1312
+ Te as drawOvalPortrait,
1313
+ oe as drawTemplate,
1314
+ ie as drawText,
1315
+ Pe as enhancePortrait,
1316
+ J as enhancePortraitFallback,
1317
+ Re as exportBillAsPDF,
1318
+ ee as formatDescription,
1319
+ De as generateBillPDF,
1320
+ Y as getApiKey,
1321
+ Je as getDefaultTemplateId,
1322
+ ae as getLayout,
1323
+ re as getTemplate,
1324
+ nt as getTemplateById,
1325
+ et as getTemplateProvider,
1326
+ X as hasApiKey,
1327
+ tt as listTemplates,
1242
1328
  j as loadImage,
1243
- ae as renderBackSide,
1244
- ne as renderFrontSide,
1245
- fe as setApiKey,
1246
- Ke as setTemplateProvider,
1247
- Le as staticTemplateProvider,
1329
+ Ne as removeBackground,
1330
+ le as renderBackSide,
1331
+ se as renderFrontSide,
1332
+ Ee as setApiKey,
1333
+ Qe as setTemplateProvider,
1334
+ Me as staticTemplateProvider,
1248
1335
  _ as t,
1249
- Ue as useBillCanvasRefs,
1250
- g as useBillStore
1336
+ Ge as useBillCanvasRefs,
1337
+ w as useBillStore
1251
1338
  };