@antontranelis/money-printer 1.0.1 → 1.0.2

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.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("react/jsx-runtime"),ge=require("zustand"),fe=require("zustand/middleware"),b=require("react"),be=require("jspdf");var T=typeof document<"u"?document.currentScript:null;const J={personalInfo:{name:"",email:"",phone:""},voucherConfig:{hours:1,description:"",language:"de"},portrait:{original:null,enhanced:null,useEnhanced:!1,zoom:1},currentSide:"front",isEnhancing:!1,isExporting:!1},m=ge.create()(fe.persist(e=>({...J,setPersonalInfo:t=>e(a=>({personalInfo:{...a.personalInfo,...t}})),setVoucherConfig:t=>e(a=>({voucherConfig:{...a.voucherConfig,...t}})),setPortrait:(t,a=null)=>e({portrait:{original:t,enhanced:a,useEnhanced:!1,zoom:1}}),setEnhancedPortrait:t=>e(a=>({portrait:{...a.portrait,enhanced:t,useEnhanced:t!==null}})),toggleUseEnhanced:()=>e(t=>({portrait:{...t.portrait,useEnhanced:t.portrait.enhanced?!t.portrait.useEnhanced:!1}})),setPortraitZoom:t=>e(a=>({portrait:{...a.portrait,zoom:t}})),setCurrentSide:t=>e({currentSide:t}),flipSide:()=>e(t=>({currentSide:t.currentSide==="front"?"back":"front"})),setIsEnhancing:t=>e({isEnhancing:t}),setIsExporting:t=>e({isExporting:t}),setLanguage:t=>e(a=>({voucherConfig:{...a.voucherConfig,language:t}})),setHours:t=>e(a=>({voucherConfig:{...a.voucherConfig,hours:t}})),reset:()=>e(J)}),{name:"money-generator-storage",partialize:e=>({personalInfo:e.personalInfo,voucherConfig:e.voucherConfig})})),xe={header:{title:"Money Generator",subtitle:"Erstelle deinen persönlichen Zeitgutschein"},form:{personalInfo:{title:"Persönliche Daten",name:"Name",namePlaceholder:"Dein Name",email:"E-Mail",emailPlaceholder:"deine@email.de",phone:"Telefon",phonePlaceholder:"+49 123 456789"},portrait:{title:"Portrait",upload:"Bild hochladen",dragDrop:"oder hierher ziehen",enhance:"Mit AI verbessern",enhancing:"Wird verbessert...",useOriginal:"Original verwenden",useEnhanced:"Verbessertes verwenden",zoom:"Zoom"},voucher:{title:"Gutschein",hours:"Stunden",hourLabel:"Stunde",hoursLabel:"Stunden",description:"Beschreibung",descriptionPlaceholder:"Was kann mit diesem Gutschein eingelöst werden?"}},preview:{front:"Vorderseite",back:"Rückseite",flip:"Umdrehen"},export:{button:"Als PDF herunterladen",exporting:"PDF wird erstellt...",success:"Download gestartet!"},bill:{descriptionText:"Für diesen Schein erhältst du {hours} {hourLabel} meiner Zeit oder ein gleichwertiges Dankeschön"}},ye={header:{title:"Money Generator",subtitle:"Create your personal time voucher"},form:{personalInfo:{title:"Personal Information",name:"Name",namePlaceholder:"Your name",email:"Email",emailPlaceholder:"your@email.com",phone:"Phone",phonePlaceholder:"+1 234 567890"},portrait:{title:"Portrait",upload:"Upload image",dragDrop:"or drag and drop",enhance:"Enhance with AI",enhancing:"Enhancing...",useOriginal:"Use original",useEnhanced:"Use enhanced",zoom:"Zoom"},voucher:{title:"Voucher",hours:"Hours",hourLabel:"hour",hoursLabel:"hours",description:"Description",descriptionPlaceholder:"What can be redeemed with this voucher?"}},preview:{front:"Front",back:"Back",flip:"Flip"},export:{button:"Download as PDF",exporting:"Creating PDF...",success:"Download started!"},bill:{descriptionText:"This voucher entitles you to {hours} {hourLabel} of my time or an equivalent thank you"}},ve={de:xe,en:ye};function I(e){return ve[e]}function K(e,t,a){if(a&&a.trim())return a;const r=I(e),o=t===1?r.form.voucher.hourLabel:r.form.voucher.hoursLabel;return r.bill.descriptionText.replace("{hours}",t.toString()).replace("{hourLabel}",o)}function we(){const e=m(o=>o.voucherConfig.language),t=m(o=>o.personalInfo),a=m(o=>o.setPersonalInfo),r=I(e);return n.jsxs("div",{className:"space-y-4",children:[n.jsxs("div",{className:"form-control",children:[n.jsx("label",{className:"label",children:n.jsx("span",{className:"label-text font-medium",children:r.form.personalInfo.name})}),n.jsx("input",{type:"text",placeholder:r.form.personalInfo.namePlaceholder,className:"input input-bordered w-full",value:t.name,onChange:o=>a({name:o.target.value})})]}),n.jsxs("div",{className:"form-control",children:[n.jsx("label",{className:"label",children:n.jsx("span",{className:"label-text font-medium",children:r.form.personalInfo.email})}),n.jsx("input",{type:"email",placeholder:r.form.personalInfo.emailPlaceholder,className:"input input-bordered w-full",value:t.email,onChange:o=>a({email:o.target.value})})]}),n.jsxs("div",{className:"form-control",children:[n.jsx("label",{className:"label",children:n.jsx("span",{className:"label-text font-medium",children:r.form.personalInfo.phone})}),n.jsx("input",{type:"tel",placeholder:r.form.personalInfo.phonePlaceholder,className:"input input-bordered w-full",value:t.phone,onChange:o=>a({phone:o.target.value})})]})]})}const H={},je="https://api.stability.ai/v1/generation",ke={vintage:"portrait in the style of vintage currency engraving, fine line work, crosshatching, sepia tones, detailed stippling, classic bank note portrait style",engraved:"portrait as detailed intaglio engraving, currency bill style, fine parallel lines, high contrast, official government portrait",currency:"portrait rendered as US dollar bill engraving, official currency portrait style, green tint, fine line engraving technique"};function Pe(e){var i;const t=e.split(","),a=((i=t[0].match(/:(.*?);/))==null?void 0:i[1])||"image/png",r=atob(t[1]),o=r.length,l=new Uint8Array(o);for(let d=0;d<o;d++)l[d]=r.charCodeAt(d);return new Blob([l],{type:a})}function O(){var t;const e=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:T&&T.tagName.toUpperCase()==="SCRIPT"&&T.src||new URL("index.cjs",document.baseURI).href}<"u"&&(H==null?void 0:H.VITE_STABILITY_API_KEY)||typeof process<"u"&&((t=process.env)==null?void 0:t.NEXT_PUBLIC_STABILITY_API_KEY);return e&&e!=="your-api-key-here"?e:typeof localStorage<"u"?localStorage.getItem("stability_api_key"):null}function ee(e){localStorage.setItem("stability_api_key",e)}function z(){return O()!==null}async function te(e){const t=O();if(!t)throw new Error("No Stability AI API key configured");const{imageDataUrl:a,style:r,strength:o=.35}=e,l=Pe(a),i=new FormData;i.append("init_image",l,"portrait.png"),i.append("init_image_mode","IMAGE_STRENGTH"),i.append("image_strength",String(1-o)),i.append("text_prompts[0][text]",ke[r]),i.append("text_prompts[0][weight]","1"),i.append("cfg_scale","7"),i.append("samples","1"),i.append("steps","30");const s=await fetch(`${je}/stable-diffusion-xl-1024-v1-0/image-to-image`,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"},body:i});if(!s.ok){const g=await s.text();throw console.error("Stability AI error:",g),s.status===401?new Error("Invalid API key"):s.status===402?new Error("Insufficient credits"):s.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${s.status}`)}const c=await s.json();if(!c.artifacts||c.artifacts.length===0)throw new Error("No image generated");return`data:image/png;base64,${c.artifacts[0].base64}`}async function M(e){return new Promise((t,a)=>{const r=new Image;r.onload=()=>{const o=document.createElement("canvas"),l=o.getContext("2d");if(!l){a(new Error("Failed to get canvas context"));return}o.width=r.width,o.height=r.height,l.filter="sepia(0.3) contrast(1.1) saturate(0.9)",l.drawImage(r,0,0),t(o.toDataURL("image/png"))},r.onerror=()=>a(new Error("Failed to load image")),r.src=e})}function Ie(){const[e,t]=b.useState(!1),[a,r]=b.useState(null),[o,l]=b.useState(z()),i=b.useCallback(()=>r(null),[]),d=b.useCallback(c=>{ee(c),l(!0),r(null)},[]);return{enhance:b.useCallback(async(c,g="vintage")=>{t(!0),r(null);try{return z()?await te({imageDataUrl:c,style:g,strength:.35}):await M(c)}catch(h){const f=h instanceof Error?h.message:"Enhancement failed";if(r(f),f.includes("API")||f.includes("key"))try{return await M(c)}catch{throw h}throw h}finally{t(!1)}},[]),isEnhancing:e,error:a,hasKey:o,setApiKey:d,clearError:i}}function ne({isOpen:e,onClose:t,onSubmit:a}){const r=m(c=>c.voucherConfig.language),[o,l]=b.useState("");if(!e)return null;const i=c=>{c.preventDefault(),o.trim()&&(a(o.trim()),l(""),t())},s={de:{title:"Stability AI API Key",description:"Um die AI-Bildverbesserung zu nutzen, benötigst du einen Stability AI API Key. Du kannst ihn auf platform.stability.ai erhalten.",placeholder:"sk-...",submit:"Speichern",cancel:"Abbrechen",hint:"Der Key wird lokal in deinem Browser gespeichert."},en:{title:"Stability AI API Key",description:"To use AI image enhancement, you need a Stability AI API key. You can get one at platform.stability.ai.",placeholder:"sk-...",submit:"Save",cancel:"Cancel",hint:"The key is stored locally in your browser."}}[r];return n.jsxs("dialog",{className:"modal modal-open",children:[n.jsxs("div",{className:"modal-box",children:[n.jsx("h3",{className:"font-bold text-lg",children:s.title}),n.jsx("p",{className:"py-4 text-sm opacity-80",children:s.description}),n.jsxs("form",{onSubmit:i,children:[n.jsxs("div",{className:"form-control",children:[n.jsx("input",{type:"password",placeholder:s.placeholder,className:"input input-bordered w-full",value:o,onChange:c=>l(c.target.value),autoFocus:!0}),n.jsx("label",{className:"label",children:n.jsx("span",{className:"label-text-alt",children:s.hint})})]}),n.jsxs("div",{className:"modal-action",children:[n.jsx("button",{type:"button",className:"btn btn-ghost",onClick:t,children:s.cancel}),n.jsx("button",{type:"submit",className:"btn btn-primary",disabled:!o.trim(),children:s.submit})]})]})]}),n.jsx("form",{method:"dialog",className:"modal-backdrop",children:n.jsx("button",{onClick:t,children:"close"})})]})}function Ne(){const e=m(u=>u.voucherConfig.language),t=m(u=>u.portrait),a=m(u=>u.setPortrait),r=m(u=>u.setEnhancedPortrait),o=m(u=>u.toggleUseEnhanced),l=m(u=>u.setPortraitZoom),{enhance:i,isEnhancing:d,error:s,hasKey:c,setApiKey:g}=Ie(),h=I(e),f=b.useRef(null),[x,p]=b.useState(!1),[N,k]=b.useState(!1),j=b.useCallback(u=>{if(!u.type.startsWith("image/"))return;const v=new FileReader;v.onload=_=>{var X;const me=(X=_.target)==null?void 0:X.result;a(me)},v.readAsDataURL(u)},[a]),S=b.useCallback(u=>{u.preventDefault(),p(!1);const v=u.dataTransfer.files[0];v&&j(v)},[j]),y=b.useCallback(u=>{u.preventDefault(),p(!0)},[]),P=b.useCallback(u=>{u.preventDefault(),p(!1)},[]),L=()=>{var u;(u=f.current)==null||u.click()},A=u=>{var _;const v=(_=u.target.files)==null?void 0:_[0];v&&j(v)},$=async()=>{if(t.original){if(!c){k(!0);return}try{const u=await i(t.original,"vintage");r(u)}catch(u){console.error("Enhancement failed:",u)}}},U=async u=>{if(g(u),t.original)try{const v=await i(t.original,"vintage");r(v)}catch(v){console.error("Enhancement failed:",v)}},he=()=>{a(null)},pe=t.useEnhanced&&t.enhanced?t.enhanced:t.original;return n.jsxs("div",{className:"space-y-4",children:[t.original?n.jsxs("div",{className:"space-y-4",children:[n.jsx("div",{className:"flex justify-center",children:n.jsxs("div",{className:"relative",children:[n.jsx("div",{className:"w-32 h-32 rounded-full overflow-hidden border-4 border-currency-gold shadow-lg",children:n.jsx("img",{src:pe||"",alt:"Portrait",className:"w-full h-full object-cover",style:{transform:`scale(${t.zoom})`}})}),n.jsx("button",{className:"btn btn-circle btn-xs btn-error absolute -top-1 -right-1",onClick:he,children:n.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:n.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]})}),n.jsxs("div",{className:"form-control",children:[n.jsxs("label",{className:"label",children:[n.jsx("span",{className:"label-text",children:h.form.portrait.zoom}),n.jsxs("span",{className:"label-text-alt",children:[Math.round(t.zoom*100),"%"]})]}),n.jsx("input",{type:"range",min:"0.5",max:"2",step:"0.05",value:t.zoom,onChange:u=>l(parseFloat(u.target.value)),className:"range range-primary range-sm"})]}),c&&n.jsxs("div",{className:"flex flex-col gap-2",children:[n.jsx("button",{className:`btn btn-secondary ${d?"loading":""}`,onClick:$,disabled:d,children:d?n.jsxs(n.Fragment,{children:[n.jsx("span",{className:"loading loading-spinner loading-sm"}),h.form.portrait.enhancing]}):n.jsxs(n.Fragment,{children:[n.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5 mr-1",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:n.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"})}),h.form.portrait.enhance]})}),s&&n.jsxs("div",{className:"alert alert-warning text-sm py-2",children:[n.jsx("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:n.jsx("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"})}),n.jsx("span",{children:s})]}),t.enhanced&&n.jsx("div",{className:"form-control",children:n.jsxs("label",{className:"label cursor-pointer justify-start gap-3",children:[n.jsx("input",{type:"checkbox",className:"toggle toggle-primary",checked:t.useEnhanced,onChange:o}),n.jsx("span",{className:"label-text",children:t.useEnhanced?h.form.portrait.useEnhanced:h.form.portrait.useOriginal})]})})]})]}):n.jsxs("div",{className:`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${x?"border-primary bg-primary/10":"border-base-300 hover:border-primary hover:bg-base-200"}`,onDrop:S,onDragOver:y,onDragLeave:P,onClick:L,children:[n.jsx("input",{ref:f,type:"file",accept:"image/*",className:"hidden",onChange:A}),n.jsxs("div",{className:"flex flex-col items-center gap-2",children:[n.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-12 w-12 text-base-content/50",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:n.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"})}),n.jsx("p",{className:"font-medium",children:h.form.portrait.upload}),n.jsx("p",{className:"text-sm text-base-content/60",children:h.form.portrait.dragDrop})]})]}),n.jsx(ne,{isOpen:N,onClose:()=>k(!1),onSubmit:U})]})}const Ce=[1,5,10];function Ee(){const e=m(i=>i.voucherConfig.language),t=m(i=>i.voucherConfig),a=m(i=>i.setHours),r=m(i=>i.setVoucherConfig),o=I(e),l=i=>i===1?o.form.voucher.hourLabel:o.form.voucher.hoursLabel;return n.jsxs("div",{className:"space-y-4",children:[n.jsxs("div",{className:"form-control",children:[n.jsx("label",{className:"label",children:n.jsx("span",{className:"label-text font-medium",children:o.form.voucher.hours})}),n.jsx("div",{className:"join w-full",children:Ce.map(i=>n.jsxs("button",{className:`join-item btn flex-1 ${t.hours===i?"btn-primary":"btn-outline"}`,onClick:()=>a(i),children:[i," ",l(i)]},i))})]}),n.jsxs("div",{className:"form-control",children:[n.jsx("label",{className:"label",children:n.jsx("span",{className:"label-text font-medium",children:o.form.voucher.description})}),n.jsx("textarea",{className:"textarea textarea-bordered h-24 resize-none w-full",placeholder:o.form.voucher.descriptionPlaceholder,value:t.description,onChange:i=>r({description:i.target.value}),maxLength:200}),n.jsxs("label",{className:"label",children:[n.jsx("span",{className:"label-text-alt"}),n.jsxs("span",{className:"label-text-alt",children:[t.description.length,"/200"]})]})]})]})}const w=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:T&&T.tagName.toUpperCase()==="SCRIPT"&&T.src||new URL("index.cjs",document.baseURI).href}<"u"&&"/"||"/",ae={en:{1:{front:`${w}templates/front_ldpi_en.png`,back:`${w}templates/back_ldpi_en.png`,width:1536,height:1024},5:{front:`${w}templates/front_ldpi_en.png`,back:`${w}templates/back_ldpi_en.png`,width:1536,height:1024},10:{front:`${w}templates/front_ldpi_en.png`,back:`${w}templates/back_ldpi_en.png`,width:1536,height:1024}},de:{1:{front:`${w}templates/front_hdpi_de.webp`,back:`${w}templates/back_hdpi_de.webp`,width:6144,height:3200},5:{front:`${w}templates/front_hdpi_de.webp`,back:`${w}templates/back_hdpi_de.webp`,width:6144,height:3200},10:{front:`${w}templates/front_hdpi_de.webp`,back:`${w}templates/back_hdpi_de.webp`,width:6144,height:3200}}},C={front:{portrait:{x:768,y:490,radiusX:236,radiusY:258},namePlate:{x:768,y:848,fontSize:36,maxWidth:380,align:"center"}},back:{portrait:{x:0,y:0,radiusX:0,radiusY:0},namePlate:{x:768,y:832,fontSize:36,maxWidth:380,align:"center"},contactInfo:{x:380,y:500,fontSize:38,lineHeight:55,align:"center"},description:{x:1150,y:500,fontSize:38,maxWidth:480,lineHeight:42,align:"center"}}},E={front:{portrait:{x:3074,y:1530,radiusX:942,radiusY:1020},namePlate:{x:3072,y:2950,fontSize:144,maxWidth:1520,align:"center"}},back:{portrait:{x:0,y:0,radiusX:0,radiusY:0},namePlate:{x:3072,y:2930,fontSize:144,maxWidth:1520,align:"center"},contactInfo:{x:1520,y:1680,fontSize:160,lineHeight:280,align:"center"},description:{x:4600,y:1680,fontSize:145,maxWidth:2e3,lineHeight:210,align:"center"}}};function W(e){return e==="de"?E:C}function q(e,t){return ae[e][t]}const F=new Map;async function D(e){return F.has(e)?F.get(e):new Promise((t,a)=>{const r=new Image;r.crossOrigin="anonymous",r.onload=()=>{F.set(e,r),t(r)},r.onerror=a,r.src=e})}function Y(e,t,a,r){e.drawImage(t,0,0,a,r)}function re(e,t,a,r,o,l,i=1){e.save(),e.beginPath(),e.ellipse(a,r,o,l,0,0,Math.PI*2),e.closePath(),e.clip();const d=t.width/t.height,s=o/l,c=o*2,g=l*2;let h,f;d>s?(f=g,h=g*d):(h=c,f=c/d),h*=i,f*=i;const x=a-h/2,p=r-f/2;e.drawImage(t,x,p,h,f),e.restore()}function V(e,t,a,r="#2a3a2a"){e.save(),e.font=`${a.fontSize}px "Times New Roman", serif`,e.textAlign=a.align||"center",e.textBaseline="middle",e.fillStyle=r,a.maxWidth?e.fillText(t,a.x,a.y,a.maxWidth):e.fillText(t,a.x,a.y),e.restore()}function oe(e,t,a,r="#2a3a2a"){e.save(),e.font=`${a.fontSize}px "Times New Roman", serif`,e.textAlign=a.align||"center",e.textBaseline="top",e.fillStyle=r;const o=a.maxWidth||400,l=a.lineHeight||a.fontSize*1.4,i=t.split(" "),d=[];let s="";for(const h of i){const f=s?`${s} ${h}`:h;e.measureText(f).width>o&&s?(d.push(s),s=h):s=f}s&&d.push(s);const c=d.length*l;let g=a.y-c/2;for(const h of d)e.fillText(h,a.x,g),g+=l;e.restore()}function ie(e,t,a,r,o,l="#2a3a2a"){e.save(),e.font=`${o.fontSize}px "Times New Roman", serif`,e.textAlign=o.align||"center",e.textBaseline="middle",e.fillStyle=l;const i=o.lineHeight||o.fontSize*1.8,d=[t,a,r].filter(Boolean),s=(d.length-1)*i;let c=o.y-s/2;for(const g of d)g&&(e.fillText(g,o.x,c),c+=i);e.restore()}async function Z(e,t,a,r,o,l,i,d=1){const s=e.getContext("2d");if(!s)return;e.width=l,e.height=i,s.clearRect(0,0,l,i);const c=await D(t);if(Y(s,c,l,i),a)try{const g=await D(a);re(s,g,o.portrait.x,o.portrait.y,o.portrait.radiusX,o.portrait.radiusY,d)}catch(g){console.error("Failed to load portrait:",g)}r&&V(s,r,o.namePlate)}async function G(e,t,a,r,o,l,i,d,s){const c=e.getContext("2d");if(!c)return;e.width=d,e.height=s,c.clearRect(0,0,d,s);const g=await D(t);Y(c,g,d,s),i.contactInfo&&(a||r||o)&&ie(c,a,r,o,i.contactInfo),i.description&&l&&oe(c,l,i.description),a&&V(c,a,i.namePlate)}function Se(){const e=m(y=>y.voucherConfig.language),t=m(y=>y.voucherConfig.hours),a=m(y=>y.voucherConfig.description),r=m(y=>y.personalInfo),o=m(y=>y.portrait),l=m(y=>y.currentSide),i=m(y=>y.flipSide),d=I(e),s=b.useRef(null),c=b.useRef(null),g=b.useRef(null),[h,f]=b.useState(!1),x=q(e,t),p=W(e),N=o.useEnhanced&&o.enhanced?o.enhanced:o.original,k=K(e,t,a);b.useEffect(()=>{s.current&&Z(s.current,x.front,N,r.name,p.front,x.width,x.height,o.zoom)},[x,N,r.name,p,o.zoom]),b.useEffect(()=>{c.current&&G(c.current,x.back,r.name,r.email,r.phone,k,p.back,x.width,x.height)},[x,r,k,p]);const j=()=>{f(!0),setTimeout(()=>{i(),f(!1)},150)},S=x.width/x.height;return n.jsxs("div",{className:"space-y-4",children:[n.jsxs("div",{className:"flex justify-between items-center",children:[n.jsxs("div",{className:"tabs tabs-boxed bg-base-200",children:[n.jsx("button",{className:`tab ${l==="front"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>l!=="front"&&j(),children:d.preview.front}),n.jsx("button",{className:`tab ${l==="back"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>l!=="back"&&j(),children:d.preview.back})]}),n.jsxs("button",{className:"btn btn-ghost btn-sm",onClick:j,children:[n.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:n.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"})}),d.preview.flip]})]}),n.jsxs("div",{ref:g,className:"relative w-full overflow-hidden shadow-lg",style:{aspectRatio:S},children:[n.jsx("canvas",{ref:s,className:`absolute inset-0 w-full h-full transition-all duration-300 ${l==="front"?h?"opacity-0 scale-95":"opacity-100 scale-100":"opacity-0 scale-95 pointer-events-none"}`}),n.jsx("canvas",{ref:c,className:`absolute inset-0 w-full h-full transition-all duration-300 ${l==="back"?h?"opacity-0 scale-95":"opacity-100 scale-100":"opacity-0 scale-95 pointer-events-none"}`})]})]})}function Te(){const e=b.useRef(null),t=b.useRef(null);return{frontCanvasRef:e,backCanvasRef:t}}async function se(e){const{frontTemplateSrc:t,backTemplateSrc:a,templateWidth:r,templateHeight:o,layout:l,portrait:i,portraitZoom:d=1,name:s,email:c,phone:g,description:h}=e,f=document.createElement("canvas"),x=document.createElement("canvas");await Promise.all([Z(f,t,i,s,l.front,r,o,d),G(x,a,s,c,g,h,l.back,r,o)]);const p=new be({orientation:"landscape",unit:"mm",format:"a4"}),N=297,k=210,j=10,S=r/o;let y=N-j*2,P=y/S;P>k-j*2&&(P=k-j*2,y=P*S);const L=(N-y)/2,A=(k-P)/2,$=f.toDataURL("image/jpeg",.95);p.addImage($,"JPEG",L,A,y,P),p.addPage();const U=x.toDataURL("image/jpeg",.95);return p.addImage(U,"JPEG",L,A,y,P),p.output("blob")}function le(e,t){const a=URL.createObjectURL(e),r=document.createElement("a");r.href=a,r.download=t,document.body.appendChild(r),r.click(),document.body.removeChild(r),URL.revokeObjectURL(a)}async function ce(e){const t=await se(e);le(t,e.filename)}function Le(){const e=m(p=>p.voucherConfig.language),t=m(p=>p.voucherConfig.hours),a=m(p=>p.voucherConfig.description),r=m(p=>p.personalInfo),o=m(p=>p.portrait),l=m(p=>p.isExporting),i=m(p=>p.setIsExporting),d=I(e),s=q(e,t),c=W(e),g=o.useEnhanced&&o.enhanced?o.enhanced:o.original,h=K(e,t,a),f=r.name.trim().length>0&&r.email.trim().length>0&&r.phone.trim().length>0&&o.original!==null,x=async()=>{if(!(!f||l)){i(!0);try{const p=`zeitgutschein-${t}h-${r.name.replace(/\s+/g,"-").toLowerCase()}.pdf`;await ce({frontTemplateSrc:s.front,backTemplateSrc:s.back,templateWidth:s.width,templateHeight:s.height,layout:c,portrait:g,portraitZoom:o.zoom,name:r.name,email:r.email,phone:r.phone,description:h,filename:p})}catch(p){console.error("PDF export failed:",p)}finally{i(!1)}}};return n.jsx("button",{className:`btn btn-primary flex-1 ${l?"loading":""}`,onClick:x,disabled:!f||l,children:l?n.jsxs(n.Fragment,{children:[n.jsx("span",{className:"loading loading-spinner loading-sm"}),d.export.exporting]}):n.jsxs(n.Fragment,{children:[n.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:n.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"})}),d.export.button]})})}function de(){const e=m(r=>r.voucherConfig.language),t=m(r=>r.setLanguage),a=r=>{t(r)};return n.jsxs("div",{className:"join",children:[n.jsx("button",{className:`join-item btn btn-sm ${e==="de"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>a("de"),children:"DE"}),n.jsx("button",{className:`join-item btn btn-sm ${e==="en"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>a("en"),children:"EN"})]})}function Ae(){const e=m(a=>a.voucherConfig.language),t=I(e);return n.jsxs("div",{className:"navbar bg-currency-green text-currency-cream shadow-lg",children:[n.jsx("div",{className:"navbar-start",children:n.jsx("a",{className:"btn btn-ghost text-xl font-currency font-bold",children:t.header.title})}),n.jsx("div",{className:"navbar-center hidden sm:flex",children:n.jsx("span",{className:"text-sm opacity-80",children:t.header.subtitle})}),n.jsx("div",{className:"navbar-end",children:n.jsx(de,{})})]})}const R="/",_e={id:"time-voucher-classic-de",name:"Zeitgutschein Classic",type:"time-voucher",category:"classic",images:{front:`${R}templates/front_hdpi_de.jpg`,back:`${R}templates/back_hdpi_de.jpg`,width:6144,height:4096},fields:[{id:"name",type:"text",label:{de:"Name",en:"Name"},required:!0,validation:{minLength:1,maxLength:50}},{id:"hours",type:"select",label:{de:"Stunden",en:"Hours"},required:!0,options:["1","5","10"]},{id:"portrait",type:"image",label:{de:"Portrait",en:"Portrait"},required:!1},{id:"email",type:"text",label:{de:"E-Mail",en:"Email"},required:!1},{id:"phone",type:"text",label:{de:"Telefon",en:"Phone"},required:!1},{id:"description",type:"textarea",label:{de:"Beschreibung",en:"Description"},required:!1,validation:{maxLength:200}}],layout:{front:{portrait:E.front.portrait,name:E.front.namePlate},back:{name:E.back.namePlate,contactInfo:E.back.contactInfo,description:E.back.description}},languages:["de"]},De={id:"time-voucher-classic-en",name:"Time Voucher Classic",type:"time-voucher",category:"classic",images:{front:`${R}templates/front_ldpi_en.png`,back:`${R}templates/back_ldpi_en.png`,width:1536,height:1024},fields:[{id:"name",type:"text",label:{de:"Name",en:"Name"},required:!0,validation:{minLength:1,maxLength:50}},{id:"hours",type:"select",label:{de:"Stunden",en:"Hours"},required:!0,options:["1","5","10"]},{id:"portrait",type:"image",label:{de:"Portrait",en:"Portrait"},required:!1},{id:"email",type:"text",label:{de:"E-Mail",en:"Email"},required:!1},{id:"phone",type:"text",label:{de:"Telefon",en:"Phone"},required:!1},{id:"description",type:"textarea",label:{de:"Beschreibung",en:"Description"},required:!1,validation:{maxLength:200}}],layout:{front:{portrait:C.front.portrait,name:C.front.namePlate},back:{name:C.back.namePlate,contactInfo:C.back.contactInfo,description:C.back.description}},languages:["en"]},Q=[_e,De],ue={async listTemplates(e){let t=[...Q];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},async getTemplate(e){const t=Q.find(a=>a.id===e);if(!t)throw new Error(`Template not found: ${e}`);return t}};function Re(e){return e==="de"?"time-voucher-classic-de":"time-voucher-classic-en"}let B=ue;function Be(e){B=e}function $e(){return B}async function Ue(e){return B.listTemplates(e)}async function He(e){return B.getTemplate(e)}exports.ApiKeyModal=ne;exports.BillPreview=Se;exports.ExportButton=Le;exports.Header=Ae;exports.LAYOUT_HDPI=E;exports.LAYOUT_LDPI=C;exports.LanguageToggle=de;exports.PersonalInfoForm=we;exports.PortraitUpload=Ne;exports.TEMPLATES=ae;exports.VoucherConfig=Ee;exports.downloadBlob=le;exports.drawContactInfo=ie;exports.drawMultilineText=oe;exports.drawOvalPortrait=re;exports.drawTemplate=Y;exports.drawText=V;exports.enhancePortrait=te;exports.enhancePortraitFallback=M;exports.exportBillAsPDF=ce;exports.formatDescription=K;exports.generateBillPDF=se;exports.getApiKey=O;exports.getDefaultTemplateId=Re;exports.getLayout=W;exports.getTemplate=q;exports.getTemplateById=He;exports.getTemplateProvider=$e;exports.hasApiKey=z;exports.listTemplates=Ue;exports.loadImage=D;exports.renderBackSide=G;exports.renderFrontSide=Z;exports.setApiKey=ee;exports.setTemplateProvider=Be;exports.staticTemplateProvider=ue;exports.t=I;exports.useBillCanvasRefs=Te;exports.useBillStore=m;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("react/jsx-runtime"),ge=require("zustand"),fe=require("zustand/middleware"),b=require("react"),be=require("jspdf");var T=typeof document<"u"?document.currentScript:null;const J={personalInfo:{name:"",email:"",phone:""},voucherConfig:{hours:1,description:"",language:"de"},portrait:{original:null,enhanced:null,useEnhanced:!1,zoom:1},currentSide:"front",isEnhancing:!1,isExporting:!1},m=ge.create()(fe.persist(e=>({...J,setPersonalInfo:t=>e(a=>({personalInfo:{...a.personalInfo,...t}})),setVoucherConfig:t=>e(a=>({voucherConfig:{...a.voucherConfig,...t}})),setPortrait:(t,a=null)=>e({portrait:{original:t,enhanced:a,useEnhanced:!1,zoom:1}}),setEnhancedPortrait:t=>e(a=>({portrait:{...a.portrait,enhanced:t,useEnhanced:t!==null}})),toggleUseEnhanced:()=>e(t=>({portrait:{...t.portrait,useEnhanced:t.portrait.enhanced?!t.portrait.useEnhanced:!1}})),setPortraitZoom:t=>e(a=>({portrait:{...a.portrait,zoom:t}})),setCurrentSide:t=>e({currentSide:t}),flipSide:()=>e(t=>({currentSide:t.currentSide==="front"?"back":"front"})),setIsEnhancing:t=>e({isEnhancing:t}),setIsExporting:t=>e({isExporting:t}),setLanguage:t=>e(a=>({voucherConfig:{...a.voucherConfig,language:t}})),setHours:t=>e(a=>({voucherConfig:{...a.voucherConfig,hours:t}})),reset:()=>e(J)}),{name:"money-generator-storage",partialize:e=>({personalInfo:e.personalInfo,voucherConfig:e.voucherConfig})})),xe={header:{title:"Money Generator",subtitle:"Erstelle deinen persönlichen Zeitgutschein"},form:{personalInfo:{title:"Persönliche Daten",name:"Name",namePlaceholder:"Dein Name",email:"E-Mail",emailPlaceholder:"deine@email.de",phone:"Telefon",phonePlaceholder:"+49 123 456789"},portrait:{title:"Portrait",upload:"Bild hochladen",dragDrop:"oder hierher ziehen",enhance:"Mit AI verbessern",enhancing:"Wird verbessert...",useOriginal:"Original verwenden",useEnhanced:"Verbessertes verwenden",zoom:"Zoom"},voucher:{title:"Gutschein",hours:"Stunden",hourLabel:"Stunde",hoursLabel:"Stunden",description:"Beschreibung",descriptionPlaceholder:"Was kann mit diesem Gutschein eingelöst werden?"}},preview:{front:"Vorderseite",back:"Rückseite",flip:"Umdrehen"},export:{button:"Als PDF herunterladen",exporting:"PDF wird erstellt...",success:"Download gestartet!"},bill:{descriptionText:"Für diesen Schein erhältst du {hours} {hourLabel} meiner Zeit oder ein gleichwertiges Dankeschön"}},ye={header:{title:"Money Generator",subtitle:"Create your personal time voucher"},form:{personalInfo:{title:"Personal Information",name:"Name",namePlaceholder:"Your name",email:"Email",emailPlaceholder:"your@email.com",phone:"Phone",phonePlaceholder:"+1 234 567890"},portrait:{title:"Portrait",upload:"Upload image",dragDrop:"or drag and drop",enhance:"Enhance with AI",enhancing:"Enhancing...",useOriginal:"Use original",useEnhanced:"Use enhanced",zoom:"Zoom"},voucher:{title:"Voucher",hours:"Hours",hourLabel:"hour",hoursLabel:"hours",description:"Description",descriptionPlaceholder:"What can be redeemed with this voucher?"}},preview:{front:"Front",back:"Back",flip:"Flip"},export:{button:"Download as PDF",exporting:"Creating PDF...",success:"Download started!"},bill:{descriptionText:"This voucher entitles you to {hours} {hourLabel} of my time or an equivalent thank you"}},ve={de:xe,en:ye};function E(e){return ve[e]}function K(e,t,a){if(a&&a.trim())return a;const r=E(e),o=t===1?r.form.voucher.hourLabel:r.form.voucher.hoursLabel;return r.bill.descriptionText.replace("{hours}",t.toString()).replace("{hourLabel}",o)}function we(){const e=m(o=>o.voucherConfig.language),t=m(o=>o.personalInfo),a=m(o=>o.setPersonalInfo),r=E(e);return n.jsxs("div",{className:"space-y-4",children:[n.jsxs("div",{className:"form-control",children:[n.jsx("label",{className:"label",children:n.jsx("span",{className:"label-text font-medium",children:r.form.personalInfo.name})}),n.jsx("input",{type:"text",placeholder:r.form.personalInfo.namePlaceholder,className:"input input-bordered w-full",value:t.name,onChange:o=>a({name:o.target.value})})]}),n.jsxs("div",{className:"form-control",children:[n.jsx("label",{className:"label",children:n.jsx("span",{className:"label-text font-medium",children:r.form.personalInfo.email})}),n.jsx("input",{type:"email",placeholder:r.form.personalInfo.emailPlaceholder,className:"input input-bordered w-full",value:t.email,onChange:o=>a({email:o.target.value})})]}),n.jsxs("div",{className:"form-control",children:[n.jsx("label",{className:"label",children:n.jsx("span",{className:"label-text font-medium",children:r.form.personalInfo.phone})}),n.jsx("input",{type:"tel",placeholder:r.form.personalInfo.phonePlaceholder,className:"input input-bordered w-full",value:t.phone,onChange:o=>a({phone:o.target.value})})]})]})}const F={},ke="https://api.stability.ai/v1/generation",je={vintage:"portrait in the style of vintage currency engraving, fine line work, crosshatching, sepia tones, detailed stippling, classic bank note portrait style",engraved:"portrait as detailed intaglio engraving, currency bill style, fine parallel lines, high contrast, official government portrait",currency:"portrait rendered as US dollar bill engraving, official currency portrait style, green tint, fine line engraving technique"};function Pe(e){var l;const t=e.split(","),a=((l=t[0].match(/:(.*?);/))==null?void 0:l[1])||"image/png",r=atob(t[1]),o=r.length,s=new Uint8Array(o);for(let d=0;d<o;d++)s[d]=r.charCodeAt(d);return new Blob([s],{type:a})}function W(){var t;const e=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:T&&T.tagName.toUpperCase()==="SCRIPT"&&T.src||new URL("index.cjs",document.baseURI).href}<"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);return e&&e!=="your-api-key-here"?e:typeof localStorage<"u"?localStorage.getItem("stability_api_key"):null}function ee(e){localStorage.setItem("stability_api_key",e)}function M(){return W()!==null}async function te(e){const t=W();if(!t)throw new Error("No Stability AI API key configured");const{imageDataUrl:a,style:r,strength:o=.35}=e,s=Pe(a),l=new FormData;l.append("init_image",s,"portrait.png"),l.append("init_image_mode","IMAGE_STRENGTH"),l.append("image_strength",String(1-o)),l.append("text_prompts[0][text]",je[r]),l.append("text_prompts[0][weight]","1"),l.append("cfg_scale","7"),l.append("samples","1"),l.append("steps","30");const i=await fetch(`${ke}/stable-diffusion-xl-1024-v1-0/image-to-image`,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"},body:l});if(!i.ok){const g=await i.text();throw console.error("Stability AI error:",g),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}`)}const c=await i.json();if(!c.artifacts||c.artifacts.length===0)throw new Error("No image generated");return`data:image/png;base64,${c.artifacts[0].base64}`}async function H(e){return new Promise((t,a)=>{const r=new Image;r.onload=()=>{const o=document.createElement("canvas"),s=o.getContext("2d");if(!s){a(new Error("Failed to get canvas context"));return}o.width=r.width,o.height=r.height,s.filter="sepia(0.3) contrast(1.1) saturate(0.9)",s.drawImage(r,0,0),t(o.toDataURL("image/png"))},r.onerror=()=>a(new Error("Failed to load image")),r.src=e})}function Ie(){const[e,t]=b.useState(!1),[a,r]=b.useState(null),[o,s]=b.useState(M()),l=b.useCallback(()=>r(null),[]),d=b.useCallback(c=>{ee(c),s(!0),r(null)},[]);return{enhance:b.useCallback(async(c,g="vintage")=>{t(!0),r(null);try{return M()?await te({imageDataUrl:c,style:g,strength:.35}):await H(c)}catch(p){const f=p instanceof Error?p.message:"Enhancement failed";if(r(f),f.includes("API")||f.includes("key"))try{return await H(c)}catch{throw p}throw p}finally{t(!1)}},[]),isEnhancing:e,error:a,hasKey:o,setApiKey:d,clearError:l}}function ne({isOpen:e,onClose:t,onSubmit:a}){const r=m(c=>c.voucherConfig.language),[o,s]=b.useState("");if(!e)return null;const l=c=>{c.preventDefault(),o.trim()&&(a(o.trim()),s(""),t())},i={de:{title:"Stability AI API Key",description:"Um die AI-Bildverbesserung zu nutzen, benötigst du einen Stability AI API Key. Du kannst ihn auf platform.stability.ai erhalten.",placeholder:"sk-...",submit:"Speichern",cancel:"Abbrechen",hint:"Der Key wird lokal in deinem Browser gespeichert."},en:{title:"Stability AI API Key",description:"To use AI image enhancement, you need a Stability AI API key. You can get one at platform.stability.ai.",placeholder:"sk-...",submit:"Save",cancel:"Cancel",hint:"The key is stored locally in your browser."}}[r];return n.jsxs("dialog",{className:"modal modal-open",children:[n.jsxs("div",{className:"modal-box",children:[n.jsx("h3",{className:"font-bold text-lg",children:i.title}),n.jsx("p",{className:"py-4 text-sm opacity-80",children:i.description}),n.jsxs("form",{onSubmit:l,children:[n.jsxs("div",{className:"form-control",children:[n.jsx("input",{type:"password",placeholder:i.placeholder,className:"input input-bordered w-full",value:o,onChange:c=>s(c.target.value),autoFocus:!0}),n.jsx("label",{className:"label",children:n.jsx("span",{className:"label-text-alt",children:i.hint})})]}),n.jsxs("div",{className:"modal-action",children:[n.jsx("button",{type:"button",className:"btn btn-ghost",onClick:t,children:i.cancel}),n.jsx("button",{type:"submit",className:"btn btn-primary",disabled:!o.trim(),children:i.submit})]})]})]}),n.jsx("form",{method:"dialog",className:"modal-backdrop",children:n.jsx("button",{onClick:t,children:"close"})})]})}function Ne(){const e=m(u=>u.voucherConfig.language),t=m(u=>u.portrait),a=m(u=>u.setPortrait),r=m(u=>u.setEnhancedPortrait),o=m(u=>u.toggleUseEnhanced),s=m(u=>u.setPortraitZoom),{enhance:l,isEnhancing:d,error:i,hasKey:c,setApiKey:g}=Ie(),p=E(e),f=b.useRef(null),[x,h]=b.useState(!1),[I,j]=b.useState(!1),k=b.useCallback(u=>{if(!u.type.startsWith("image/"))return;const v=new FileReader;v.onload=_=>{var X;const me=(X=_.target)==null?void 0:X.result;a(me)},v.readAsDataURL(u)},[a]),S=b.useCallback(u=>{u.preventDefault(),h(!1);const v=u.dataTransfer.files[0];v&&k(v)},[k]),y=b.useCallback(u=>{u.preventDefault(),h(!0)},[]),P=b.useCallback(u=>{u.preventDefault(),h(!1)},[]),L=()=>{var u;(u=f.current)==null||u.click()},A=u=>{var _;const v=(_=u.target.files)==null?void 0:_[0];v&&k(v)},$=async()=>{if(t.original){if(!c){j(!0);return}try{const u=await l(t.original,"vintage");r(u)}catch(u){console.error("Enhancement failed:",u)}}},U=async u=>{if(g(u),t.original)try{const v=await l(t.original,"vintage");r(v)}catch(v){console.error("Enhancement failed:",v)}},pe=()=>{a(null)},he=t.useEnhanced&&t.enhanced?t.enhanced:t.original;return n.jsxs("div",{className:"space-y-4",children:[t.original?n.jsxs("div",{className:"space-y-4",children:[n.jsx("div",{className:"flex justify-center",children:n.jsxs("div",{className:"relative",children:[n.jsx("div",{className:"w-32 h-32 rounded-full overflow-hidden border-4 border-currency-gold shadow-lg",children:n.jsx("img",{src:he||"",alt:"Portrait",className:"w-full h-full object-cover",style:{transform:`scale(${t.zoom})`}})}),n.jsx("button",{className:"btn btn-circle btn-xs btn-error absolute -top-1 -right-1",onClick:pe,children:n.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:n.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]})}),n.jsxs("div",{className:"form-control",children:[n.jsxs("label",{className:"label",children:[n.jsx("span",{className:"label-text",children:p.form.portrait.zoom}),n.jsxs("span",{className:"label-text-alt",children:[Math.round(t.zoom*100),"%"]})]}),n.jsx("input",{type:"range",min:"0.5",max:"2",step:"0.05",value:t.zoom,onChange:u=>s(parseFloat(u.target.value)),className:"range range-primary range-sm"})]}),c&&n.jsxs("div",{className:"flex flex-col gap-2",children:[n.jsx("button",{className:`btn btn-secondary ${d?"loading":""}`,onClick:$,disabled:d,children:d?n.jsxs(n.Fragment,{children:[n.jsx("span",{className:"loading loading-spinner loading-sm"}),p.form.portrait.enhancing]}):n.jsxs(n.Fragment,{children:[n.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5 mr-1",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:n.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"})}),p.form.portrait.enhance]})}),i&&n.jsxs("div",{className:"alert alert-warning text-sm py-2",children:[n.jsx("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:n.jsx("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"})}),n.jsx("span",{children:i})]}),t.enhanced&&n.jsx("div",{className:"form-control",children:n.jsxs("label",{className:"label cursor-pointer justify-start gap-3",children:[n.jsx("input",{type:"checkbox",className:"toggle toggle-primary",checked:t.useEnhanced,onChange:o}),n.jsx("span",{className:"label-text",children:t.useEnhanced?p.form.portrait.useEnhanced:p.form.portrait.useOriginal})]})})]})]}):n.jsxs("div",{className:`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${x?"border-primary bg-primary/10":"border-base-300 hover:border-primary hover:bg-base-200"}`,onDrop:S,onDragOver:y,onDragLeave:P,onClick:L,children:[n.jsx("input",{ref:f,type:"file",accept:"image/*",className:"hidden",onChange:A}),n.jsxs("div",{className:"flex flex-col items-center gap-2",children:[n.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-12 w-12 text-base-content/50",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:n.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"})}),n.jsx("p",{className:"font-medium",children:p.form.portrait.upload}),n.jsx("p",{className:"text-sm text-base-content/60",children:p.form.portrait.dragDrop})]})]}),n.jsx(ne,{isOpen:I,onClose:()=>j(!1),onSubmit:U})]})}function Ce(){return null}const w=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:T&&T.tagName.toUpperCase()==="SCRIPT"&&T.src||new URL("index.cjs",document.baseURI).href}<"u"&&"/"||"/",ae={en:{1:{front:`${w}templates/front_ldpi_en.png`,back:`${w}templates/back_ldpi_en.png`,width:1536,height:1024},5:{front:`${w}templates/front_ldpi_en.png`,back:`${w}templates/back_ldpi_en.png`,width:1536,height:1024},10:{front:`${w}templates/front_ldpi_en.png`,back:`${w}templates/back_ldpi_en.png`,width:1536,height:1024}},de:{1:{front:`${w}templates/front_hdpi_de.webp`,back:`${w}templates/back_hdpi_de.webp`,width:6144,height:3200},5:{front:`${w}templates/front_hdpi_de.webp`,back:`${w}templates/back_hdpi_de.webp`,width:6144,height:3200},10:{front:`${w}templates/front_hdpi_de.webp`,back:`${w}templates/back_hdpi_de.webp`,width:6144,height:3200}}},N={front:{portrait:{x:768,y:490,radiusX:236,radiusY:258},namePlate:{x:768,y:848,fontSize:36,maxWidth:380,align:"center"}},back:{portrait:{x:0,y:0,radiusX:0,radiusY:0},namePlate:{x:768,y:832,fontSize:36,maxWidth:380,align:"center"},contactInfo:{x:380,y:500,fontSize:38,lineHeight:55,align:"center"},description:{x:1150,y:500,fontSize:38,maxWidth:480,lineHeight:42,align:"center"}}},C={front:{portrait:{x:3074,y:1530,radiusX:942,radiusY:1020},namePlate:{x:3072,y:2950,fontSize:144,maxWidth:1520,align:"center"}},back:{portrait:{x:0,y:0,radiusX:0,radiusY:0},namePlate:{x:3072,y:2930,fontSize:144,maxWidth:1520,align:"center"},contactInfo:{x:1520,y:1680,fontSize:160,lineHeight:280,align:"center"},description:{x:4600,y:1680,fontSize:145,maxWidth:2e3,lineHeight:210,align:"center"}}};function O(e){return e==="de"?C:N}function q(e,t){return ae[e][t]}const z=new Map;async function D(e){return z.has(e)?z.get(e):new Promise((t,a)=>{const r=new Image;r.crossOrigin="anonymous",r.onload=()=>{z.set(e,r),t(r)},r.onerror=a,r.src=e})}function Y(e,t,a,r){e.drawImage(t,0,0,a,r)}function re(e,t,a,r,o,s,l=1){e.save(),e.beginPath(),e.ellipse(a,r,o,s,0,0,Math.PI*2),e.closePath(),e.clip();const d=t.width/t.height,i=o/s,c=o*2,g=s*2;let p,f;d>i?(f=g,p=g*d):(p=c,f=c/d),p*=l,f*=l;const x=a-p/2,h=r-f/2;e.drawImage(t,x,h,p,f),e.restore()}function V(e,t,a,r="#2a3a2a"){e.save(),e.font=`${a.fontSize}px "Times New Roman", serif`,e.textAlign=a.align||"center",e.textBaseline="middle",e.fillStyle=r,a.maxWidth?e.fillText(t,a.x,a.y,a.maxWidth):e.fillText(t,a.x,a.y),e.restore()}function oe(e,t,a,r="#2a3a2a"){e.save(),e.font=`${a.fontSize}px "Times New Roman", serif`,e.textAlign=a.align||"center",e.textBaseline="top",e.fillStyle=r;const o=a.maxWidth||400,s=a.lineHeight||a.fontSize*1.4,l=t.split(" "),d=[];let i="";for(const p of l){const f=i?`${i} ${p}`:p;e.measureText(f).width>o&&i?(d.push(i),i=p):i=f}i&&d.push(i);const c=d.length*s;let g=a.y-c/2;for(const p of d)e.fillText(p,a.x,g),g+=s;e.restore()}function ie(e,t,a,r,o,s="#2a3a2a"){e.save(),e.font=`${o.fontSize}px "Times New Roman", serif`,e.textAlign=o.align||"center",e.textBaseline="middle",e.fillStyle=s;const l=o.lineHeight||o.fontSize*1.8,d=[t,a,r].filter(Boolean),i=(d.length-1)*l;let c=o.y-i/2;for(const g of d)g&&(e.fillText(g,o.x,c),c+=l);e.restore()}async function Z(e,t,a,r,o,s,l,d=1){const i=e.getContext("2d");if(!i)return;e.width=s,e.height=l,i.clearRect(0,0,s,l);const c=await D(t);if(Y(i,c,s,l),a)try{const g=await D(a);re(i,g,o.portrait.x,o.portrait.y,o.portrait.radiusX,o.portrait.radiusY,d)}catch(g){console.error("Failed to load portrait:",g)}r&&V(i,r,o.namePlate)}async function G(e,t,a,r,o,s,l,d,i){const c=e.getContext("2d");if(!c)return;e.width=d,e.height=i,c.clearRect(0,0,d,i);const g=await D(t);Y(c,g,d,i),l.contactInfo&&(a||r||o)&&ie(c,a,r,o,l.contactInfo),l.description&&s&&oe(c,s,l.description),a&&V(c,a,l.namePlate)}function Ee(){const e=m(y=>y.voucherConfig.language),t=m(y=>y.voucherConfig.hours),a=m(y=>y.voucherConfig.description),r=m(y=>y.personalInfo),o=m(y=>y.portrait),s=m(y=>y.currentSide),l=m(y=>y.flipSide),d=E(e),i=b.useRef(null),c=b.useRef(null),g=b.useRef(null),[p,f]=b.useState(!1),x=q(e,t),h=O(e),I=o.useEnhanced&&o.enhanced?o.enhanced:o.original,j=K(e,t,a);b.useEffect(()=>{i.current&&Z(i.current,x.front,I,r.name,h.front,x.width,x.height,o.zoom)},[x,I,r.name,h,o.zoom]),b.useEffect(()=>{c.current&&G(c.current,x.back,r.name,r.email,r.phone,j,h.back,x.width,x.height)},[x,r,j,h]);const k=()=>{f(!0),setTimeout(()=>{l(),f(!1)},150)},S=x.width/x.height;return n.jsxs("div",{className:"space-y-4",children:[n.jsxs("div",{className:"flex justify-between items-center",children:[n.jsxs("div",{className:"tabs tabs-boxed bg-base-200",children:[n.jsx("button",{className:`tab ${s==="front"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>s!=="front"&&k(),children:d.preview.front}),n.jsx("button",{className:`tab ${s==="back"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>s!=="back"&&k(),children:d.preview.back})]}),n.jsxs("button",{className:"btn btn-ghost btn-sm",onClick:k,children:[n.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:n.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"})}),d.preview.flip]})]}),n.jsxs("div",{ref:g,className:"relative w-full overflow-hidden shadow-lg",style:{aspectRatio:S},children:[n.jsx("canvas",{ref:i,className:`absolute inset-0 w-full h-full transition-all duration-300 ${s==="front"?p?"opacity-0 scale-95":"opacity-100 scale-100":"opacity-0 scale-95 pointer-events-none"}`}),n.jsx("canvas",{ref:c,className:`absolute inset-0 w-full h-full transition-all duration-300 ${s==="back"?p?"opacity-0 scale-95":"opacity-100 scale-100":"opacity-0 scale-95 pointer-events-none"}`})]})]})}function Se(){const e=b.useRef(null),t=b.useRef(null);return{frontCanvasRef:e,backCanvasRef:t}}async function se(e){const{frontTemplateSrc:t,backTemplateSrc:a,templateWidth:r,templateHeight:o,layout:s,portrait:l,portraitZoom:d=1,name:i,email:c,phone:g,description:p}=e,f=document.createElement("canvas"),x=document.createElement("canvas");await Promise.all([Z(f,t,l,i,s.front,r,o,d),G(x,a,i,c,g,p,s.back,r,o)]);const h=new be({orientation:"landscape",unit:"mm",format:"a4"}),I=297,j=210,k=10,S=r/o;let y=I-k*2,P=y/S;P>j-k*2&&(P=j-k*2,y=P*S);const L=(I-y)/2,A=(j-P)/2,$=f.toDataURL("image/jpeg",.95);h.addImage($,"JPEG",L,A,y,P),h.addPage();const U=x.toDataURL("image/jpeg",.95);return h.addImage(U,"JPEG",L,A,y,P),h.output("blob")}function le(e,t){const a=URL.createObjectURL(e),r=document.createElement("a");r.href=a,r.download=t,document.body.appendChild(r),r.click(),document.body.removeChild(r),URL.revokeObjectURL(a)}async function ce(e){const t=await se(e);le(t,e.filename)}function Te(){const e=m(h=>h.voucherConfig.language),t=m(h=>h.voucherConfig.hours),a=m(h=>h.voucherConfig.description),r=m(h=>h.personalInfo),o=m(h=>h.portrait),s=m(h=>h.isExporting),l=m(h=>h.setIsExporting),d=E(e),i=q(e,t),c=O(e),g=o.useEnhanced&&o.enhanced?o.enhanced:o.original,p=K(e,t,a),f=r.name.trim().length>0&&r.email.trim().length>0&&r.phone.trim().length>0&&o.original!==null,x=async()=>{if(!(!f||s)){l(!0);try{const h=`zeitgutschein-${t}h-${r.name.replace(/\s+/g,"-").toLowerCase()}.pdf`;await ce({frontTemplateSrc:i.front,backTemplateSrc:i.back,templateWidth:i.width,templateHeight:i.height,layout:c,portrait:g,portraitZoom:o.zoom,name:r.name,email:r.email,phone:r.phone,description:p,filename:h})}catch(h){console.error("PDF export failed:",h)}finally{l(!1)}}};return n.jsx("button",{className:`btn btn-primary flex-1 ${s?"loading":""}`,onClick:x,disabled:!f||s,children:s?n.jsxs(n.Fragment,{children:[n.jsx("span",{className:"loading loading-spinner loading-sm"}),d.export.exporting]}):n.jsxs(n.Fragment,{children:[n.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:n.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"})}),d.export.button]})})}function de(){const e=m(r=>r.voucherConfig.language),t=m(r=>r.setLanguage),a=r=>{t(r)};return n.jsxs("div",{className:"join",children:[n.jsx("button",{className:`join-item btn btn-sm ${e==="de"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>a("de"),children:"DE"}),n.jsx("button",{className:`join-item btn btn-sm ${e==="en"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>a("en"),children:"EN"})]})}function Le(){const e=m(a=>a.voucherConfig.language),t=E(e);return n.jsxs("div",{className:"navbar bg-currency-green text-currency-cream shadow-lg",children:[n.jsx("div",{className:"navbar-start",children:n.jsx("a",{className:"btn btn-ghost text-xl font-currency font-bold",children:t.header.title})}),n.jsx("div",{className:"navbar-center hidden sm:flex",children:n.jsx("span",{className:"text-sm opacity-80",children:t.header.subtitle})}),n.jsx("div",{className:"navbar-end",children:n.jsx(de,{})})]})}const R="/",Ae={id:"time-voucher-classic-de",name:"Zeitgutschein Classic",type:"time-voucher",category:"classic",images:{front:`${R}templates/front_hdpi_de.jpg`,back:`${R}templates/back_hdpi_de.jpg`,width:6144,height:4096},fields:[{id:"name",type:"text",label:{de:"Name",en:"Name"},required:!0,validation:{minLength:1,maxLength:50}},{id:"hours",type:"select",label:{de:"Stunden",en:"Hours"},required:!0,options:["1","5","10"]},{id:"portrait",type:"image",label:{de:"Portrait",en:"Portrait"},required:!1},{id:"email",type:"text",label:{de:"E-Mail",en:"Email"},required:!1},{id:"phone",type:"text",label:{de:"Telefon",en:"Phone"},required:!1},{id:"description",type:"textarea",label:{de:"Beschreibung",en:"Description"},required:!1,validation:{maxLength:200}}],layout:{front:{portrait:C.front.portrait,name:C.front.namePlate},back:{name:C.back.namePlate,contactInfo:C.back.contactInfo,description:C.back.description}},languages:["de"]},_e={id:"time-voucher-classic-en",name:"Time Voucher Classic",type:"time-voucher",category:"classic",images:{front:`${R}templates/front_ldpi_en.png`,back:`${R}templates/back_ldpi_en.png`,width:1536,height:1024},fields:[{id:"name",type:"text",label:{de:"Name",en:"Name"},required:!0,validation:{minLength:1,maxLength:50}},{id:"hours",type:"select",label:{de:"Stunden",en:"Hours"},required:!0,options:["1","5","10"]},{id:"portrait",type:"image",label:{de:"Portrait",en:"Portrait"},required:!1},{id:"email",type:"text",label:{de:"E-Mail",en:"Email"},required:!1},{id:"phone",type:"text",label:{de:"Telefon",en:"Phone"},required:!1},{id:"description",type:"textarea",label:{de:"Beschreibung",en:"Description"},required:!1,validation:{maxLength:200}}],layout:{front:{portrait:N.front.portrait,name:N.front.namePlate},back:{name:N.back.namePlate,contactInfo:N.back.contactInfo,description:N.back.description}},languages:["en"]},Q=[Ae,_e],ue={async listTemplates(e){let t=[...Q];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},async getTemplate(e){const t=Q.find(a=>a.id===e);if(!t)throw new Error(`Template not found: ${e}`);return t}};function De(e){return e==="de"?"time-voucher-classic-de":"time-voucher-classic-en"}let B=ue;function Re(e){B=e}function Be(){return B}async function $e(e){return B.listTemplates(e)}async function Ue(e){return B.getTemplate(e)}exports.ApiKeyModal=ne;exports.BillPreview=Ee;exports.ExportButton=Te;exports.Header=Le;exports.LAYOUT_HDPI=C;exports.LAYOUT_LDPI=N;exports.LanguageToggle=de;exports.PersonalInfoForm=we;exports.PortraitUpload=Ne;exports.TEMPLATES=ae;exports.VoucherConfig=Ce;exports.downloadBlob=le;exports.drawContactInfo=ie;exports.drawMultilineText=oe;exports.drawOvalPortrait=re;exports.drawTemplate=Y;exports.drawText=V;exports.enhancePortrait=te;exports.enhancePortraitFallback=H;exports.exportBillAsPDF=ce;exports.formatDescription=K;exports.generateBillPDF=se;exports.getApiKey=W;exports.getDefaultTemplateId=De;exports.getLayout=O;exports.getTemplate=q;exports.getTemplateById=Ue;exports.getTemplateProvider=Be;exports.hasApiKey=M;exports.listTemplates=$e;exports.loadImage=D;exports.renderBackSide=G;exports.renderFrontSide=Z;exports.setApiKey=ee;exports.setTemplateProvider=Re;exports.staticTemplateProvider=ue;exports.t=E;exports.useBillCanvasRefs=Se;exports.useBillStore=m;
package/dist/index.d.ts CHANGED
@@ -374,7 +374,7 @@ voucherConfig: VoucherConfigType;
374
374
  };
375
375
  }>;
376
376
 
377
- export declare function VoucherConfig(): JSX.Element;
377
+ export declare function VoucherConfig(): null;
378
378
 
379
379
  export declare interface VoucherConfigType {
380
380
  hours: HourValue;
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
- import { jsxs as h, jsx as o, Fragment as z } from "react/jsx-runtime";
1
+ import { jsxs as m, jsx as o, Fragment as z } from "react/jsx-runtime";
2
2
  import { create as le } from "zustand";
3
3
  import { persist as se } from "zustand/middleware";
4
- import { useState as C, useCallback as E, useRef as _, useEffect as O } from "react";
4
+ import { useState as C, useCallback as E, useRef as A, useEffect as O } from "react";
5
5
  import ce from "jspdf";
6
- const V = {
6
+ const Y = {
7
7
  personalInfo: {
8
8
  name: "",
9
9
  email: "",
@@ -26,7 +26,7 @@ const V = {
26
26
  }, g = le()(
27
27
  se(
28
28
  (e) => ({
29
- ...V,
29
+ ...Y,
30
30
  setPersonalInfo: (t) => e((n) => ({
31
31
  personalInfo: { ...n.personalInfo, ...t }
32
32
  })),
@@ -72,7 +72,7 @@ const V = {
72
72
  setHours: (t) => e((n) => ({
73
73
  voucherConfig: { ...n.voucherConfig, hours: t }
74
74
  })),
75
- reset: () => e(V)
75
+ reset: () => e(Y)
76
76
  }),
77
77
  {
78
78
  name: "money-generator-storage",
@@ -177,19 +177,19 @@ const V = {
177
177
  descriptionText: "This voucher entitles you to {hours} {hourLabel} of my time or an equivalent thank you"
178
178
  }
179
179
  }, pe = { de, en: he };
180
- function S(e) {
180
+ function _(e) {
181
181
  return pe[e];
182
182
  }
183
183
  function G(e, t, n) {
184
184
  if (n && n.trim())
185
185
  return n;
186
- const a = S(e), r = t === 1 ? a.form.voucher.hourLabel : a.form.voucher.hoursLabel;
186
+ const a = _(e), r = t === 1 ? a.form.voucher.hourLabel : a.form.voucher.hoursLabel;
187
187
  return a.bill.descriptionText.replace("{hours}", t.toString()).replace("{hourLabel}", r);
188
188
  }
189
- function Be() {
190
- const e = g((r) => r.voucherConfig.language), t = g((r) => r.personalInfo), n = g((r) => r.setPersonalInfo), a = S(e);
191
- return /* @__PURE__ */ h("div", { className: "space-y-4", children: [
192
- /* @__PURE__ */ h("div", { className: "form-control", children: [
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
193
  /* @__PURE__ */ o("label", { className: "label", children: /* @__PURE__ */ o("span", { className: "label-text font-medium", children: a.form.personalInfo.name }) }),
194
194
  /* @__PURE__ */ o(
195
195
  "input",
@@ -202,7 +202,7 @@ function Be() {
202
202
  }
203
203
  )
204
204
  ] }),
205
- /* @__PURE__ */ h("div", { className: "form-control", children: [
205
+ /* @__PURE__ */ m("div", { className: "form-control", children: [
206
206
  /* @__PURE__ */ o("label", { className: "label", children: /* @__PURE__ */ o("span", { className: "label-text font-medium", children: a.form.personalInfo.email }) }),
207
207
  /* @__PURE__ */ o(
208
208
  "input",
@@ -215,7 +215,7 @@ function Be() {
215
215
  }
216
216
  )
217
217
  ] }),
218
- /* @__PURE__ */ h("div", { className: "form-control", children: [
218
+ /* @__PURE__ */ m("div", { className: "form-control", children: [
219
219
  /* @__PURE__ */ o("label", { className: "label", children: /* @__PURE__ */ o("span", { className: "label-text font-medium", children: a.form.personalInfo.phone }) }),
220
220
  /* @__PURE__ */ o(
221
221
  "input",
@@ -230,17 +230,17 @@ function Be() {
230
230
  ] })
231
231
  ] });
232
232
  }
233
- const F = {}, me = "https://api.stability.ai/v1/generation", ue = {
233
+ const F = {}, ue = "https://api.stability.ai/v1/generation", me = {
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
237
  };
238
238
  function ge(e) {
239
- var i;
240
- const t = e.split(","), n = ((i = t[0].match(/:(.*?);/)) == null ? void 0 : i[1]) || "image/png", a = atob(t[1]), r = a.length, s = new Uint8Array(r);
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
241
  for (let d = 0; d < r; d++)
242
- s[d] = a.charCodeAt(d);
243
- return new Blob([s], { type: n });
242
+ l[d] = a.charCodeAt(d);
243
+ return new Blob([l], { type: n });
244
244
  }
245
245
  function X() {
246
246
  var t;
@@ -250,68 +250,68 @@ function X() {
250
250
  function fe(e) {
251
251
  localStorage.setItem("stability_api_key", e);
252
252
  }
253
- function Y() {
253
+ function q() {
254
254
  return X() !== null;
255
255
  }
256
256
  async function be(e) {
257
257
  const t = X();
258
258
  if (!t)
259
259
  throw new Error("No Stability AI API key configured");
260
- const { imageDataUrl: n, style: a, strength: r = 0.35 } = e, s = ge(n), i = new FormData();
261
- i.append("init_image", s, "portrait.png"), i.append("init_image_mode", "IMAGE_STRENGTH"), i.append("image_strength", String(1 - r)), i.append("text_prompts[0][text]", ue[a]), i.append("text_prompts[0][weight]", "1"), i.append("cfg_scale", "7"), i.append("samples", "1"), i.append("steps", "30");
262
- const l = await fetch(`${me}/stable-diffusion-xl-1024-v1-0/image-to-image`, {
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`, {
263
263
  method: "POST",
264
264
  headers: {
265
265
  Authorization: `Bearer ${t}`,
266
266
  Accept: "application/json"
267
267
  },
268
- body: i
268
+ body: s
269
269
  });
270
- if (!l.ok) {
271
- const f = await l.text();
272
- throw console.error("Stability AI error:", f), l.status === 401 ? new Error("Invalid API key") : l.status === 402 ? new Error("Insufficient credits") : l.status === 429 ? new Error("Rate limit exceeded. Please try again later.") : new Error(`API error: ${l.status}`);
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}`);
273
273
  }
274
- const c = await l.json();
274
+ const c = await i.json();
275
275
  if (!c.artifacts || c.artifacts.length === 0)
276
276
  throw new Error("No image generated");
277
277
  return `data:image/png;base64,${c.artifacts[0].base64}`;
278
278
  }
279
- async function q(e) {
279
+ async function V(e) {
280
280
  return new Promise((t, n) => {
281
281
  const a = new Image();
282
282
  a.onload = () => {
283
- const r = document.createElement("canvas"), s = r.getContext("2d");
284
- if (!s) {
283
+ const r = document.createElement("canvas"), l = r.getContext("2d");
284
+ if (!l) {
285
285
  n(new Error("Failed to get canvas context"));
286
286
  return;
287
287
  }
288
- r.width = a.width, r.height = a.height, s.filter = "sepia(0.3) contrast(1.1) saturate(0.9)", s.drawImage(a, 0, 0), t(r.toDataURL("image/png"));
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
289
  }, a.onerror = () => n(new Error("Failed to load image")), a.src = e;
290
290
  });
291
291
  }
292
- function ve() {
293
- const [e, t] = C(!1), [n, a] = C(null), [r, s] = C(Y()), i = E(() => a(null), []), d = E((c) => {
294
- fe(c), s(!0), a(null);
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
295
  }, []);
296
296
  return {
297
297
  enhance: E(
298
298
  async (c, f = "vintage") => {
299
299
  t(!0), a(null);
300
300
  try {
301
- return Y() ? await be({
301
+ return q() ? await be({
302
302
  imageDataUrl: c,
303
303
  style: f,
304
304
  strength: 0.35
305
- }) : await q(c);
306
- } catch (m) {
307
- const b = m instanceof Error ? m.message : "Enhancement failed";
305
+ }) : await V(c);
306
+ } catch (p) {
307
+ const b = p instanceof Error ? p.message : "Enhancement failed";
308
308
  if (a(b), b.includes("API") || b.includes("key"))
309
309
  try {
310
- return await q(c);
310
+ return await V(c);
311
311
  } catch {
312
- throw m;
312
+ throw p;
313
313
  }
314
- throw m;
314
+ throw p;
315
315
  } finally {
316
316
  t(!1);
317
317
  }
@@ -322,15 +322,15 @@ function ve() {
322
322
  error: n,
323
323
  hasKey: r,
324
324
  setApiKey: d,
325
- clearError: i
325
+ clearError: s
326
326
  };
327
327
  }
328
- function ye({ isOpen: e, onClose: t, onSubmit: n }) {
329
- const a = g((c) => c.voucherConfig.language), [r, s] = C("");
328
+ function ve({ isOpen: e, onClose: t, onSubmit: n }) {
329
+ const a = g((c) => c.voucherConfig.language), [r, l] = C("");
330
330
  if (!e) return null;
331
- const i = (c) => {
332
- c.preventDefault(), r.trim() && (n(r.trim()), s(""), t());
333
- }, l = {
331
+ const s = (c) => {
332
+ c.preventDefault(), r.trim() && (n(r.trim()), l(""), t());
333
+ }, i = {
334
334
  de: {
335
335
  title: "Stability AI API Key",
336
336
  description: "Um die AI-Bildverbesserung zu nutzen, benötigst du einen Stability AI API Key. Du kannst ihn auf platform.stability.ai erhalten.",
@@ -348,28 +348,28 @@ function ye({ isOpen: e, onClose: t, onSubmit: n }) {
348
348
  hint: "The key is stored locally in your browser."
349
349
  }
350
350
  }[a];
351
- return /* @__PURE__ */ h("dialog", { className: "modal modal-open", children: [
352
- /* @__PURE__ */ h("div", { className: "modal-box", children: [
353
- /* @__PURE__ */ o("h3", { className: "font-bold text-lg", children: l.title }),
354
- /* @__PURE__ */ o("p", { className: "py-4 text-sm opacity-80", children: l.description }),
355
- /* @__PURE__ */ h("form", { onSubmit: i, children: [
356
- /* @__PURE__ */ h("div", { className: "form-control", children: [
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
357
  /* @__PURE__ */ o(
358
358
  "input",
359
359
  {
360
360
  type: "password",
361
- placeholder: l.placeholder,
361
+ placeholder: i.placeholder,
362
362
  className: "input input-bordered w-full",
363
363
  value: r,
364
- onChange: (c) => s(c.target.value),
364
+ onChange: (c) => l(c.target.value),
365
365
  autoFocus: !0
366
366
  }
367
367
  ),
368
- /* @__PURE__ */ o("label", { className: "label", children: /* @__PURE__ */ o("span", { className: "label-text-alt", children: l.hint }) })
368
+ /* @__PURE__ */ o("label", { className: "label", children: /* @__PURE__ */ o("span", { className: "label-text-alt", children: i.hint }) })
369
369
  ] }),
370
- /* @__PURE__ */ h("div", { className: "modal-action", children: [
371
- /* @__PURE__ */ o("button", { type: "button", className: "btn btn-ghost", onClick: t, children: l.cancel }),
372
- /* @__PURE__ */ o("button", { type: "submit", className: "btn btn-primary", disabled: !r.trim(), children: l.submit })
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 })
373
373
  ] })
374
374
  ] })
375
375
  ] }),
@@ -377,53 +377,53 @@ function ye({ isOpen: e, onClose: t, onSubmit: n }) {
377
377
  ] });
378
378
  }
379
379
  function Re() {
380
- const e = g((p) => p.voucherConfig.language), t = g((p) => p.portrait), n = g((p) => p.setPortrait), a = g((p) => p.setEnhancedPortrait), r = g((p) => p.toggleUseEnhanced), s = g((p) => p.setPortraitZoom), { enhance: i, isEnhancing: d, error: l, hasKey: c, setApiKey: f } = ve(), m = S(e), b = _(null), [y, u] = C(!1), [P, N] = C(!1), k = E(
381
- (p) => {
382
- if (!p.type.startsWith("image/"))
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/"))
383
383
  return;
384
384
  const w = new FileReader();
385
- w.onload = (H) => {
385
+ w.onload = (B) => {
386
386
  var K;
387
- const ie = (K = H.target) == null ? void 0 : K.result;
387
+ const ie = (K = B.target) == null ? void 0 : K.result;
388
388
  n(ie);
389
- }, w.readAsDataURL(p);
389
+ }, w.readAsDataURL(h);
390
390
  },
391
391
  [n]
392
- ), L = E(
393
- (p) => {
394
- p.preventDefault(), u(!1);
395
- const w = p.dataTransfer.files[0];
392
+ ), S = E(
393
+ (h) => {
394
+ h.preventDefault(), u(!1);
395
+ const w = h.dataTransfer.files[0];
396
396
  w && k(w);
397
397
  },
398
398
  [k]
399
- ), v = E((p) => {
400
- p.preventDefault(), u(!0);
401
- }, []), I = E((p) => {
402
- p.preventDefault(), u(!1);
399
+ ), y = E((h) => {
400
+ h.preventDefault(), u(!0);
401
+ }, []), P = E((h) => {
402
+ h.preventDefault(), u(!1);
403
403
  }, []), D = () => {
404
- var p;
405
- (p = b.current) == null || p.click();
406
- }, $ = (p) => {
407
- var H;
408
- const w = (H = p.target.files) == null ? void 0 : H[0];
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
409
  w && k(w);
410
410
  }, M = async () => {
411
411
  if (t.original) {
412
412
  if (!c) {
413
- N(!0);
413
+ I(!0);
414
414
  return;
415
415
  }
416
416
  try {
417
- const p = await i(t.original, "vintage");
418
- a(p);
419
- } catch (p) {
420
- console.error("Enhancement failed:", p);
417
+ const h = await s(t.original, "vintage");
418
+ a(h);
419
+ } catch (h) {
420
+ console.error("Enhancement failed:", h);
421
421
  }
422
422
  }
423
- }, U = async (p) => {
424
- if (f(p), t.original)
423
+ }, U = async (h) => {
424
+ if (f(h), t.original)
425
425
  try {
426
- const w = await i(t.original, "vintage");
426
+ const w = await s(t.original, "vintage");
427
427
  a(w);
428
428
  } catch (w) {
429
429
  console.error("Enhancement failed:", w);
@@ -431,9 +431,9 @@ function Re() {
431
431
  }, re = () => {
432
432
  n(null);
433
433
  }, oe = t.useEnhanced && t.enhanced ? t.enhanced : t.original;
434
- return /* @__PURE__ */ h("div", { className: "space-y-4", children: [
435
- t.original ? /* @__PURE__ */ h("div", { className: "space-y-4", children: [
436
- /* @__PURE__ */ o("div", { className: "flex justify-center", children: /* @__PURE__ */ h("div", { className: "relative", children: [
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
437
  /* @__PURE__ */ o("div", { className: "w-32 h-32 rounded-full overflow-hidden border-4 border-currency-gold shadow-lg", children: /* @__PURE__ */ o(
438
438
  "img",
439
439
  {
@@ -470,10 +470,10 @@ function Re() {
470
470
  }
471
471
  )
472
472
  ] }) }),
473
- /* @__PURE__ */ h("div", { className: "form-control", children: [
474
- /* @__PURE__ */ h("label", { className: "label", children: [
475
- /* @__PURE__ */ o("span", { className: "label-text", children: m.form.portrait.zoom }),
476
- /* @__PURE__ */ h("span", { className: "label-text-alt", children: [
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: [
477
477
  Math.round(t.zoom * 100),
478
478
  "%"
479
479
  ] })
@@ -486,22 +486,22 @@ function Re() {
486
486
  max: "2",
487
487
  step: "0.05",
488
488
  value: t.zoom,
489
- onChange: (p) => s(parseFloat(p.target.value)),
489
+ onChange: (h) => l(parseFloat(h.target.value)),
490
490
  className: "range range-primary range-sm"
491
491
  }
492
492
  )
493
493
  ] }),
494
- c && /* @__PURE__ */ h("div", { className: "flex flex-col gap-2", children: [
494
+ c && /* @__PURE__ */ m("div", { className: "flex flex-col gap-2", children: [
495
495
  /* @__PURE__ */ o(
496
496
  "button",
497
497
  {
498
498
  className: `btn btn-secondary ${d ? "loading" : ""}`,
499
499
  onClick: M,
500
500
  disabled: d,
501
- children: d ? /* @__PURE__ */ h(z, { children: [
501
+ children: d ? /* @__PURE__ */ m(z, { children: [
502
502
  /* @__PURE__ */ o("span", { className: "loading loading-spinner loading-sm" }),
503
- m.form.portrait.enhancing
504
- ] }) : /* @__PURE__ */ h(z, { children: [
503
+ p.form.portrait.enhancing
504
+ ] }) : /* @__PURE__ */ m(z, { children: [
505
505
  /* @__PURE__ */ o(
506
506
  "svg",
507
507
  {
@@ -521,15 +521,15 @@ function Re() {
521
521
  )
522
522
  }
523
523
  ),
524
- m.form.portrait.enhance
524
+ p.form.portrait.enhance
525
525
  ] })
526
526
  }
527
527
  ),
528
- l && /* @__PURE__ */ h("div", { className: "alert alert-warning text-sm py-2", children: [
528
+ i && /* @__PURE__ */ m("div", { className: "alert alert-warning text-sm py-2", children: [
529
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: l })
530
+ /* @__PURE__ */ o("span", { children: i })
531
531
  ] }),
532
- t.enhanced && /* @__PURE__ */ o("div", { className: "form-control", children: /* @__PURE__ */ h("label", { className: "label cursor-pointer justify-start gap-3", children: [
532
+ t.enhanced && /* @__PURE__ */ o("div", { className: "form-control", children: /* @__PURE__ */ m("label", { className: "label cursor-pointer justify-start gap-3", children: [
533
533
  /* @__PURE__ */ o(
534
534
  "input",
535
535
  {
@@ -539,16 +539,16 @@ function Re() {
539
539
  onChange: r
540
540
  }
541
541
  ),
542
- /* @__PURE__ */ o("span", { className: "label-text", children: t.useEnhanced ? m.form.portrait.useEnhanced : m.form.portrait.useOriginal })
542
+ /* @__PURE__ */ o("span", { className: "label-text", children: t.useEnhanced ? p.form.portrait.useEnhanced : p.form.portrait.useOriginal })
543
543
  ] }) })
544
544
  ] })
545
- ] }) : /* @__PURE__ */ h(
545
+ ] }) : /* @__PURE__ */ m(
546
546
  "div",
547
547
  {
548
- className: `border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${y ? "border-primary bg-primary/10" : "border-base-300 hover:border-primary hover:bg-base-200"}`,
549
- onDrop: L,
550
- onDragOver: v,
551
- onDragLeave: I,
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
552
  onClick: D,
553
553
  children: [
554
554
  /* @__PURE__ */ o(
@@ -561,7 +561,7 @@ function Re() {
561
561
  onChange: $
562
562
  }
563
563
  ),
564
- /* @__PURE__ */ h("div", { className: "flex flex-col items-center gap-2", children: [
564
+ /* @__PURE__ */ m("div", { className: "flex flex-col items-center gap-2", children: [
565
565
  /* @__PURE__ */ o(
566
566
  "svg",
567
567
  {
@@ -581,65 +581,26 @@ function Re() {
581
581
  )
582
582
  }
583
583
  ),
584
- /* @__PURE__ */ o("p", { className: "font-medium", children: m.form.portrait.upload }),
585
- /* @__PURE__ */ o("p", { className: "text-sm text-base-content/60", children: m.form.portrait.dragDrop })
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 })
586
586
  ] })
587
587
  ]
588
588
  }
589
589
  ),
590
590
  /* @__PURE__ */ o(
591
- ye,
591
+ ve,
592
592
  {
593
- isOpen: P,
594
- onClose: () => N(!1),
593
+ isOpen: N,
594
+ onClose: () => I(!1),
595
595
  onSubmit: U
596
596
  }
597
597
  )
598
598
  ] });
599
599
  }
600
- const we = [1, 5, 10];
601
- function Me() {
602
- const e = g((i) => i.voucherConfig.language), t = g((i) => i.voucherConfig), n = g((i) => i.setHours), a = g((i) => i.setVoucherConfig), r = S(e), s = (i) => i === 1 ? r.form.voucher.hourLabel : r.form.voucher.hoursLabel;
603
- return /* @__PURE__ */ h("div", { className: "space-y-4", children: [
604
- /* @__PURE__ */ h("div", { className: "form-control", children: [
605
- /* @__PURE__ */ o("label", { className: "label", children: /* @__PURE__ */ o("span", { className: "label-text font-medium", children: r.form.voucher.hours }) }),
606
- /* @__PURE__ */ o("div", { className: "join w-full", children: we.map((i) => /* @__PURE__ */ h(
607
- "button",
608
- {
609
- className: `join-item btn flex-1 ${t.hours === i ? "btn-primary" : "btn-outline"}`,
610
- onClick: () => n(i),
611
- children: [
612
- i,
613
- " ",
614
- s(i)
615
- ]
616
- },
617
- i
618
- )) })
619
- ] }),
620
- /* @__PURE__ */ h("div", { className: "form-control", children: [
621
- /* @__PURE__ */ o("label", { className: "label", children: /* @__PURE__ */ o("span", { className: "label-text font-medium", children: r.form.voucher.description }) }),
622
- /* @__PURE__ */ o(
623
- "textarea",
624
- {
625
- className: "textarea textarea-bordered h-24 resize-none w-full",
626
- placeholder: r.form.voucher.descriptionPlaceholder,
627
- value: t.description,
628
- onChange: (i) => a({ description: i.target.value }),
629
- maxLength: 200
630
- }
631
- ),
632
- /* @__PURE__ */ h("label", { className: "label", children: [
633
- /* @__PURE__ */ o("span", { className: "label-text-alt" }),
634
- /* @__PURE__ */ h("span", { className: "label-text-alt", children: [
635
- t.description.length,
636
- "/200"
637
- ] })
638
- ] })
639
- ] })
640
- ] });
600
+ function He() {
601
+ return null;
641
602
  }
642
- const x = typeof import.meta < "u" && "/" || "/", xe = {
603
+ const x = typeof import.meta < "u" && "/" || "/", we = {
643
604
  en: {
644
605
  1: {
645
606
  front: `${x}templates/front_ldpi_en.png`,
@@ -726,7 +687,7 @@ const x = typeof import.meta < "u" && "/" || "/", xe = {
726
687
  align: "center"
727
688
  }
728
689
  }
729
- }, A = {
690
+ }, L = {
730
691
  front: {
731
692
  portrait: {
732
693
  x: 3074,
@@ -774,10 +735,10 @@ const x = typeof import.meta < "u" && "/" || "/", xe = {
774
735
  }
775
736
  };
776
737
  function J(e) {
777
- return e === "de" ? A : T;
738
+ return e === "de" ? L : T;
778
739
  }
779
740
  function Q(e, t) {
780
- return xe[e][t];
741
+ return we[e][t];
781
742
  }
782
743
  const W = /* @__PURE__ */ new Map();
783
744
  async function j(e) {
@@ -791,50 +752,50 @@ async function j(e) {
791
752
  function ee(e, t, n, a) {
792
753
  e.drawImage(t, 0, 0, n, a);
793
754
  }
794
- function ke(e, t, n, a, r, s, i = 1) {
795
- e.save(), e.beginPath(), e.ellipse(n, a, r, s, 0, 0, Math.PI * 2), e.closePath(), e.clip();
796
- const d = t.width / t.height, l = r / s, c = r * 2, f = s * 2;
797
- let m, b;
798
- d > l ? (b = f, m = f * d) : (m = c, b = c / d), m *= i, b *= i;
799
- const y = n - m / 2, u = a - b / 2;
800
- e.drawImage(t, y, u, m, b), e.restore();
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();
801
762
  }
802
763
  function te(e, t, n, a = "#2a3a2a") {
803
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();
804
765
  }
805
- function Ne(e, t, n, a = "#2a3a2a") {
766
+ function ke(e, t, n, a = "#2a3a2a") {
806
767
  e.save(), e.font = `${n.fontSize}px "Times New Roman", serif`, e.textAlign = n.align || "center", e.textBaseline = "top", e.fillStyle = a;
807
- const r = n.maxWidth || 400, s = n.lineHeight || n.fontSize * 1.4, i = t.split(" "), d = [];
808
- let l = "";
809
- for (const m of i) {
810
- const b = l ? `${l} ${m}` : m;
811
- e.measureText(b).width > r && l ? (d.push(l), l = m) : l = b;
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;
812
773
  }
813
- l && d.push(l);
814
- const c = d.length * s;
774
+ i && d.push(i);
775
+ const c = d.length * l;
815
776
  let f = n.y - c / 2;
816
- for (const m of d)
817
- e.fillText(m, n.x, f), f += s;
777
+ for (const p of d)
778
+ e.fillText(p, n.x, f), f += l;
818
779
  e.restore();
819
780
  }
820
- function Ie(e, t, n, a, r, s = "#2a3a2a") {
821
- e.save(), e.font = `${r.fontSize}px "Times New Roman", serif`, e.textAlign = r.align || "center", e.textBaseline = "middle", e.fillStyle = s;
822
- const i = r.lineHeight || r.fontSize * 1.8, d = [t, n, a].filter(Boolean), l = (d.length - 1) * i;
823
- let c = r.y - l / 2;
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;
824
785
  for (const f of d)
825
- f && (e.fillText(f, r.x, c), c += i);
786
+ f && (e.fillText(f, r.x, c), c += s);
826
787
  e.restore();
827
788
  }
828
- async function ne(e, t, n, a, r, s, i, d = 1) {
829
- const l = e.getContext("2d");
830
- if (!l) return;
831
- e.width = s, e.height = i, l.clearRect(0, 0, s, i);
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);
832
793
  const c = await j(t);
833
- if (ee(l, c, s, i), n)
794
+ if (ee(i, c, l, s), n)
834
795
  try {
835
796
  const f = await j(n);
836
- ke(
837
- l,
797
+ xe(
798
+ i,
838
799
  f,
839
800
  r.portrait.x,
840
801
  r.portrait.y,
@@ -845,67 +806,67 @@ async function ne(e, t, n, a, r, s, i, d = 1) {
845
806
  } catch (f) {
846
807
  console.error("Failed to load portrait:", f);
847
808
  }
848
- a && te(l, a, r.namePlate);
809
+ a && te(i, a, r.namePlate);
849
810
  }
850
- async function ae(e, t, n, a, r, s, i, d, l) {
811
+ async function ae(e, t, n, a, r, l, s, d, i) {
851
812
  const c = e.getContext("2d");
852
813
  if (!c) return;
853
- e.width = d, e.height = l, c.clearRect(0, 0, d, l);
814
+ e.width = d, e.height = i, c.clearRect(0, 0, d, i);
854
815
  const f = await j(t);
855
- ee(c, f, d, l), i.contactInfo && (n || a || r) && Ie(c, n, a, r, i.contactInfo), i.description && s && Ne(c, s, i.description), n && te(c, n, i.namePlate);
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);
856
817
  }
857
- function Ue() {
858
- const e = g((v) => v.voucherConfig.language), t = g((v) => v.voucherConfig.hours), n = g((v) => v.voucherConfig.description), a = g((v) => v.personalInfo), r = g((v) => v.portrait), s = g((v) => v.currentSide), i = g((v) => v.flipSide), d = S(e), l = _(null), c = _(null), f = _(null), [m, b] = C(!1), y = Q(e, t), u = J(e), P = r.useEnhanced && r.enhanced ? r.enhanced : r.original, N = G(e, t, n);
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);
859
820
  O(() => {
860
- l.current && ne(
861
- l.current,
862
- y.front,
863
- P,
821
+ i.current && ne(
822
+ i.current,
823
+ v.front,
824
+ N,
864
825
  a.name,
865
826
  u.front,
866
- y.width,
867
- y.height,
827
+ v.width,
828
+ v.height,
868
829
  r.zoom
869
830
  );
870
- }, [y, P, a.name, u, r.zoom]), O(() => {
831
+ }, [v, N, a.name, u, r.zoom]), O(() => {
871
832
  c.current && ae(
872
833
  c.current,
873
- y.back,
834
+ v.back,
874
835
  a.name,
875
836
  a.email,
876
837
  a.phone,
877
- N,
838
+ I,
878
839
  u.back,
879
- y.width,
880
- y.height
840
+ v.width,
841
+ v.height
881
842
  );
882
- }, [y, a, N, u]);
843
+ }, [v, a, I, u]);
883
844
  const k = () => {
884
845
  b(!0), setTimeout(() => {
885
- i(), b(!1);
846
+ s(), b(!1);
886
847
  }, 150);
887
- }, L = y.width / y.height;
888
- return /* @__PURE__ */ h("div", { className: "space-y-4", children: [
889
- /* @__PURE__ */ h("div", { className: "flex justify-between items-center", children: [
890
- /* @__PURE__ */ h("div", { className: "tabs tabs-boxed bg-base-200", children: [
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: [
891
852
  /* @__PURE__ */ o(
892
853
  "button",
893
854
  {
894
- className: `tab ${s === "front" ? "tab-active bg-primary text-primary-content font-semibold" : ""}`,
895
- onClick: () => s !== "front" && k(),
855
+ className: `tab ${l === "front" ? "tab-active bg-primary text-primary-content font-semibold" : ""}`,
856
+ onClick: () => l !== "front" && k(),
896
857
  children: d.preview.front
897
858
  }
898
859
  ),
899
860
  /* @__PURE__ */ o(
900
861
  "button",
901
862
  {
902
- className: `tab ${s === "back" ? "tab-active bg-primary text-primary-content font-semibold" : ""}`,
903
- onClick: () => s !== "back" && k(),
863
+ className: `tab ${l === "back" ? "tab-active bg-primary text-primary-content font-semibold" : ""}`,
864
+ onClick: () => l !== "back" && k(),
904
865
  children: d.preview.back
905
866
  }
906
867
  )
907
868
  ] }),
908
- /* @__PURE__ */ h("button", { className: "btn btn-ghost btn-sm", onClick: k, children: [
869
+ /* @__PURE__ */ m("button", { className: "btn btn-ghost btn-sm", onClick: k, children: [
909
870
  /* @__PURE__ */ o(
910
871
  "svg",
911
872
  {
@@ -928,25 +889,25 @@ function Ue() {
928
889
  d.preview.flip
929
890
  ] })
930
891
  ] }),
931
- /* @__PURE__ */ h(
892
+ /* @__PURE__ */ m(
932
893
  "div",
933
894
  {
934
895
  ref: f,
935
896
  className: "relative w-full overflow-hidden shadow-lg",
936
- style: { aspectRatio: L },
897
+ style: { aspectRatio: S },
937
898
  children: [
938
899
  /* @__PURE__ */ o(
939
900
  "canvas",
940
901
  {
941
- ref: l,
942
- className: `absolute inset-0 w-full h-full transition-all duration-300 ${s === "front" ? m ? "opacity-0 scale-95" : "opacity-100 scale-100" : "opacity-0 scale-95 pointer-events-none"}`
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"}`
943
904
  }
944
905
  ),
945
906
  /* @__PURE__ */ o(
946
907
  "canvas",
947
908
  {
948
909
  ref: c,
949
- className: `absolute inset-0 w-full h-full transition-all duration-300 ${s === "back" ? m ? "opacity-0 scale-95" : "opacity-100 scale-100" : "opacity-0 scale-95 pointer-events-none"}`
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"}`
950
911
  }
951
912
  )
952
913
  ]
@@ -954,8 +915,8 @@ function Ue() {
954
915
  )
955
916
  ] });
956
917
  }
957
- function Fe() {
958
- const e = _(null), t = _(null);
918
+ function Ue() {
919
+ const e = A(null), t = A(null);
959
920
  return { frontCanvasRef: e, backCanvasRef: t };
960
921
  }
961
922
  async function Pe(e) {
@@ -964,75 +925,75 @@ async function Pe(e) {
964
925
  backTemplateSrc: n,
965
926
  templateWidth: a,
966
927
  templateHeight: r,
967
- layout: s,
968
- portrait: i,
928
+ layout: l,
929
+ portrait: s,
969
930
  portraitZoom: d = 1,
970
- name: l,
931
+ name: i,
971
932
  email: c,
972
933
  phone: f,
973
- description: m
974
- } = e, b = document.createElement("canvas"), y = document.createElement("canvas");
934
+ description: p
935
+ } = e, b = document.createElement("canvas"), v = document.createElement("canvas");
975
936
  await Promise.all([
976
- ne(b, t, i, l, s.front, a, r, d),
977
- ae(y, n, l, c, f, m, s.back, a, r)
937
+ ne(b, t, s, i, l.front, a, r, d),
938
+ ae(v, n, i, c, f, p, l.back, a, r)
978
939
  ]);
979
940
  const u = new ce({
980
941
  orientation: "landscape",
981
942
  unit: "mm",
982
943
  format: "a4"
983
- }), P = 297, N = 210, k = 10, L = a / r;
984
- let v = P - k * 2, I = v / L;
985
- I > N - k * 2 && (I = N - k * 2, v = I * L);
986
- const D = (P - v) / 2, $ = (N - I) / 2, M = b.toDataURL("image/jpeg", 0.95);
987
- u.addImage(M, "JPEG", D, $, v, I), u.addPage();
988
- const U = y.toDataURL("image/jpeg", 0.95);
989
- return u.addImage(U, "JPEG", D, $, v, I), u.output("blob");
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");
990
951
  }
991
- function Ee(e, t) {
952
+ function Ne(e, t) {
992
953
  const n = URL.createObjectURL(e), a = document.createElement("a");
993
954
  a.href = n, a.download = t, document.body.appendChild(a), a.click(), document.body.removeChild(a), URL.revokeObjectURL(n);
994
955
  }
995
- async function Ce(e) {
956
+ async function Ee(e) {
996
957
  const t = await Pe(e);
997
- Ee(t, e.filename);
958
+ Ne(t, e.filename);
998
959
  }
999
- function We() {
1000
- 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), s = g((u) => u.isExporting), i = g((u) => u.setIsExporting), d = S(e), l = Q(e, t), c = J(e), f = r.useEnhanced && r.enhanced ? r.enhanced : r.original, m = G(e, t, n), b = a.name.trim().length > 0 && a.email.trim().length > 0 && a.phone.trim().length > 0 && r.original !== null;
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;
1001
962
  return /* @__PURE__ */ o(
1002
963
  "button",
1003
964
  {
1004
- className: `btn btn-primary flex-1 ${s ? "loading" : ""}`,
965
+ className: `btn btn-primary flex-1 ${l ? "loading" : ""}`,
1005
966
  onClick: async () => {
1006
- if (!(!b || s)) {
1007
- i(!0);
967
+ if (!(!b || l)) {
968
+ s(!0);
1008
969
  try {
1009
970
  const u = `zeitgutschein-${t}h-${a.name.replace(/\s+/g, "-").toLowerCase()}.pdf`;
1010
- await Ce({
1011
- frontTemplateSrc: l.front,
1012
- backTemplateSrc: l.back,
1013
- templateWidth: l.width,
1014
- templateHeight: l.height,
971
+ await Ee({
972
+ frontTemplateSrc: i.front,
973
+ backTemplateSrc: i.back,
974
+ templateWidth: i.width,
975
+ templateHeight: i.height,
1015
976
  layout: c,
1016
977
  portrait: f,
1017
978
  portraitZoom: r.zoom,
1018
979
  name: a.name,
1019
980
  email: a.email,
1020
981
  phone: a.phone,
1021
- description: m,
982
+ description: p,
1022
983
  filename: u
1023
984
  });
1024
985
  } catch (u) {
1025
986
  console.error("PDF export failed:", u);
1026
987
  } finally {
1027
- i(!1);
988
+ s(!1);
1028
989
  }
1029
990
  }
1030
991
  },
1031
- disabled: !b || s,
1032
- children: s ? /* @__PURE__ */ h(z, { children: [
992
+ disabled: !b || l,
993
+ children: l ? /* @__PURE__ */ m(z, { children: [
1033
994
  /* @__PURE__ */ o("span", { className: "loading loading-spinner loading-sm" }),
1034
995
  d.export.exporting
1035
- ] }) : /* @__PURE__ */ h(z, { children: [
996
+ ] }) : /* @__PURE__ */ m(z, { children: [
1036
997
  /* @__PURE__ */ o(
1037
998
  "svg",
1038
999
  {
@@ -1057,11 +1018,11 @@ function We() {
1057
1018
  }
1058
1019
  );
1059
1020
  }
1060
- function Se() {
1021
+ function Ce() {
1061
1022
  const e = g((a) => a.voucherConfig.language), t = g((a) => a.setLanguage), n = (a) => {
1062
1023
  t(a);
1063
1024
  };
1064
- return /* @__PURE__ */ h("div", { className: "join", children: [
1025
+ return /* @__PURE__ */ m("div", { className: "join", children: [
1065
1026
  /* @__PURE__ */ o(
1066
1027
  "button",
1067
1028
  {
@@ -1080,22 +1041,22 @@ function Se() {
1080
1041
  )
1081
1042
  ] });
1082
1043
  }
1083
- function je() {
1084
- const e = g((n) => n.voucherConfig.language), t = S(e);
1085
- return /* @__PURE__ */ h("div", { className: "navbar bg-currency-green text-currency-cream shadow-lg", children: [
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: [
1086
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 }) }),
1087
1048
  /* @__PURE__ */ o("div", { className: "navbar-center hidden sm:flex", children: /* @__PURE__ */ o("span", { className: "text-sm opacity-80", children: t.header.subtitle }) }),
1088
- /* @__PURE__ */ o("div", { className: "navbar-end", children: /* @__PURE__ */ o(Se, {}) })
1049
+ /* @__PURE__ */ o("div", { className: "navbar-end", children: /* @__PURE__ */ o(Ce, {}) })
1089
1050
  ] });
1090
1051
  }
1091
- const B = "/", Le = {
1052
+ const R = "/", Se = {
1092
1053
  id: "time-voucher-classic-de",
1093
1054
  name: "Zeitgutschein Classic",
1094
1055
  type: "time-voucher",
1095
1056
  category: "classic",
1096
1057
  images: {
1097
- front: `${B}templates/front_hdpi_de.jpg`,
1098
- back: `${B}templates/back_hdpi_de.jpg`,
1058
+ front: `${R}templates/front_hdpi_de.jpg`,
1059
+ back: `${R}templates/back_hdpi_de.jpg`,
1099
1060
  width: 6144,
1100
1061
  height: 4096
1101
1062
  },
@@ -1142,13 +1103,13 @@ const B = "/", Le = {
1142
1103
  ],
1143
1104
  layout: {
1144
1105
  front: {
1145
- portrait: A.front.portrait,
1146
- name: A.front.namePlate
1106
+ portrait: L.front.portrait,
1107
+ name: L.front.namePlate
1147
1108
  },
1148
1109
  back: {
1149
- name: A.back.namePlate,
1150
- contactInfo: A.back.contactInfo,
1151
- description: A.back.description
1110
+ name: L.back.namePlate,
1111
+ contactInfo: L.back.contactInfo,
1112
+ description: L.back.description
1152
1113
  }
1153
1114
  },
1154
1115
  languages: ["de"]
@@ -1158,8 +1119,8 @@ const B = "/", Le = {
1158
1119
  type: "time-voucher",
1159
1120
  category: "classic",
1160
1121
  images: {
1161
- front: `${B}templates/front_ldpi_en.png`,
1162
- back: `${B}templates/back_ldpi_en.png`,
1122
+ front: `${R}templates/front_ldpi_en.png`,
1123
+ back: `${R}templates/back_ldpi_en.png`,
1163
1124
  width: 1536,
1164
1125
  height: 1024
1165
1126
  },
@@ -1217,9 +1178,9 @@ const B = "/", Le = {
1217
1178
  },
1218
1179
  languages: ["en"]
1219
1180
  }, Z = [
1220
- Le,
1181
+ Se,
1221
1182
  Te
1222
- ], Ae = {
1183
+ ], Le = {
1223
1184
  async listTemplates(e) {
1224
1185
  let t = [...Z];
1225
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;
@@ -1231,60 +1192,60 @@ const B = "/", Le = {
1231
1192
  return t;
1232
1193
  }
1233
1194
  };
1234
- function Ke(e) {
1195
+ function je(e) {
1235
1196
  return e === "de" ? "time-voucher-classic-de" : "time-voucher-classic-en";
1236
1197
  }
1237
- let R = Ae;
1238
- function Oe(e) {
1239
- R = e;
1198
+ let H = Le;
1199
+ function Ke(e) {
1200
+ H = e;
1240
1201
  }
1241
- function Ve() {
1242
- return R;
1202
+ function Oe() {
1203
+ return H;
1243
1204
  }
1244
1205
  async function Ye(e) {
1245
- return R.listTemplates(e);
1206
+ return H.listTemplates(e);
1246
1207
  }
1247
1208
  async function qe(e) {
1248
- return R.getTemplate(e);
1209
+ return H.getTemplate(e);
1249
1210
  }
1250
1211
  export {
1251
- ye as ApiKeyModal,
1252
- Ue as BillPreview,
1253
- We as ExportButton,
1254
- je as Header,
1255
- A as LAYOUT_HDPI,
1212
+ ve as ApiKeyModal,
1213
+ Me as BillPreview,
1214
+ Fe as ExportButton,
1215
+ We as Header,
1216
+ L as LAYOUT_HDPI,
1256
1217
  T as LAYOUT_LDPI,
1257
- Se as LanguageToggle,
1258
- Be as PersonalInfoForm,
1218
+ Ce as LanguageToggle,
1219
+ ze as PersonalInfoForm,
1259
1220
  Re as PortraitUpload,
1260
- xe as TEMPLATES,
1261
- Me as VoucherConfig,
1262
- Ee as downloadBlob,
1221
+ we as TEMPLATES,
1222
+ He as VoucherConfig,
1223
+ Ne as downloadBlob,
1263
1224
  Ie as drawContactInfo,
1264
- Ne as drawMultilineText,
1265
- ke as drawOvalPortrait,
1225
+ ke as drawMultilineText,
1226
+ xe as drawOvalPortrait,
1266
1227
  ee as drawTemplate,
1267
1228
  te as drawText,
1268
1229
  be as enhancePortrait,
1269
- q as enhancePortraitFallback,
1270
- Ce as exportBillAsPDF,
1230
+ V as enhancePortraitFallback,
1231
+ Ee as exportBillAsPDF,
1271
1232
  G as formatDescription,
1272
1233
  Pe as generateBillPDF,
1273
1234
  X as getApiKey,
1274
- Ke as getDefaultTemplateId,
1235
+ je as getDefaultTemplateId,
1275
1236
  J as getLayout,
1276
1237
  Q as getTemplate,
1277
1238
  qe as getTemplateById,
1278
- Ve as getTemplateProvider,
1279
- Y as hasApiKey,
1239
+ Oe as getTemplateProvider,
1240
+ q as hasApiKey,
1280
1241
  Ye as listTemplates,
1281
1242
  j as loadImage,
1282
1243
  ae as renderBackSide,
1283
1244
  ne as renderFrontSide,
1284
1245
  fe as setApiKey,
1285
- Oe as setTemplateProvider,
1286
- Ae as staticTemplateProvider,
1287
- S as t,
1288
- Fe as useBillCanvasRefs,
1246
+ Ke as setTemplateProvider,
1247
+ Le as staticTemplateProvider,
1248
+ _ as t,
1249
+ Ue as useBillCanvasRefs,
1289
1250
  g as useBillStore
1290
1251
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antontranelis/money-printer",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Create personalized time vouchers that look like real currency. React components for voucher generation with PDF export.",
5
5
  "type": "module",
6
6
  "license": "MIT",