@antontranelis/money-printer 1.0.74 → 1.0.76

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,6 +1,33 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("react/jsx-runtime"),g=require("react"),Qt=require("zustand"),en=require("zustand/middleware"),tn=require("jspdf");var de=typeof document<"u"?document.currentScript:null;const nn=1024,ct=1200,ce=new Map;let G=null,lt=null;function Qe(e,t){return G||(G=document.createElement("canvas"),lt=G.getContext("2d",{willReadFrequently:!0})),(G.width!==e||G.height!==t)&&(G.width=e,G.height=t),lt}function he(e){const t=ce.get(e);return t?Promise.resolve(t):new Promise((n,a)=>{const r=new Image;r.onload=()=>{if(ce.size>10){const l=ce.keys().next().value;l&&ce.delete(l)}ce.set(e,r),n(r)},r.onerror=()=>a(new Error("Failed to load image")),r.src=e})}function an(){ce.clear()}async function pt(e,t=nn){const n=await he(e),a=Math.max(n.width,n.height);if(a<=t)return e;const r=t/a,l=Math.round(n.width*r),i=Math.round(n.height*r),s=document.createElement("canvas"),o=s.getContext("2d");if(!o)throw new Error("Failed to get canvas context");return s.width=l,s.height=i,o.drawImage(n,0,0,l,i),s.toDataURL("image/jpeg",.9)}async function ft(e){const t=await he(e),n=Math.max(t.width,t.height);if(n<=ct){const o=document.createElement("canvas"),u=o.getContext("2d");if(!u)throw new Error("Failed to get canvas context");return o.width=t.width,o.height=t.height,u.drawImage(t,0,0),o.toDataURL("image/png")}const a=ct/n,r=Math.round(t.width*a),l=Math.round(t.height*a),i=document.createElement("canvas"),s=i.getContext("2d");if(!s)throw new Error("Failed to get canvas context");return i.width=r,i.height=l,s.drawImage(t,0,0,r,l),i.toDataURL("image/png")}async function We(e,t,n,a=0){const[r,l]=await Promise.all([he(e),he(t)]),i=Qe(r.width,r.height);if(i.clearRect(0,0,r.width,r.height),n>0){const s=a*20;i.save(),i.globalAlpha=n,s>0&&(i.filter=`blur(${s}px)`),i.drawImage(l,0,0,r.width,r.height),i.restore()}return i.drawImage(r,0,0),G.toDataURL("image/png")}async function bt(e,t=.5,n=40){const a=await he(e),r=Qe(a.width,a.height);r.clearRect(0,0,a.width,a.height),r.drawImage(a,0,0);const l=r.getImageData(0,0,a.width,a.height),i=l.data,s=new Uint32Array(i.buffer),o=1+t*.8,u=1-t,m=n%360/360;for(let f=0;f<s.length;f++){const p=s[f],h=p&255,y=p>>8&255,v=p>>16&255,d=p>>24&255;if(d===0)continue;let I=(((77*h+150*y+29*v>>8)/255-.5)*o+.5)*255;I<0?I=0:I>255&&(I=255);const T=I/255,P=.12,[S,H,C]=xt(m,P,T),N=h*u+S*t|0,L=y*u+H*t|0,B=v*u+C*t|0;s[f]=d<<24|B<<16|L<<8|N}return r.putImageData(l,0,0),G.toDataURL("image/png")}function rn(e,t,n){e/=255,t/=255,n/=255;const a=Math.max(e,t,n),r=Math.min(e,t,n),l=(a+r)/2;let i=0,s=0;if(a!==r){const o=a-r;switch(s=l>.5?o/(2-a-r):o/(a+r),a){case e:i=((t-n)/o+(t<n?6:0))/6;break;case t:i=((n-e)/o+2)/6;break;case n:i=((e-t)/o+4)/6;break}}return[i,s,l]}function xt(e,t,n){if(t===0){const i=Math.round(n*255);return[i,i,i]}const a=(i,s,o)=>(o<0&&(o+=1),o>1&&(o-=1),o<1/6?i+(s-i)*6*o:o<1/2?s:o<2/3?i+(s-i)*(2/3-o)*6:i),r=n<.5?n*(1+t):n+t-n*t,l=2*n-r;return[Math.round(a(l,r,e+1/3)*255),Math.round(a(l,r,e)*255),Math.round(a(l,r,e-1/3)*255)]}const on=29,sn=5;async function wt(e,t){if(Math.abs(t-on)<=sn)return e;const n=await he(e),a=Qe(n.width,n.height);a.clearRect(0,0,n.width,n.height),a.drawImage(n,0,0);const r=a.getImageData(0,0,n.width,n.height),l=r.data,i=new Uint32Array(l.buffer),s=t%360/360,o=20/360,u=45/360,m=i.length;for(let f=0;f<m;f++){const p=i[f],h=p&255,y=p>>8&255,v=p>>16&255,d=p>>24&255;if(d===0)continue;const[k,I,T]=rn(h,y,v);if(I<.08||k<o||k>u)continue;const P=s,S=Math.min(I,.05),[H,C,N]=xt(P,S,T);i[f]=d<<24|N<<16|C<<8|H}return a.putImageData(r,0,0),G.toDataURL("image/png")}const Ee="money-generator-portrait",Se="money-generator-bg-removed";async function cn(e){try{if(localStorage.removeItem(Ee),!e)return;const t=await ft(e);try{localStorage.setItem(Ee,t)}catch(n){console.warn("Could not persist portrait to localStorage:",n)}}catch(t){console.warn("Error processing portrait for storage:",t)}}async function ln(e){try{if(localStorage.removeItem(Se),!e)return;const t=await ft(e);try{localStorage.setItem(Se,t)}catch(n){console.warn("Could not persist bg-removed image to localStorage:",n)}}catch(t){console.warn("Error processing bg-removed image for storage:",t)}}function un(){try{return localStorage.getItem(Ee)}catch{return null}}function dn(){try{return localStorage.getItem(Se)}catch{return null}}function gn(){try{localStorage.removeItem(Ee),localStorage.removeItem(Se)}catch{}}function mn(){return(typeof navigator<"u"?navigator.language:"de").toLowerCase().startsWith("de")?"de":"en"}const Le=mn(),ut={personalInfo:{name:"",email:"",phone:""},voucherConfig:{hours:1,description:"",language:Le,templateHue:29},portrait:{original:null,enhanced:null,useEnhanced:!1,zoom:1,panX:0,panY:0,rawImage:null,bgRemovedImage:null,bgRemoved:!1,bgOpacity:0,bgBlur:0,engravingIntensity:0},currentSide:"front",isEnhancing:!1,isExporting:!1,appLanguage:Le},w=Qt.create()(en.persist(e=>({...ut,setPersonalInfo:t=>e(n=>({personalInfo:{...n.personalInfo,...t}})),setVoucherConfig:t=>e(n=>({voucherConfig:{...n.voucherConfig,...t}})),setPortrait:(t,n=null)=>(cn(t),e(a=>({portrait:{...a.portrait,original:t,enhanced:n,useEnhanced:!1,zoom:a.portrait.original&&t?a.portrait.zoom:1,panX:a.portrait.original&&t?a.portrait.panX:0,panY:a.portrait.original&&t?a.portrait.panY:0}}))),setEnhancedPortrait:t=>e(n=>({portrait:{...n.portrait,enhanced:t,useEnhanced:t!==null}})),toggleUseEnhanced:()=>e(t=>({portrait:{...t.portrait,useEnhanced:t.portrait.enhanced?!t.portrait.useEnhanced:!1}})),setPortraitZoom:t=>e(n=>({portrait:{...n.portrait,zoom:t}})),setPortraitPan:(t,n)=>e(a=>({portrait:{...a.portrait,panX:t,panY:n}})),setPortraitRawImage:t=>e(n=>({portrait:{...n.portrait,rawImage:t}})),setPortraitBgRemoved:(t,n)=>(n!==void 0&&ln(n),e(a=>({portrait:{...a.portrait,bgRemoved:t,bgRemovedImage:n!==void 0?n:a.portrait.bgRemovedImage}}))),setPortraitBgOpacity:t=>e(n=>({portrait:{...n.portrait,bgOpacity:t}})),setPortraitBgBlur:t=>e(n=>({portrait:{...n.portrait,bgBlur:t}})),setPortraitEngravingIntensity:t=>e(n=>({portrait:{...n.portrait,engravingIntensity: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}),setAppLanguage:t=>e({appLanguage:t}),setBillLanguage:t=>e(n=>({voucherConfig:{...n.voucherConfig,language:t}})),setHours:t=>e(n=>({voucherConfig:{...n.voucherConfig,hours:t}})),setTemplateHue:t=>e(n=>({voucherConfig:{...n.voucherConfig,templateHue:t}})),reset:()=>(gn(),e(ut))}),{name:"money-generator-storage",migrate:e=>{const t=e;return t!=null&&t.voucherConfig&&(t.voucherConfig.templateHue=29,t.voucherConfig.hours=1,t.voucherConfig.language=Le),t&&(t.appLanguage=Le),t},version:1,partialize:e=>({personalInfo:e.personalInfo,voucherConfig:{...e.voucherConfig,templateHue:29},appLanguage:e.appLanguage,portrait:{original:null,enhanced:null,useEnhanced:e.portrait.useEnhanced,zoom:e.portrait.zoom,panX:e.portrait.panX,panY:e.portrait.panY,rawImage:null,bgRemovedImage:null,bgRemoved:e.portrait.bgRemoved,bgOpacity:e.portrait.bgOpacity,bgBlur:e.portrait.bgBlur,engravingIntensity:e.portrait.engravingIntensity},currentSide:"front",isEnhancing:!1,isExporting:!1})}));if(typeof window<"u"){const e=un(),t=dn();e&&setTimeout(()=>{const n=w.getState();if(!n.portrait.original){const a=n.portrait.bgRemoved,r=t!==null;w.setState({portrait:{...n.portrait,original:e,rawImage:e,bgRemovedImage:t,bgRemoved:a&&r,bgOpacity:a&&r?n.portrait.bgOpacity:0,bgBlur:a&&r?n.portrait.bgBlur:0}})}},0)}const hn={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?",billLanguage:"Schein-Sprache",billLanguageGerman:"Deutsch",billLanguageEnglish:"Englisch"},billColor:{title:"Scheinfarbe",label:"Farbton"}},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 {bannerText} meiner Zeit oder ein gleichwertiges Dankeschön.",bannerText:{1:"eine Stunde",5:"fünf Stunden",10:"zehn Stunden"}}},pn={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?",billLanguage:"Bill Language",billLanguageGerman:"German",billLanguageEnglish:"English"},billColor:{title:"Bill Color",label:"Hue"}},preview:{front:"Front",back:"Back",flip:"Flip"},export:{button:"Download as PDF",exporting:"Creating PDF...",success:"Download started!"},bill:{descriptionText:"For this voucher, you will receive {bannerText} of my time or an equivalent appreciation in return.",bannerText:{1:"one hour",5:"five hours",10:"ten hours"}}},fn={de:hn,en:pn};function ne(e){return fn[e]}function et(e,t,n){if(n&&n.trim())return n;const a=ne(e),r=a.bill.bannerText[t]||a.bill.bannerText[1];return a.bill.descriptionText.replace("{bannerText}",r)}function bn(e){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)}function xn(e){return e.replace(/\D/g,"").length>=6}function wn({focusField:e,onFocused:t,onFormFocusChange:n}={}){const a=w(d=>d.appLanguage),r=w(d=>d.personalInfo),l=w(d=>d.setPersonalInfo),i=ne(a),[s,o]=g.useState(!1),[u,m]=g.useState(!1),f=s&&r.email.trim()&&!bn(r.email),p=u&&r.phone.trim()&&!xn(r.phone),h=g.useRef(null),y=g.useRef(null),v=g.useRef(null);return g.useEffect(()=>{if(e){const d=e==="name"?h:e==="email"?y:v;setTimeout(()=>{var k,I;(k=d.current)==null||k.click(),(I=d.current)==null||I.focus(),setTimeout(()=>{var T;(T=d.current)==null||T.scrollIntoView({behavior:"smooth",block:"center"})},300),t==null||t()},100)}},[e,t]),c.jsxs("div",{className:"space-y-4",children:[c.jsxs("div",{className:"form-control",children:[c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text font-medium",children:i.form.personalInfo.name})}),c.jsx("input",{ref:h,type:"text",name:"name",autoComplete:"name",placeholder:i.form.personalInfo.namePlaceholder,className:"input input-bordered w-full input-md",value:r.name,onChange:d=>l({name:d.target.value}),onFocus:d=>{n==null||n(!0),setTimeout(()=>d.target.scrollIntoView({behavior:"smooth",block:"center"}),300)},onBlur:()=>n==null?void 0:n(!1)})]}),c.jsxs("div",{className:"form-control",children:[c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text font-medium",children:i.form.personalInfo.email})}),c.jsx("input",{ref:y,type:"email",name:"email",autoComplete:"email",placeholder:i.form.personalInfo.emailPlaceholder,className:`input input-bordered w-full input-md ${f?"input-error":""}`,value:r.email,onChange:d=>l({email:d.target.value}),onFocus:d=>{n==null||n(!0),setTimeout(()=>d.target.scrollIntoView({behavior:"smooth",block:"center"}),300)},onBlur:()=>{o(!0),n==null||n(!1)}}),f&&c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text-alt text-error",children:a==="de"?"Bitte gib eine gültige E-Mail-Adresse ein":"Please enter a valid email address"})})]}),c.jsxs("div",{className:"form-control",children:[c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text font-medium",children:i.form.personalInfo.phone})}),c.jsx("input",{ref:v,type:"tel",name:"phone",autoComplete:"tel",placeholder:i.form.personalInfo.phonePlaceholder,className:`input input-bordered w-full input-md ${p?"input-error":""}`,value:r.phone,onChange:d=>l({phone:d.target.value}),onFocus:d=>{n==null||n(!0),setTimeout(()=>d.target.scrollIntoView({behavior:"smooth",block:"center"}),300)},onBlur:()=>{m(!0),n==null||n(!1)}}),p&&c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text-alt text-error",children:a==="de"?"Bitte gib eine gültige Telefonnummer ein":"Please enter a valid phone number"})})]})]})}const _e={},yn="https://api.stability.ai/v1/generation",vn="https://api.stability.ai/v2beta/stable-image/edit/remove-background",yt="stability_api_key";let pe=null;function kn(e){pe=e}function In(){return pe}function Tn(){return pe!==null}const Pn={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"},dt=[{width:1024,height:1024},{width:1152,height:896},{width:1216,height:832},{width:1344,height:768},{width:1536,height:640},{width:640,height:1536},{width:768,height:1344},{width:832,height:1216},{width:896,height:1152}];function En(e,t){const n=e/t;let a=dt[0],r=1/0;for(const l of dt){const i=l.width/l.height,s=Math.abs(n-i);s<r&&(r=s,a=l)}return a}function Sn(e){return new Promise((t,n)=>{const a=new Image;a.onload=()=>{const r=En(a.width,a.height),l=document.createElement("canvas");l.width=r.width,l.height=r.height;const i=l.getContext("2d");if(!i){n(new Error("Failed to get canvas context"));return}const s=a.width/a.height,o=r.width/r.height;let u=0,m=0,f=a.width,p=a.height;s>o?(f=a.height*o,u=(a.width-f)/2):(p=a.width/o,m=(a.height-p)/2),i.drawImage(a,u,m,f,p,0,0,r.width,r.height),t(l.toDataURL("image/png"))},a.onerror=()=>n(new Error("Failed to load image")),a.src=e})}function vt(e){var i;const t=e.split(","),n=((i=t[0].match(/:(.*?);/))==null?void 0:i[1])||"image/png",a=atob(t[1]),r=a.length,l=new Uint8Array(r);for(let s=0;s<r;s++)l[s]=a.charCodeAt(s);return new Blob([l],{type:n})}function Be(){var t;const e=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:de&&de.tagName.toUpperCase()==="SCRIPT"&&de.src||new URL("index.cjs",document.baseURI).href}<"u"&&(_e==null?void 0:_e.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(yt):null}function kt(e){localStorage.setItem(yt,e)}function Te(){return pe?!0:Be()!==null}async function Ln(e){const t=Be();if(!t)throw new Error("No Stability AI API key configured");const{imageDataUrl:n,style:a,strength:r=.35}=e,l=await Sn(n),i=vt(l),s=new FormData;s.append("init_image",i,"portrait.png"),s.append("init_image_mode","IMAGE_STRENGTH"),s.append("image_strength",String(1-r)),s.append("text_prompts[0][text]",Pn[a]),s.append("text_prompts[0][weight]","1"),s.append("cfg_scale","7"),s.append("samples","1"),s.append("steps","30");const u=await fetch(`${yn}/stable-diffusion-xl-1024-v1-0/image-to-image`,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"},body:s});if(!u.ok){const f=await u.text();throw console.error("Stability AI error:",f),u.status===401?new Error("Invalid API key"):u.status===402?new Error("Insufficient credits"):u.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${u.status}`)}const m=await u.json();if(!m.artifacts||m.artifacts.length===0)throw new Error("No image generated");return`data:image/png;base64,${m.artifacts[0].base64}`}async function It(e){if(pe){const i=await fetch(pe,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({imageDataUrl:e})});if(!i.ok){const o=await i.json().catch(()=>({}));throw new Error(o.error||`API error: ${i.status}`)}return(await i.json()).imageDataUrl}const t=Be();if(!t)throw new Error("No Stability AI API key configured");const n=vt(e),a=new FormData;a.append("image",n,"image.png"),a.append("output_format","png");const r=await fetch(vn,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"image/*"},body:a});if(!r.ok){const i=await r.text();throw console.error("Stability AI remove background error:",i),r.status===401?new Error("Invalid API key"):r.status===402?new Error("Insufficient credits"):r.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${r.status}`)}const l=await r.blob();return new Promise((i,s)=>{const o=new FileReader;o.onload=()=>i(o.result),o.onerror=()=>s(new Error("Failed to read result")),o.readAsDataURL(l)})}function Rn(){const[e,t]=g.useState(!1),[n,a]=g.useState(!1),[r,l]=g.useState(null),[i,s]=g.useState(()=>Te());g.useEffect(()=>{s(Te());const p=setTimeout(()=>{s(Te())},150);return()=>clearTimeout(p)},[]);const o=g.useCallback(()=>l(null),[]),u=g.useCallback(p=>{kt(p),s(!0),l(null)},[]),m=g.useCallback(async(p,h=.5,y=40)=>{t(!0),l(null);try{return await bt(p,h,y)}catch(v){const d=v instanceof Error?v.message:"Enhancement failed";throw l(d),v}finally{t(!1)}},[]),f=g.useCallback(async p=>{a(!0),l(null);try{return await It(p)}catch(h){const y=h instanceof Error?h.message:"Background removal failed";throw l(y),h}finally{a(!1)}},[]);return{enhance:m,removeBg:f,isEnhancing:e,isRemovingBg:n,error:r,hasKey:i,setApiKey:u,clearError:o}}function Tt({isOpen:e,onClose:t,onSubmit:n}){const a=w(u=>u.appLanguage),[r,l]=g.useState("");if(!e)return null;const i=u=>{u.preventDefault(),r.trim()&&(n(r.trim()),l(""),t())},o={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."}}[a];return c.jsxs("dialog",{className:"modal modal-open",children:[c.jsxs("div",{className:"modal-box",children:[c.jsx("h3",{className:"font-bold text-lg",children:o.title}),c.jsx("p",{className:"py-4 text-sm opacity-80",children:o.description}),c.jsxs("form",{onSubmit:i,children:[c.jsxs("div",{className:"form-control",children:[c.jsx("input",{type:"password",placeholder:o.placeholder,className:"input input-bordered w-full",value:r,onChange:u=>l(u.target.value),autoFocus:!0}),c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text-alt",children:o.hint})})]}),c.jsxs("div",{className:"modal-action",children:[c.jsx("button",{type:"button",className:"btn btn-ghost",onClick:t,children:o.cancel}),c.jsx("button",{type:"submit",className:"btn btn-primary",disabled:!r.trim(),children:o.submit})]})]})]}),c.jsx("form",{method:"dialog",className:"modal-backdrop",children:c.jsx("button",{onClick:t,children:"close"})})]})}function we({min:e,max:t,step:n,value:a,onChange:r,className:l="",disabled:i=!1}){const s=g.useRef(null),o=g.useRef(null),u=g.useRef(!1),[m,f]=g.useState(!1),p=(a-e)/(t-e)*100,h=g.useCallback(T=>{if(!s.current)return a;const P=s.current.getBoundingClientRect(),S=Math.max(0,Math.min(1,(T-P.left)/P.width)),H=t-e,C=e+S*H,N=Math.round(C/n)*n;return Math.max(e,Math.min(t,N))},[e,t,n,a]),y=g.useCallback(T=>{if(i)return;const P=T.touches[0];o.current={x:P.clientX,y:P.clientY,value:a,decided:!1},u.current=!1},[a,i]),v=g.useCallback(T=>{if(i||!o.current)return;const P=T.touches[0],S=Math.abs(P.clientX-o.current.x),H=Math.abs(P.clientY-o.current.y);if(!o.current.decided){if(S<8&&H<8)return;if(o.current.decided=!0,H>S){o.current=null;return}u.current=!0,f(!0)}if(u.current){const C=h(P.clientX);C!==a&&r(C)}},[i,h,r,a]),d=g.useCallback(T=>{if(o.current&&!o.current.decided){const P=T.changedTouches[0];if(P){const S=h(P.clientX);S!==a&&r(S)}}o.current=null,u.current=!1,f(!1)},[h,r,a]);g.useEffect(()=>{const T=s.current;if(!T)return;const P=S=>{u.current&&S.preventDefault()};return T.addEventListener("touchmove",P,{passive:!1}),()=>{T.removeEventListener("touchmove",P)}},[]);const k=g.useCallback(T=>{if(i)return;const P=h(T.clientX);r(P),f(!0);const S=C=>{const N=h(C.clientX);r(N)},H=()=>{f(!1),document.removeEventListener("mousemove",S),document.removeEventListener("mouseup",H)};document.addEventListener("mousemove",S),document.addEventListener("mouseup",H)},[i,h,r]),I=`calc(10px + (100% - 20px) * ${p/100})`;return c.jsxs("div",{ref:s,className:`relative h-10 flex items-center cursor-pointer overflow-visible ${i?"opacity-50 cursor-not-allowed":""}`,onTouchStart:y,onTouchMove:v,onTouchEnd:d,onMouseDown:k,children:[c.jsx("div",{className:"absolute h-2 bg-base-300 rounded-full inset-x-0"}),c.jsx("div",{className:`absolute h-2 rounded-full transition-colors ${l.includes("range-primary")?"bg-primary":l.includes("range-secondary")?"bg-secondary":"bg-primary"}`,style:{left:0,width:I}}),c.jsx("div",{className:`absolute w-5 h-5 rounded-full bg-base-100 border-2 shadow-md transition-transform ${m?"scale-110":""} ${l.includes("range-primary")?"border-primary":l.includes("range-secondary")?"border-secondary":"border-primary"}`,style:{left:I,transform:"translateX(-50%)"}})]})}function Bn(){const e=w(b=>b.appLanguage),t=w(b=>b.portrait),n=w(b=>b.setPortrait),a=w(b=>b.setPortraitZoom),r=w(b=>b.setPortraitPan),l=w(b=>b.setPortraitRawImage),i=w(b=>b.setPortraitBgRemoved),s=w(b=>b.setPortraitBgOpacity),o=w(b=>b.setPortraitBgBlur),u=w(b=>b.setPortraitEngravingIntensity),{enhance:m,removeBg:f,isEnhancing:p,isRemovingBg:h,error:y,hasKey:v,setApiKey:d}=Rn(),k=ne(e),I=g.useRef(null),[T,P]=g.useState(!1),[S,H]=g.useState(!1),C=g.useRef(null),N=g.useRef(null),L=t.rawImage,B=t.bgRemovedImage,z=t.bgRemoved,F=t.bgOpacity,M=t.bgBlur,Y=t.engravingIntensity;g.useEffect(()=>{t.original&&!t.rawImage&&l(t.original)},[t.original,t.rawImage,l]),g.useEffect(()=>()=>{C.current&&clearTimeout(C.current),N.current&&clearTimeout(N.current)},[]);const Z=w(b=>b.voucherConfig.templateHue),te=g.useRef(Z),W=g.useCallback(async b=>{if(!b.type.startsWith("image/"))return;const E=new FileReader;E.onload=async A=>{var O;const D=(O=A.target)==null?void 0:O.result,K=await pt(D);an(),l(K),n(K),a(1),r(0,0),i(!1,null),s(0),o(0),u(0)},E.readAsDataURL(b)},[n,l,a,r,i,s,o,u]),J=g.useCallback(b=>{b.preventDefault(),P(!1);const E=b.dataTransfer.files[0];E&&W(E)},[W]),q=g.useCallback(b=>{b.preventDefault(),P(!0)},[]),fe=g.useCallback(b=>{b.preventDefault(),P(!1)},[]),be=()=>{var b;(b=I.current)==null||b.click()},De=b=>{var A;const E=(A=b.target.files)==null?void 0:A[0];E&&W(E)},Q=g.useCallback(async(b,E,A)=>{try{return await m(b,E,A)}catch(D){return console.error("Enhancement failed:",D),b}},[m]),ye=g.useCallback(async b=>{try{const E=await f(b);return i(!0,E),E}catch(E){return console.error("Background removal failed:",E),b}},[f,i]),ee=g.useCallback(async()=>{const b=w.getState(),E=b.portrait,A=b.voucherConfig.templateHue;if(!E.rawImage)return;let D;E.bgRemoved&&E.bgRemovedImage?D=await We(E.bgRemovedImage,E.rawImage,E.bgOpacity,E.bgBlur):D=E.rawImage,E.engravingIntensity>0&&(D=await Q(D,E.engravingIntensity,A)),n(D)},[Q,n]);g.useEffect(()=>{if(te.current===Z)return;te.current=Z;const b=w.getState().portrait;b.engravingIntensity>0&&b.rawImage&&(C.current&&clearTimeout(C.current),C.current=setTimeout(ee,150))},[Z,ee]);const He=async()=>{if(!L)return;if(!z&&!v){H(!0);return}if(!z){const E=await ye(L),A=w.getState(),D=A.portrait,K=A.voucherConfig.templateHue;let O=await We(E,L,D.bgOpacity,D.bgBlur);D.engravingIntensity>0&&(O=await Q(O,D.engravingIntensity,K)),n(O)}else{i(!1,null);const E=w.getState(),A=E.portrait.engravingIntensity,D=E.voucherConfig.templateHue;if(A>0){const K=await Q(L,A,D);n(K)}else n(L)}},xe=b=>{u(b),C.current&&clearTimeout(C.current),L&&(C.current=setTimeout(ee,150))},Me=async b=>{if(d(b),!L)return;const E=await ye(L),A=w.getState(),D=A.portrait,K=A.voucherConfig.templateHue;let O=await We(E,L,D.bgOpacity,D.bgBlur);D.engravingIntensity>0&&(O=await Q(O,D.engravingIntensity,K)),n(O)},ve=b=>{s(b),N.current&&clearTimeout(N.current),!(!L||!B)&&(N.current=setTimeout(ee,150))},ke=b=>{o(b),N.current&&clearTimeout(N.current),!(!L||!B)&&(N.current=setTimeout(ee,150))};return c.jsxs("div",{className:"space-y-4",children:[t.original?c.jsxs("div",{className:"flex flex-col space-y-4",children:[c.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[c.jsxs("div",{className:"form-control w-full",children:[c.jsxs("label",{className:"label",children:[c.jsx("span",{className:"label-text",children:k.form.portrait.zoom}),c.jsxs("span",{className:"label-text-alt",children:[Math.round(t.zoom*100),"%"]})]}),c.jsx(we,{min:.5,max:2,step:.05,value:t.zoom,onChange:a,className:"range range-primary range-sm"})]}),c.jsxs("div",{className:"form-control w-full",children:[c.jsxs("label",{className:"label",children:[c.jsxs("span",{className:"label-text flex items-center gap-2",children:[e==="de"?"Farbanpassung":"Color adjustment",p&&c.jsx("span",{className:"loading loading-spinner loading-xs"})]}),c.jsxs("span",{className:"label-text-alt",children:[Math.round(Y*100),"%"]})]}),c.jsx(we,{min:0,max:1,step:.05,value:Y,onChange:xe,className:"range range-secondary range-sm",disabled:p||!L})]})]}),z?c.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[c.jsxs("div",{className:"form-control w-full",children:[c.jsxs("label",{className:"label",children:[c.jsx("span",{className:"label-text",children:e==="de"?"Hintergrund":"Background"}),c.jsxs("span",{className:"label-text-alt",children:[Math.round(F*100),"%"]})]}),c.jsx(we,{min:0,max:1,step:.05,value:F,onChange:ve,className:"range range-primary range-sm"})]}),c.jsxs("div",{className:"form-control w-full",children:[c.jsxs("label",{className:"label",children:[c.jsx("span",{className:"label-text",children:e==="de"?"Unschärfe":"Blur"}),c.jsxs("span",{className:"label-text-alt",children:[Math.round(M*100),"%"]})]}),c.jsx(we,{min:0,max:1,step:.05,value:M,onChange:ke,className:"range range-primary range-sm",disabled:F===0})]})]}):c.jsx("div",{className:"flex justify-center",children:c.jsx("button",{className:"btn btn-ghost btn gap-2 text-base-content/70",onClick:He,disabled:h||!L,children:h?c.jsxs(c.Fragment,{children:[e==="de"?"Hintergrund wird entfernt":"Removing background",c.jsx("span",{className:"loading loading-dots loading-xs"})]}):c.jsxs(c.Fragment,{children:[c.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:c.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9.813 15.904L9 18.75l-.813-2.846a4.5 4.5 0 00-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 003.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 003.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 00-3.09 3.09zM18.259 8.715L18 9.75l-.259-1.035a3.375 3.375 0 00-2.455-2.456L14.25 6l1.036-.259a3.375 3.375 0 002.455-2.456L18 2.25l.259 1.035a3.375 3.375 0 002.456 2.456L21.75 6l-1.035.259a3.375 3.375 0 00-2.456 2.456zM16.894 20.567L16.5 21.75l-.394-1.183a2.25 2.25 0 00-1.423-1.423L13.5 18.75l1.183-.394a2.25 2.25 0 001.423-1.423l.394-1.183.394 1.183a2.25 2.25 0 001.423 1.423l1.183.394-1.183.394a2.25 2.25 0 00-1.423 1.423z"})}),e==="de"?"Hintergrund entfernen":"Remove background",!v&&c.jsx("span",{className:"badge badge-sm badge-outline",children:"API"})]})})}),y&&c.jsxs("div",{className:"alert alert-warning text-sm py-2",children:[c.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:c.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"})}),c.jsx("span",{children:y})]})]}):c.jsxs("div",{className:`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${h?"border-primary bg-primary/10 pointer-events-none":T?"border-primary bg-primary/10":"border-base-300 hover:border-primary hover:bg-base-200"}`,onDrop:J,onDragOver:q,onDragLeave:fe,onClick:be,children:[c.jsx("input",{ref:I,type:"file",accept:"image/*",className:"hidden",onChange:De}),h?c.jsxs("div",{className:"flex flex-col items-center gap-2",children:[c.jsx("span",{className:"loading loading-spinner loading-lg text-primary"}),c.jsx("p",{className:"font-medium",children:e==="de"?"Hintergrund wird entfernt...":"Removing background..."})]}):c.jsxs("div",{className:"flex flex-col items-center gap-2",children:[c.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:c.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"})}),c.jsx("p",{className:"font-medium",children:k.form.portrait.upload}),c.jsx("p",{className:"text-sm text-base-content/60",children:k.form.portrait.dragDrop})]})]}),c.jsx(Tt,{isOpen:S,onClose:()=>H(!1),onSubmit:Me})]})}function jn(){const e=w(s=>s.appLanguage),t=w(s=>s.voucherConfig.language),n=w(s=>s.voucherConfig.hours);w(s=>s.voucherConfig.templateHue);const a=w(s=>s.setBillLanguage),r=w(s=>s.setHours);w(s=>s.setTemplateHue);const l=ne(e),i=[1,5,10];return c.jsxs("div",{className:"space-y-4",children:[c.jsx("div",{className:"form-control",children:c.jsxs("div",{className:"flex items-center justify-between gap-2",children:[c.jsx("span",{className:"label-text font-medium",children:l.form.voucher.billLanguage}),c.jsxs("div",{className:"join border border-base-300 rounded-lg shadow",children:[c.jsx("button",{className:`join-item btn btn-md ${t==="de"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>a("de"),children:l.form.voucher.billLanguageGerman}),c.jsx("button",{className:`join-item btn btn-md ${t==="en"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>a("en"),children:l.form.voucher.billLanguageEnglish})]})]})}),c.jsx("div",{className:"form-control",children:c.jsxs("div",{className:"flex items-center justify-between gap-2",children:[c.jsx("span",{className:"label-text font-medium",children:l.form.voucher.hours}),c.jsx("div",{className:"join border border-base-300 rounded-lg shadow",children:i.map(s=>c.jsxs("button",{className:`join-item btn btn-md ${n===s?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>r(s),children:[s,c.jsxs("span",{className:"hidden sm:inline",children:[" ",s===1?l.form.voucher.hourLabel:l.form.voucher.hoursLabel]})]},s))})]})}),!1]})}const $e=new Map,se=new Map;async function R(e){return $e.has(e)?$e.get(e):new Promise((t,n)=>{const a=new Image;a.crossOrigin="anonymous",a.onload=()=>{$e.set(e,a),t(a)},a.onerror=n,a.src=e})}function ie(e,t,n,a){e.drawImage(t,0,0,n,a)}async function Pt(e,t,n,a){if(t>=155&&t<=165)return R(e);const r=`${e}:${t}:${n}x${a}`;if(se.has(r))return R(se.get(r));const l=await R(e),i=document.createElement("canvas");i.width=n,i.height=a;const s=i.getContext("2d");if(!s)throw new Error("Failed to get canvas context");s.drawImage(l,0,0,n,a);const o=i.toDataURL("image/png"),u=await wt(o,t);if(se.size>20){const m=se.keys().next().value;m&&se.delete(m)}return se.set(r,u),R(u)}function Cn(e,t,n,a,r,l="de"){e.save(),e.beginPath(),e.ellipse(t,n,a,r,0,0,Math.PI*2),e.closePath(),e.setLineDash([20,10]),e.strokeStyle="rgba(100, 100, 100, 0.4)",e.lineWidth=3,e.stroke(),e.restore()}function Et(e,t,n,a,r,l,i=1,s=0,o=0){e.save(),e.beginPath(),e.ellipse(n,a,r,l,0,0,Math.PI*2),e.closePath(),e.clip();const u=t.width/t.height,m=r/l,f=r*2,p=l*2;let h,y;u>m?(y=p,h=p*u):(h=f,y=f/u),h*=i,y*=i;const v=Math.max(0,(h-f)/2),d=Math.max(0,(y-p)/2),k=n-h/2+s*v,I=a-y/2+o*d;e.drawImage(t,k,I,h,y),e.restore()}function tt(e,t,n,a="#2a3a2a"){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()}function St(e,t,n,a="#2a3a2a"){e.save(),e.font=`${n.fontSize}px "Times New Roman", serif`,e.textAlign=n.align||"center",e.textBaseline="top",e.fillStyle=a;const r=n.maxWidth||400,l=n.lineHeight||n.fontSize*1.4,i=t.split(" "),s=[];let o="";for(const f of i){const p=o?`${o} ${f}`:f;e.measureText(p).width>r&&o?(s.push(o),o=f):o=p}o&&s.push(o);const u=s.length*l;let m=n.y-u/2;for(const f of s)e.fillText(f,n.x,m),m+=l;e.restore()}function Lt(e,t,n,a,r,l="#2a3a2a"){e.save(),e.font=`${r.fontSize}px "Times New Roman", serif`,e.textAlign=r.align||"center",e.textBaseline="middle",e.fillStyle=l;const i=r.lineHeight||r.fontSize*1.8,s=[t,n,a].filter(Boolean),o=(s.length-1)*i;let u=r.y-o/2;for(const m of s)m&&(e.fillText(m,r.x,u),u+=i);e.restore()}function Nn(e,t,n,a="#2a3a2a"){e.save(),e.strokeStyle=a,e.lineWidth=Math.max(2,t.labelFontSize/16),e.beginPath(),e.moveTo(t.x-t.width/2,t.y),e.lineTo(t.x+t.width/2,t.y),e.stroke(),e.font=`${t.labelFontSize}px "Times New Roman", serif`,e.textAlign="center",e.textBaseline="top",e.fillStyle=a,e.fillText(n,t.x,t.y+t.labelFontSize*.3),e.restore()}async function Rt(e,t,n,a,r,l,i,s,o,u=1,m=0,f=0,p=0,h=1,y="de"){const v=e.getContext("2d");if(!v)return;const d=document.createElement("canvas");d.width=s,d.height=o;const k=d.getContext("2d");if(!k)return;k.clearRect(0,0,s,o);const I=await Pt(t,p,s,o);ie(k,I,s,o);const T=await R(n);if(ie(k,T,s,o),r)try{const H=await R(r);Et(k,H,i.portrait.x,i.portrait.y,i.portrait.radiusX,i.portrait.radiusY,u,m,f)}catch(H){console.error("Failed to load portrait:",H)}else Cn(k,i.portrait.x,i.portrait.y,i.portrait.radiusX,i.portrait.radiusY,y);const P=await R(a);ie(k,P,s,o);const S=s/3633;Ht(k,h,y,S),l&&tt(k,l,i.namePlate),e.width=s,e.height=o,v.drawImage(d,0,0)}async function Bt(e,t,n,a,r,l,i,s,o,u,m,f=0,p=1,h="de"){const y=e.getContext("2d");if(!y)return;const v=document.createElement("canvas");v.width=u,v.height=m;const d=v.getContext("2d");if(!d)return;d.clearRect(0,0,u,m);const k=await Pt(t,f,u,m);ie(d,k,u,m);const I=await R(n);ie(d,I,u,m);const T=await R(a);ie(d,T,u,m);const P=u/3633;if(Ht(d,p,h,P),o.contactInfo&&(r||l||i)&&Lt(d,r,l,i,o.contactInfo),o.description&&s&&St(d,s,o.description),r&&tt(d,r,o.namePlate),o.signature){const S=h==="de"?"Unterschrift":"Signature";Nn(d,o.signature,S)}e.width=u,e.height=m,y.drawImage(v,0,0)}const ge=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:de&&de.tagName.toUpperCase()==="SCRIPT"&&de.src||new URL("index.cjs",document.baseURI).href}<"u"&&"/"||"/",V={background:`${ge}templates/background.webp`,frontFrame:`${ge}templates/front_frame.webp`,backFrame:`${ge}templates/back_frame.webp`},me={1:`${ge}templates/1.png`,5:`${ge}templates/5.png`,10:`${ge}templates/10.png`},jt={de:{banner:{1:"EINE STUNDE",5:"FÜNF STUNDEN",10:"ZEHN STUNDEN"}},en:{banner:{1:"ONE HOUR",5:"FIVE HOURS",10:"TEN HOURS"}}},ae=3633,re=1920,je=.5,Dn=Math.round(ae*je),Hn=Math.round(re*je),Ct=320,Nt=335,X={badges:{topLeft:{x:286,y:235},topRight:{x:3340,y:230},bottomLeft:{x:282,y:1665},bottomRight:{x:3345,y:1665}},banner:{centerX:1816,centerY:3820,radius:3610,fontSize:103,color:"#2a3a2a"}},Pe=new Map,oe=new Map,Ke=new Map,qe=new Map,Ge=new Map;function Dt(e,t,n,a,r,l,i){e.save(),e.font=`900 ${l}px "Times New Roman", Georgia, serif`,e.fillStyle=i,e.textAlign="center",e.textBaseline="middle";const o=e.measureText(t).width/r,u=-Math.PI/2-o/2,m=t.split(""),f=[];for(const h of m)f.push(e.measureText(h).width);let p=u;for(let h=0;h<m.length;h++){const y=m[h],v=f[h],d=p+v/2/r,k=n+r*Math.cos(d),I=a+r*Math.sin(d);e.save(),e.translate(k,I),e.rotate(d+Math.PI/2),e.fillText(y,0,0),e.restore(),p+=v/r}e.restore()}let _={background:null,frontFrame:null,backFrame:null,badges:{1:null,5:null,10:null}};async function Mn(){const[e,t,n,a,r,l]=await Promise.all([R(V.background),R(V.frontFrame),R(V.backFrame),R(me[1]),R(me[5]),R(me[10])]);_={background:e,frontFrame:t,backFrame:n,badges:{1:a,5:r,10:l}}}function An(e,t){const n=Math.round(ae*e),a=Math.round(re*e),r=document.createElement("canvas");r.width=n,r.height=a;const l=r.getContext("2d");if(!l)throw new Error("Failed to get canvas context");l.drawImage(t,0,0,n,a);const i=e<1?.8:.95;return r.toDataURL("image/jpeg",i)}function Un(e,t){const n=Math.round(ae*e),a=Math.round(re*e),r=document.createElement("canvas");r.width=n,r.height=a;const l=r.getContext("2d");if(!l)throw new Error("Failed to get canvas context");const i=Ct*e,s=Nt*e,o=X.badges,u=(m,f)=>{const p=f/2,h=m.x*e-p,y=m.y*e-p;l.drawImage(t,h,y,f,f)};return u(o.topLeft,i),u(o.topRight,i),u(o.bottomLeft,s),u(o.bottomRight,s),r.toDataURL("image/png")}function Ht(e,t,n,a=1){const r=jt[n].banner[t];Dt(e,r,X.banner.centerX*a,X.banner.centerY*a,X.banner.radius*a,X.banner.fontSize*a,X.banner.color)}function Mt(e,t,n,a,r,l,i){const s=Math.round(ae*a),o=Math.round(re*a),u=document.createElement("canvas");u.width=s,u.height=o;const m=u.getContext("2d");if(!m)throw new Error("Failed to get canvas context");m.drawImage(r,0,0,s,o);{const p=Ct*a,h=Nt*a,y=X.badges,v=(d,k)=>{const I=k/2,T=d.x*a-I,P=d.y*a-I;m.drawImage(i,T,P,k,k)};v(y.topLeft,p),v(y.topRight,p),v(y.bottomLeft,h),v(y.bottomRight,h)}if(m.drawImage(l,0,0,s,o),n==="front"){const p=jt[t].banner[e];Dt(m,p,X.banner.centerX*a,X.banner.centerY*a,X.banner.radius*a,X.banner.fontSize*a,X.banner.color)}const f=a<1?.8:.95;return u.toDataURL("image/jpeg",f)}async function At(e,t,n){const a=`${e}-${t}-${n}`;if(Pe.has(a))return Pe.get(a);const r=_.background||await R(V.background),l=n==="front"?_.frontFrame||await R(V.frontFrame):_.backFrame||await R(V.backFrame),i=_.badges[e]||await R(me[e]),s=Mt(e,t,n,je,r,l,i);return Pe.set(a,s),s}async function Fe(e,t,n){const a=`${e}-${t}-${n}`;if(oe.has(a))return oe.get(a);const r=_.background||await R(V.background),l=n==="front"?_.frontFrame||await R(V.frontFrame):_.backFrame||await R(V.backFrame),i=_.badges[e]||await R(me[e]),s=Mt(e,t,n,1,r,l,i);if(oe.size>4){const o=oe.keys().next().value;o&&oe.delete(o)}return oe.set(a,s),s}function Yn(){return{width:ae,height:re}}function On(){Pe.clear(),oe.clear(),Ke.clear(),qe.clear(),Ge.clear()}async function Ze(e,t,n="front",a=je){const r=`bg-${a}`;let l=Ke.get(r);if(!l){const m=_.background||await R(V.background);l=An(a,m),Ke.set(r,l)}const i=`badges-${e}-${a}`;let s=qe.get(i);if(!s){const m=_.badges[e]||await R(me[e]);s=Un(a,m),qe.set(i,s)}const o=`${n}-${a}`;let u=Ge.get(o);if(!u){const m=n==="front"?_.frontFrame||await R(V.frontFrame):_.backFrame||await R(V.backFrame),f=Math.round(ae*a),p=Math.round(re*a),h=document.createElement("canvas");h.width=f,h.height=p;const y=h.getContext("2d");if(!y)throw new Error("Failed to get canvas context");y.drawImage(m,0,0,f,p),u=h.toDataURL("image/png"),Ge.set(o,u)}return{background:l,badges:s,frame:u}}async function zn(){const e=[1,5,10],t=["de","en"],n=["front","back"],a=[];for(const r of e)for(const l of t)for(const i of n)a.push(At(r,l,i));await Promise.all(a)}function nt(e,t){return{front:"",back:"",width:ae,height:re}}const Ce={front:{portrait:{x:1810,y:918,radiusX:570,radiusY:605},namePlate:{x:1816,y:1765,fontSize:85,maxWidth:898,align:"center"}},back:{portrait:{x:0,y:0,radiusX:0,radiusY:0},namePlate:{x:1816,y:1770,fontSize:85,maxWidth:898,align:"center"},contactInfo:{x:898,y:939,fontSize:93,lineHeight:165,align:"center"},description:{x:2721,y:939,fontSize:85,maxWidth:1177,lineHeight:124,align:"center"},signature:{x:1820,y:1445,width:950,height:145,labelFontSize:85}}},le=Ce,ue=Ce;function at(e){return Ce}const Je=.75;function Wn(e){const t=at(),n=Je,a=r=>({portrait:{x:r.portrait.x*n,y:r.portrait.y*n,radiusX:r.portrait.radiusX*n,radiusY:r.portrait.radiusY*n},namePlate:{x:r.namePlate.x*n,y:r.namePlate.y*n,fontSize:r.namePlate.fontSize*n,maxWidth:r.namePlate.maxWidth?r.namePlate.maxWidth*n:void 0,lineHeight:r.namePlate.lineHeight?r.namePlate.lineHeight*n:void 0,align:r.namePlate.align},contactInfo:r.contactInfo?{x:r.contactInfo.x*n,y:r.contactInfo.y*n,fontSize:r.contactInfo.fontSize*n,maxWidth:r.contactInfo.maxWidth?r.contactInfo.maxWidth*n:void 0,lineHeight:r.contactInfo.lineHeight?r.contactInfo.lineHeight*n:void 0,align:r.contactInfo.align}:void 0,description:r.description?{x:r.description.x*n,y:r.description.y*n,fontSize:r.description.fontSize*n,maxWidth:r.description.maxWidth?r.description.maxWidth*n:void 0,lineHeight:r.description.lineHeight?r.description.lineHeight*n:void 0,align:r.description.align}:void 0,signature:r.signature?{x:r.signature.x*n,y:r.signature.y*n,width:r.signature.width*n,height:r.signature.height*n,labelFontSize:r.signature.labelFontSize*n}:void 0});return{front:a(t.front),back:a(t.back)}}function _n(e,t){const n=nt();return{...n,width:Math.round(n.width*Je),height:Math.round(n.height*Je)}}function $n(e,t){const[n,a]=g.useState(e);return g.useEffect(()=>{const r=setTimeout(()=>a(e),t);return()=>clearTimeout(r)},[e,t]),n}function Xn({onPortraitClick:e,onFileDrop:t}={}){const n=w(x=>x.appLanguage),a=w(x=>x.voucherConfig.language),r=w(x=>x.voucherConfig.hours),l=w(x=>x.voucherConfig.description),i=w(x=>x.voucherConfig.templateHue),s=w(x=>x.personalInfo),o=w(x=>x.portrait),u=w(x=>x.currentSide),m=w(x=>x.flipSide),f=w(x=>x.setPortraitPan),p=$n(i,150),h=ne(n),y=g.useRef(null),v=g.useRef(null),d=g.useRef(null),[k,I]=g.useState(!1),[T,P]=g.useState(!1),[S,H]=g.useState(!1),[C,N]=g.useState(!1),L=g.useRef(null),B=g.useRef(null),z=g.useRef(!1),F=g.useRef(0),M=_n(),Y=Wn(),Z=o.useEnhanced&&o.enhanced?o.enhanced:o.original,te=et(a,r,l),[W,J]=g.useState(""),[q,fe]=g.useState(""),[be,De]=g.useState(""),[Q,ye]=g.useState(""),[ee,He]=g.useState(""),[xe,Me]=g.useState(""),[ve,ke]=g.useState(!0);g.useEffect(()=>{let x=!0;ke(!0);async function j(){const[U,$]=await Promise.all([Ze(r,a,"front"),Ze(r,a,"back")]);x&&(J(U.background),fe(U.badges),De(U.frame),ye($.background),He($.badges),Me($.frame),ke(!1))}return j(),()=>{x=!1}},[r,a]),g.useEffect(()=>{!y.current||!W||!q||!be||Rt(y.current,W,q,be,Z,s.name,Y.front,M.width,M.height,o.zoom,o.panX,o.panY,p,r,a)},[M,W,q,be,Z,s.name,Y,o.zoom,o.panX,o.panY,p,r,a]),g.useEffect(()=>{!v.current||!Q||!ee||!xe||Bt(v.current,Q,ee,xe,s.name,s.email,s.phone,te,Y.back,M.width,M.height,p,r,a)},[M,Q,ee,xe,s,te,Y,p,r,a]);const b=()=>{I(!k),m()};g.useEffect(()=>{I(u==="back")},[u]);const E=g.useCallback((x,j)=>{if(!d.current||u!=="front")return!1;const U=d.current.getBoundingClientRect(),$=U.width/M.width,Ae=U.height/M.height,Ie=(x-U.left)/$,Ue=(j-U.top)/Ae,{x:Ye,y:Oe,radiusX:ze,radiusY:Jt}=Y.front.portrait,it=(Ie-Ye)/ze,st=(Ue-Oe)/Jt;return it*it+st*st<=1},[u,M.width,M.height,Y.front.portrait]),A=5,D=g.useCallback((x,j)=>{o.original&&(P(!0),L.current={x,y:j,panX:o.panX,panY:o.panY})},[o.original,o.panX,o.panY]),K=g.useCallback((x,j)=>{if(!T||!L.current||!d.current)return;const U=performance.now();if(U-F.current<33)return;F.current=U;const $=d.current.getBoundingClientRect(),Ie=4/Math.max($.width,$.height)*o.zoom,Ue=(x-L.current.x)*Ie,Ye=(j-L.current.y)*Ie,Oe=Math.max(-1,Math.min(1,L.current.panX+Ue)),ze=Math.max(-1,Math.min(1,L.current.panY+Ye));f(Oe,ze)},[T,f,o.zoom]),O=g.useCallback(()=>{P(!1),L.current=null,B.current=null},[]),rt=g.useCallback(()=>{e&&e()},[e]),_t=x=>{E(x.clientX,x.clientY)&&(x.preventDefault(),B.current={x:x.clientX,y:x.clientY},z.current=!1)},$t=x=>{if(H(E(x.clientX,x.clientY)),B.current&&o.original){const j=x.clientX-B.current.x,U=x.clientY-B.current.y;Math.sqrt(j*j+U*U)>A&&!T&&(z.current=!0,D(B.current.x,B.current.y))}T&&K(x.clientX,x.clientY)},Xt=x=>{B.current&&!z.current&&E(x.clientX,x.clientY)&&rt(),O()},Vt=()=>{O(),H(!1)},Kt=x=>{if(x.touches.length===1){const j=x.touches[0];E(j.clientX,j.clientY)&&(B.current={x:j.clientX,y:j.clientY},z.current=!1)}},qt=x=>{if(x.touches.length===1&&B.current&&o.original){const j=x.touches[0],U=j.clientX-B.current.x,$=j.clientY-B.current.y;Math.sqrt(U*U+$*$)>A&&!T&&(z.current=!0,D(B.current.x,B.current.y)),T&&K(j.clientX,j.clientY)}},Gt=()=>{B.current&&!z.current&&E(B.current.x,B.current.y)&&rt(),O()},ot=g.useRef(!1);g.useEffect(()=>{ot.current=T},[T]),g.useEffect(()=>{const x=d.current;if(!x)return;const j=U=>{ot.current&&U.preventDefault()};return x.addEventListener("touchmove",j,{passive:!1}),()=>{x.removeEventListener("touchmove",j)}},[]);const Ft=u==="front"&&o.original,Zt=M.width/M.height;return c.jsxs("div",{className:"space-y-4",children:[c.jsxs("div",{className:"flex justify-between items-center mb-6",children:[c.jsxs("div",{className:"join border border-base-300 rounded-lg",children:[c.jsx("button",{className:`join-item btn btn-md ${u==="front"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>u!=="front"&&b(),children:h.preview.front}),c.jsx("button",{className:`join-item btn btn-md ${u==="back"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>u!=="back"&&b(),children:h.preview.back})]}),c.jsxs("button",{className:"btn btn-ghost btn-md",onClick:b,children:[c.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:c.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"})}),c.jsx("span",{className:"hidden sm:inline",children:h.preview.flip})]})]}),c.jsxs("div",{className:"relative w-full overflow-visible",style:{aspectRatio:Zt,perspective:"1500px"},children:[ve&&c.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-base-300 rounded-lg z-10",children:c.jsx("span",{className:"loading loading-spinner loading-lg text-primary"})}),c.jsxs("div",{ref:d,className:`relative w-full h-full shadow-lg ${S&&Ft?T?"cursor-grabbing":"cursor-grab":""} ${ve?"opacity-0":"opacity-100"} transition-opacity duration-300`,style:{transformStyle:"preserve-3d",transition:"transform 0.6s ease-in-out, opacity 0.3s ease-in-out",transform:k?"rotateY(180deg)":"rotateY(0deg)"},onMouseDown:_t,onMouseMove:$t,onMouseUp:Xt,onMouseLeave:Vt,onTouchStart:Kt,onTouchMove:qt,onTouchEnd:Gt,onDragOver:x=>{x.preventDefault(),u==="front"&&N(!0)},onDragLeave:x=>{x.preventDefault(),N(!1)},onDrop:x=>{if(x.preventDefault(),N(!1),u==="front"&&t){const j=x.dataTransfer.files[0];j&&j.type.startsWith("image/")&&t(j)}},children:[c.jsx("canvas",{ref:y,className:"absolute inset-0 w-full h-full",style:{backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden"}}),c.jsx("canvas",{ref:v,className:"absolute inset-0 w-full h-full",style:{backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden",transform:"rotateY(180deg)"}}),u==="front"&&!o.original&&c.jsx("div",{className:`absolute flex flex-col items-center justify-center transition-colors duration-300 ease-in-out pointer-events-none ${C?"bg-primary/20":"hover:bg-base-content/5"}`,style:{left:`${(Y.front.portrait.x-Y.front.portrait.radiusX)/M.width*100}%`,top:`${(Y.front.portrait.y-Y.front.portrait.radiusY)/M.height*100}%`,width:`${Y.front.portrait.radiusX*2/M.width*100}%`,height:`${Y.front.portrait.radiusY*2/M.height*100}%`,borderRadius:"50%",backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden"},children:c.jsxs("button",{className:"btn btn-dash hover:btn-dash hover:border-base-content/60 flex flex-col items-center gap-0.5 sm:gap-1 h-auto py-1.5 px-2.5 sm:py-3 sm:px-4 bg-base-100/20 hover:bg-base-100/30",children:[c.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",className:"w-7 h-6 sm:w-10 sm:h-9 text-base-content/50",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round",children:[c.jsx("circle",{cx:"12",cy:"8",r:"4"}),c.jsx("path",{d:"M4 21c0-4 4-6 8-6s8 2 8 6"})]}),c.jsx("span",{className:"text-[10px] sm:text-xs text-center leading-tight whitespace-pre-line",children:n==="de"?`Foto
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("react/jsx-runtime"),g=require("react"),Jt=require("zustand"),Qt=require("zustand/middleware"),en=require("jspdf");var me=typeof document<"u"?document.currentScript:null;const tn=1024,st=1200,ue=new Map;let F=null,ct=null;function Je(e,t){return F||(F=document.createElement("canvas"),ct=F.getContext("2d",{willReadFrequently:!0})),(F.width!==e||F.height!==t)&&(F.width=e,F.height=t),ct}function fe(e){const t=ue.get(e);return t?Promise.resolve(t):new Promise((n,a)=>{const r=new Image;r.onload=()=>{if(ue.size>10){const l=ue.keys().next().value;l&&ue.delete(l)}ue.set(e,r),n(r)},r.onerror=()=>a(new Error("Failed to load image")),r.src=e})}function nn(){ue.clear()}async function ht(e,t=tn){const n=await fe(e),a=Math.max(n.width,n.height);if(a<=t)return e;const r=t/a,l=Math.round(n.width*r),i=Math.round(n.height*r),s=document.createElement("canvas"),o=s.getContext("2d");if(!o)throw new Error("Failed to get canvas context");return s.width=l,s.height=i,o.drawImage(n,0,0,l,i),s.toDataURL("image/jpeg",.9)}async function pt(e){const t=await fe(e),n=Math.max(t.width,t.height);if(n<=st){const o=document.createElement("canvas"),u=o.getContext("2d");if(!u)throw new Error("Failed to get canvas context");return o.width=t.width,o.height=t.height,u.drawImage(t,0,0),o.toDataURL("image/png")}const a=st/n,r=Math.round(t.width*a),l=Math.round(t.height*a),i=document.createElement("canvas"),s=i.getContext("2d");if(!s)throw new Error("Failed to get canvas context");return i.width=r,i.height=l,s.drawImage(t,0,0,r,l),i.toDataURL("image/png")}async function _e(e,t,n,a=0){const[r,l]=await Promise.all([fe(e),fe(t)]),i=Je(r.width,r.height);if(i.clearRect(0,0,r.width,r.height),n>0){const s=a*20;i.save(),i.globalAlpha=n,s>0&&(i.filter=`blur(${s}px)`),i.drawImage(l,0,0,r.width,r.height),i.restore()}return i.drawImage(r,0,0),F.toDataURL("image/png")}async function ft(e,t=.5,n=40){const a=await fe(e),r=Je(a.width,a.height);r.clearRect(0,0,a.width,a.height),r.drawImage(a,0,0);const l=r.getImageData(0,0,a.width,a.height),i=l.data,s=new Uint32Array(i.buffer),o=1+t*.8,u=1-t,m=n%360/360;for(let f=0;f<s.length;f++){const p=s[f],h=p&255,y=p>>8&255,I=p>>16&255,d=p>>24&255;if(d===0)continue;let E=(((77*h+150*y+29*I>>8)/255-.5)*o+.5)*255;E<0?E=0:E>255&&(E=255);const v=E/255,S=.12,[R,P,D]=bt(m,S,v),j=h*u+R*t|0,L=y*u+P*t|0,B=I*u+D*t|0;s[f]=d<<24|B<<16|L<<8|j}return r.putImageData(l,0,0),F.toDataURL("image/png")}function an(e,t,n){e/=255,t/=255,n/=255;const a=Math.max(e,t,n),r=Math.min(e,t,n),l=(a+r)/2;let i=0,s=0;if(a!==r){const o=a-r;switch(s=l>.5?o/(2-a-r):o/(a+r),a){case e:i=((t-n)/o+(t<n?6:0))/6;break;case t:i=((n-e)/o+2)/6;break;case n:i=((e-t)/o+4)/6;break}}return[i,s,l]}function bt(e,t,n){if(t===0){const i=Math.round(n*255);return[i,i,i]}const a=(i,s,o)=>(o<0&&(o+=1),o>1&&(o-=1),o<1/6?i+(s-i)*6*o:o<1/2?s:o<2/3?i+(s-i)*(2/3-o)*6:i),r=n<.5?n*(1+t):n+t-n*t,l=2*n-r;return[Math.round(a(l,r,e+1/3)*255),Math.round(a(l,r,e)*255),Math.round(a(l,r,e-1/3)*255)]}const rn=29,on=5;async function xt(e,t){if(Math.abs(t-rn)<=on)return e;const n=await fe(e),a=Je(n.width,n.height);a.clearRect(0,0,n.width,n.height),a.drawImage(n,0,0);const r=a.getImageData(0,0,n.width,n.height),l=r.data,i=new Uint32Array(l.buffer),s=t%360/360,o=20/360,u=45/360,m=i.length;for(let f=0;f<m;f++){const p=i[f],h=p&255,y=p>>8&255,I=p>>16&255,d=p>>24&255;if(d===0)continue;const[k,E,v]=an(h,y,I);if(E<.08||k<o||k>u)continue;const S=s,R=Math.min(E,.05),[P,D,j]=bt(S,R,v);i[f]=d<<24|j<<16|D<<8|P}return a.putImageData(r,0,0),F.toDataURL("image/png")}const Se="money-generator-portrait",Pe="money-generator-bg-removed";async function sn(e){try{if(localStorage.removeItem(Se),!e)return;const t=await pt(e);try{localStorage.setItem(Se,t)}catch(n){console.warn("Could not persist portrait to localStorage:",n)}}catch(t){console.warn("Error processing portrait for storage:",t)}}async function cn(e){try{if(localStorage.removeItem(Pe),!e)return;const t=await pt(e);try{localStorage.setItem(Pe,t)}catch(n){console.warn("Could not persist bg-removed image to localStorage:",n)}}catch(t){console.warn("Error processing bg-removed image for storage:",t)}}function ln(){try{return localStorage.getItem(Se)}catch{return null}}function un(){try{return localStorage.getItem(Pe)}catch{return null}}function dn(){try{localStorage.removeItem(Se),localStorage.removeItem(Pe)}catch{}}function gn(){return(typeof navigator<"u"?navigator.language:"de").toLowerCase().startsWith("de")?"de":"en"}const Re=gn(),lt={personalInfo:{name:"",email:"",phone:""},voucherConfig:{hours:1,description:"",language:Re,templateHue:29},portrait:{original:null,enhanced:null,useEnhanced:!1,zoom:1,panX:0,panY:0,rawImage:null,bgRemovedImage:null,bgRemoved:!1,bgOpacity:0,bgBlur:0,engravingIntensity:0},currentSide:"front",isEnhancing:!1,isExporting:!1,appLanguage:Re},w=Jt.create()(Qt.persist(e=>({...lt,setPersonalInfo:t=>e(n=>({personalInfo:{...n.personalInfo,...t}})),setVoucherConfig:t=>e(n=>({voucherConfig:{...n.voucherConfig,...t}})),setPortrait:(t,n=null)=>(sn(t),e(a=>({portrait:{...a.portrait,original:t,enhanced:n,useEnhanced:!1,zoom:a.portrait.original&&t?a.portrait.zoom:1,panX:a.portrait.original&&t?a.portrait.panX:0,panY:a.portrait.original&&t?a.portrait.panY:0}}))),setEnhancedPortrait:t=>e(n=>({portrait:{...n.portrait,enhanced:t,useEnhanced:t!==null}})),toggleUseEnhanced:()=>e(t=>({portrait:{...t.portrait,useEnhanced:t.portrait.enhanced?!t.portrait.useEnhanced:!1}})),setPortraitZoom:t=>e(n=>({portrait:{...n.portrait,zoom:t}})),setPortraitPan:(t,n)=>e(a=>({portrait:{...a.portrait,panX:t,panY:n}})),setPortraitRawImage:t=>e(n=>({portrait:{...n.portrait,rawImage:t}})),setPortraitBgRemoved:(t,n)=>(n!==void 0&&cn(n),e(a=>({portrait:{...a.portrait,bgRemoved:t,bgRemovedImage:n!==void 0?n:a.portrait.bgRemovedImage}}))),setPortraitBgOpacity:t=>e(n=>({portrait:{...n.portrait,bgOpacity:t}})),setPortraitBgBlur:t=>e(n=>({portrait:{...n.portrait,bgBlur:t}})),setPortraitEngravingIntensity:t=>e(n=>({portrait:{...n.portrait,engravingIntensity: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}),setAppLanguage:t=>e({appLanguage:t}),setBillLanguage:t=>e(n=>({voucherConfig:{...n.voucherConfig,language:t}})),setHours:t=>e(n=>({voucherConfig:{...n.voucherConfig,hours:t}})),setTemplateHue:t=>e(n=>({voucherConfig:{...n.voucherConfig,templateHue:t}})),reset:()=>(dn(),e(lt))}),{name:"money-generator-storage",migrate:e=>{const t=e;return t!=null&&t.voucherConfig&&(t.voucherConfig.templateHue=29,t.voucherConfig.hours=1,t.voucherConfig.language=Re),t&&(t.appLanguage=Re),t},version:1,partialize:e=>({personalInfo:e.personalInfo,voucherConfig:{...e.voucherConfig,templateHue:29},appLanguage:e.appLanguage,portrait:{original:null,enhanced:null,useEnhanced:e.portrait.useEnhanced,zoom:e.portrait.zoom,panX:e.portrait.panX,panY:e.portrait.panY,rawImage:null,bgRemovedImage:null,bgRemoved:e.portrait.bgRemoved,bgOpacity:e.portrait.bgOpacity,bgBlur:e.portrait.bgBlur,engravingIntensity:e.portrait.engravingIntensity},currentSide:"front",isEnhancing:!1,isExporting:!1})}));if(typeof window<"u"){const e=ln(),t=un();e&&setTimeout(()=>{const n=w.getState();if(!n.portrait.original){const a=n.portrait.bgRemoved,r=t!==null;w.setState({portrait:{...n.portrait,original:e,rawImage:e,bgRemovedImage:t,bgRemoved:a&&r,bgOpacity:a&&r?n.portrait.bgOpacity:0,bgBlur:a&&r?n.portrait.bgBlur:0}})}},0)}const mn={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?",billLanguage:"Schein-Sprache",billLanguageGerman:"Deutsch",billLanguageEnglish:"Englisch"},billColor:{title:"Scheinfarbe",label:"Farbton"}},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 {bannerText} meiner Zeit oder ein gleichwertiges Dankeschön.",bannerText:{1:"eine Stunde",5:"fünf Stunden",10:"zehn Stunden"}}},hn={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?",billLanguage:"Bill Language",billLanguageGerman:"German",billLanguageEnglish:"English"},billColor:{title:"Bill Color",label:"Hue"}},preview:{front:"Front",back:"Back",flip:"Flip"},export:{button:"Download as PDF",exporting:"Creating PDF...",success:"Download started!"},bill:{descriptionText:"For this voucher, you will receive {bannerText} of my time or an equivalent appreciation in return.",bannerText:{1:"one hour",5:"five hours",10:"ten hours"}}},pn={de:mn,en:hn};function ne(e){return pn[e]}function Qe(e,t,n){if(n&&n.trim())return n;const a=ne(e),r=a.bill.bannerText[t]||a.bill.bannerText[1];return a.bill.descriptionText.replace("{bannerText}",r)}function fn(e){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)}function bn(e){return e.replace(/\D/g,"").length>=6}function xn({focusField:e,onFocused:t,onFormFocusChange:n}={}){const a=w(d=>d.appLanguage),r=w(d=>d.personalInfo),l=w(d=>d.setPersonalInfo),i=ne(a),[s,o]=g.useState(!1),[u,m]=g.useState(!1),f=s&&r.email.trim()&&!fn(r.email),p=u&&r.phone.trim()&&!bn(r.phone),h=g.useRef(null),y=g.useRef(null),I=g.useRef(null);return g.useEffect(()=>{if(e){const d=e==="name"?h:e==="email"?y:I;setTimeout(()=>{var k,E;(k=d.current)==null||k.click(),(E=d.current)==null||E.focus(),setTimeout(()=>{var v;(v=d.current)==null||v.scrollIntoView({behavior:"smooth",block:"center"})},300),t==null||t()},100)}},[e,t]),c.jsxs("div",{className:"space-y-4",children:[c.jsxs("div",{className:"form-control",children:[c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text font-medium",children:i.form.personalInfo.name})}),c.jsx("input",{ref:h,type:"text",name:"name",autoComplete:"name",placeholder:i.form.personalInfo.namePlaceholder,className:"input input-bordered w-full input-md",value:r.name,onChange:d=>l({name:d.target.value}),onFocus:d=>{n==null||n(!0),setTimeout(()=>d.target.scrollIntoView({behavior:"smooth",block:"center"}),300)},onBlur:()=>n==null?void 0:n(!1)})]}),c.jsxs("div",{className:"form-control",children:[c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text font-medium",children:i.form.personalInfo.email})}),c.jsx("input",{ref:y,type:"email",name:"email",autoComplete:"email",placeholder:i.form.personalInfo.emailPlaceholder,className:`input input-bordered w-full input-md ${f?"input-error":""}`,value:r.email,onChange:d=>l({email:d.target.value}),onFocus:d=>{n==null||n(!0),setTimeout(()=>d.target.scrollIntoView({behavior:"smooth",block:"center"}),300)},onBlur:()=>{o(!0),n==null||n(!1)}}),f&&c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text-alt text-error",children:a==="de"?"Bitte gib eine gültige E-Mail-Adresse ein":"Please enter a valid email address"})})]}),c.jsxs("div",{className:"form-control",children:[c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text font-medium",children:i.form.personalInfo.phone})}),c.jsx("input",{ref:I,type:"tel",name:"phone",autoComplete:"tel",placeholder:i.form.personalInfo.phonePlaceholder,className:`input input-bordered w-full input-md ${p?"input-error":""}`,value:r.phone,onChange:d=>l({phone:d.target.value}),onFocus:d=>{n==null||n(!0),setTimeout(()=>d.target.scrollIntoView({behavior:"smooth",block:"center"}),300)},onBlur:()=>{m(!0),n==null||n(!1)}}),p&&c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text-alt text-error",children:a==="de"?"Bitte gib eine gültige Telefonnummer ein":"Please enter a valid phone number"})})]})]})}const wn="https://api.stability.ai/v1/generation",yn="https://api.stability.ai/v2beta/stable-image/edit/remove-background",wt="stability_api_key";let be=null;function vn(e){be=e}function In(){return be}function kn(){return be!==null}const Tn={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"},ut=[{width:1024,height:1024},{width:1152,height:896},{width:1216,height:832},{width:1344,height:768},{width:1536,height:640},{width:640,height:1536},{width:768,height:1344},{width:832,height:1216},{width:896,height:1152}];function En(e,t){const n=e/t;let a=ut[0],r=1/0;for(const l of ut){const i=l.width/l.height,s=Math.abs(n-i);s<r&&(r=s,a=l)}return a}function Sn(e){return new Promise((t,n)=>{const a=new Image;a.onload=()=>{const r=En(a.width,a.height),l=document.createElement("canvas");l.width=r.width,l.height=r.height;const i=l.getContext("2d");if(!i){n(new Error("Failed to get canvas context"));return}const s=a.width/a.height,o=r.width/r.height;let u=0,m=0,f=a.width,p=a.height;s>o?(f=a.height*o,u=(a.width-f)/2):(p=a.width/o,m=(a.height-p)/2),i.drawImage(a,u,m,f,p,0,0,r.width,r.height),t(l.toDataURL("image/png"))},a.onerror=()=>n(new Error("Failed to load image")),a.src=e})}function yt(e){var i;const t=e.split(","),n=((i=t[0].match(/:(.*?);/))==null?void 0:i[1])||"image/png",a=atob(t[1]),r=a.length,l=new Uint8Array(r);for(let s=0;s<r;s++)l[s]=a.charCodeAt(s);return new Blob([l],{type:n})}function Be(){var t;const e=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:me&&me.tagName.toUpperCase()==="SCRIPT"&&me.src||new URL("index.cjs",document.baseURI).href}<"u"&&"sk-7mEKklrqaltdtgbX0VoZbkA8E1cl939Spn75jSIYRvp1BW0b"||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(wt):null}function vt(e){localStorage.setItem(wt,e)}function Te(){return be?!0:Be()!==null}async function Pn(e){const t=Be();if(!t)throw new Error("No Stability AI API key configured");const{imageDataUrl:n,style:a,strength:r=.35}=e,l=await Sn(n),i=yt(l),s=new FormData;s.append("init_image",i,"portrait.png"),s.append("init_image_mode","IMAGE_STRENGTH"),s.append("image_strength",String(1-r)),s.append("text_prompts[0][text]",Tn[a]),s.append("text_prompts[0][weight]","1"),s.append("cfg_scale","7"),s.append("samples","1"),s.append("steps","30");const u=await fetch(`${wn}/stable-diffusion-xl-1024-v1-0/image-to-image`,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"},body:s});if(!u.ok){const f=await u.text();throw console.error("Stability AI error:",f),u.status===401?new Error("Invalid API key"):u.status===402?new Error("Insufficient credits"):u.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${u.status}`)}const m=await u.json();if(!m.artifacts||m.artifacts.length===0)throw new Error("No image generated");return`data:image/png;base64,${m.artifacts[0].base64}`}async function It(e){if(be){const i=await fetch(be,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({imageDataUrl:e})});if(!i.ok){const o=await i.json().catch(()=>({}));throw new Error(o.error||`API error: ${i.status}`)}return(await i.json()).imageDataUrl}const t=Be();if(!t)throw new Error("No Stability AI API key configured");const n=yt(e),a=new FormData;a.append("image",n,"image.png"),a.append("output_format","png");const r=await fetch(yn,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"image/*"},body:a});if(!r.ok){const i=await r.text();throw console.error("Stability AI remove background error:",i),r.status===401?new Error("Invalid API key"):r.status===402?new Error("Insufficient credits"):r.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${r.status}`)}const l=await r.blob();return new Promise((i,s)=>{const o=new FileReader;o.onload=()=>i(o.result),o.onerror=()=>s(new Error("Failed to read result")),o.readAsDataURL(l)})}function Rn(){const[e,t]=g.useState(!1),[n,a]=g.useState(!1),[r,l]=g.useState(null),[i,s]=g.useState(()=>Te());g.useEffect(()=>{s(Te());const p=setTimeout(()=>{s(Te())},150);return()=>clearTimeout(p)},[]);const o=g.useCallback(()=>l(null),[]),u=g.useCallback(p=>{vt(p),s(!0),l(null)},[]),m=g.useCallback(async(p,h=.5,y=40)=>{t(!0),l(null);try{return await ft(p,h,y)}catch(I){const d=I instanceof Error?I.message:"Enhancement failed";throw l(d),I}finally{t(!1)}},[]),f=g.useCallback(async p=>{a(!0),l(null);try{return await It(p)}catch(h){const y=h instanceof Error?h.message:"Background removal failed";throw l(y),h}finally{a(!1)}},[]);return{enhance:m,removeBg:f,isEnhancing:e,isRemovingBg:n,error:r,hasKey:i,setApiKey:u,clearError:o}}function kt({isOpen:e,onClose:t,onSubmit:n}){const a=w(u=>u.appLanguage),[r,l]=g.useState("");if(!e)return null;const i=u=>{u.preventDefault(),r.trim()&&(n(r.trim()),l(""),t())},o={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."}}[a];return c.jsxs("dialog",{className:"modal modal-open",children:[c.jsxs("div",{className:"modal-box",children:[c.jsx("h3",{className:"font-bold text-lg",children:o.title}),c.jsx("p",{className:"py-4 text-sm opacity-80",children:o.description}),c.jsxs("form",{onSubmit:i,children:[c.jsxs("div",{className:"form-control",children:[c.jsx("input",{type:"password",placeholder:o.placeholder,className:"input input-bordered w-full",value:r,onChange:u=>l(u.target.value),autoFocus:!0}),c.jsx("label",{className:"label",children:c.jsx("span",{className:"label-text-alt",children:o.hint})})]}),c.jsxs("div",{className:"modal-action",children:[c.jsx("button",{type:"button",className:"btn btn-ghost",onClick:t,children:o.cancel}),c.jsx("button",{type:"submit",className:"btn btn-primary",disabled:!r.trim(),children:o.submit})]})]})]}),c.jsx("form",{method:"dialog",className:"modal-backdrop",children:c.jsx("button",{onClick:t,children:"close"})})]})}function we({min:e,max:t,step:n,value:a,onChange:r,className:l="",disabled:i=!1}){const s=g.useRef(null),o=g.useRef(null),u=g.useRef(!1),[m,f]=g.useState(!1),p=(a-e)/(t-e)*100,h=g.useCallback(v=>{if(!s.current)return a;const S=s.current.getBoundingClientRect(),R=Math.max(0,Math.min(1,(v-S.left)/S.width)),P=t-e,D=e+R*P,j=Math.round(D/n)*n;return Math.max(e,Math.min(t,j))},[e,t,n,a]),y=g.useCallback(v=>{if(i)return;const S=v.touches[0];o.current={x:S.clientX,y:S.clientY,value:a,decided:!1},u.current=!1},[a,i]),I=g.useCallback(v=>{if(i||!o.current)return;const S=v.touches[0],R=Math.abs(S.clientX-o.current.x),P=Math.abs(S.clientY-o.current.y);if(!o.current.decided){if(R<8&&P<8)return;if(o.current.decided=!0,P>R){o.current=null;return}u.current=!0,f(!0)}if(u.current){const D=h(S.clientX);D!==a&&r(D)}},[i,h,r,a]),d=g.useCallback(v=>{if(o.current&&!o.current.decided){const S=v.changedTouches[0];if(S){const R=h(S.clientX);R!==a&&r(R)}}o.current=null,u.current=!1,f(!1)},[h,r,a]);g.useEffect(()=>{const v=s.current;if(!v)return;const S=R=>{u.current&&R.preventDefault()};return v.addEventListener("touchmove",S,{passive:!1}),()=>{v.removeEventListener("touchmove",S)}},[]);const k=g.useCallback(v=>{if(i)return;const S=h(v.clientX);r(S),f(!0);const R=D=>{const j=h(D.clientX);r(j)},P=()=>{f(!1),document.removeEventListener("mousemove",R),document.removeEventListener("mouseup",P)};document.addEventListener("mousemove",R),document.addEventListener("mouseup",P)},[i,h,r]),E=`calc(10px + (100% - 20px) * ${p/100})`;return c.jsxs("div",{ref:s,className:`relative h-10 flex items-center cursor-pointer overflow-visible ${i?"opacity-50 cursor-not-allowed":""}`,onTouchStart:y,onTouchMove:I,onTouchEnd:d,onMouseDown:k,children:[c.jsx("div",{className:"absolute h-2 bg-base-300 rounded-full inset-x-0"}),c.jsx("div",{className:`absolute h-2 rounded-full transition-colors ${l.includes("range-primary")?"bg-primary":l.includes("range-secondary")?"bg-secondary":"bg-primary"}`,style:{left:0,width:E}}),c.jsx("div",{className:`absolute w-5 h-5 rounded-full bg-base-100 border-2 shadow-md transition-transform ${m?"scale-110":""} ${l.includes("range-primary")?"border-primary":l.includes("range-secondary")?"border-secondary":"border-primary"}`,style:{left:E,transform:"translateX(-50%)"}})]})}function Ln(){const e=w(b=>b.appLanguage),t=w(b=>b.portrait),n=w(b=>b.setPortrait),a=w(b=>b.setPortraitZoom),r=w(b=>b.setPortraitPan),l=w(b=>b.setPortraitRawImage),i=w(b=>b.setPortraitBgRemoved),s=w(b=>b.setPortraitBgOpacity),o=w(b=>b.setPortraitBgBlur),u=w(b=>b.setPortraitEngravingIntensity),{enhance:m,removeBg:f,isEnhancing:p,isRemovingBg:h,error:y,hasKey:I,setApiKey:d}=Rn(),k=ne(e),E=g.useRef(null),[v,S]=g.useState(!1),[R,P]=g.useState(!1),D=g.useRef(null),j=g.useRef(null),L=t.rawImage,B=t.bgRemovedImage,Y=t.bgRemoved,q=t.bgOpacity,H=t.bgBlur,O=t.engravingIntensity;g.useEffect(()=>{t.original&&!t.rawImage&&l(t.original)},[t.original,t.rawImage,l]),g.useEffect(()=>()=>{D.current&&clearTimeout(D.current),j.current&&clearTimeout(j.current)},[]);const Z=w(b=>b.voucherConfig.templateHue),oe=g.useRef(Z),K=g.useCallback(async b=>{if(!b.type.startsWith("image/"))return;const T=new FileReader;T.onload=async M=>{var W;const A=(W=M.target)==null?void 0:W.result,G=await ht(A);nn(),l(G),n(G),a(1),r(0,0),i(!1,null),s(0),o(0),u(0)},T.readAsDataURL(b)},[n,l,a,r,i,s,o,u]),J=g.useCallback(b=>{b.preventDefault(),S(!1);const T=b.dataTransfer.files[0];T&&K(T)},[K]),V=g.useCallback(b=>{b.preventDefault(),S(!0)},[]),te=g.useCallback(b=>{b.preventDefault(),S(!1)},[]),ie=()=>{var b;(b=E.current)==null||b.click()},Ae=b=>{var M;const T=(M=b.target.files)==null?void 0:M[0];T&&K(T)},Q=g.useCallback(async(b,T,M)=>{try{return await m(b,T,M)}catch(A){return console.error("Enhancement failed:",A),b}},[m]),ye=g.useCallback(async b=>{try{const T=await f(b);return i(!0,T),T}catch(T){return console.error("Background removal failed:",T),b}},[f,i]),ee=g.useCallback(async()=>{const b=w.getState(),T=b.portrait,M=b.voucherConfig.templateHue;if(!T.rawImage)return;let A;T.bgRemoved&&T.bgRemovedImage?A=await _e(T.bgRemovedImage,T.rawImage,T.bgOpacity,T.bgBlur):A=T.rawImage,T.engravingIntensity>0&&(A=await Q(A,T.engravingIntensity,M)),n(A)},[Q,n]);g.useEffect(()=>{if(oe.current===Z)return;oe.current=Z;const b=w.getState().portrait;b.engravingIntensity>0&&b.rawImage&&(D.current&&clearTimeout(D.current),D.current=setTimeout(ee,150))},[Z,ee]);const De=async()=>{if(!L)return;if(!Y&&!I){P(!0);return}if(!Y){const T=await ye(L),M=w.getState(),A=M.portrait,G=M.voucherConfig.templateHue;let W=await _e(T,L,A.bgOpacity,A.bgBlur);A.engravingIntensity>0&&(W=await Q(W,A.engravingIntensity,G)),n(W)}else{i(!1,null);const T=w.getState(),M=T.portrait.engravingIntensity,A=T.voucherConfig.templateHue;if(M>0){const G=await Q(L,M,A);n(G)}else n(L)}},xe=b=>{u(b),D.current&&clearTimeout(D.current),L&&(D.current=setTimeout(ee,150))},He=async b=>{if(d(b),!L)return;const T=await ye(L),M=w.getState(),A=M.portrait,G=M.voucherConfig.templateHue;let W=await _e(T,L,A.bgOpacity,A.bgBlur);A.engravingIntensity>0&&(W=await Q(W,A.engravingIntensity,G)),n(W)},ve=b=>{s(b),j.current&&clearTimeout(j.current),!(!L||!B)&&(j.current=setTimeout(ee,150))},Ie=b=>{o(b),j.current&&clearTimeout(j.current),!(!L||!B)&&(j.current=setTimeout(ee,150))};return c.jsxs("div",{className:"space-y-4",children:[t.original?c.jsxs("div",{className:"flex flex-col space-y-4",children:[c.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[c.jsxs("div",{className:"form-control w-full",children:[c.jsxs("label",{className:"label",children:[c.jsx("span",{className:"label-text",children:k.form.portrait.zoom}),c.jsxs("span",{className:"label-text-alt",children:[Math.round(t.zoom*100),"%"]})]}),c.jsx(we,{min:.5,max:2,step:.05,value:t.zoom,onChange:a,className:"range range-primary range-sm"})]}),c.jsxs("div",{className:"form-control w-full",children:[c.jsxs("label",{className:"label",children:[c.jsxs("span",{className:"label-text flex items-center gap-2",children:[e==="de"?"Farbanpassung":"Color adjustment",p&&c.jsx("span",{className:"loading loading-spinner loading-xs"})]}),c.jsxs("span",{className:"label-text-alt",children:[Math.round(O*100),"%"]})]}),c.jsx(we,{min:0,max:1,step:.05,value:O,onChange:xe,className:"range range-secondary range-sm",disabled:p||!L})]})]}),Y?c.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[c.jsxs("div",{className:"form-control w-full",children:[c.jsxs("label",{className:"label",children:[c.jsx("span",{className:"label-text",children:e==="de"?"Hintergrund":"Background"}),c.jsxs("span",{className:"label-text-alt",children:[Math.round(q*100),"%"]})]}),c.jsx(we,{min:0,max:1,step:.05,value:q,onChange:ve,className:"range range-primary range-sm"})]}),c.jsxs("div",{className:"form-control w-full",children:[c.jsxs("label",{className:"label",children:[c.jsx("span",{className:"label-text",children:e==="de"?"Unschärfe":"Blur"}),c.jsxs("span",{className:"label-text-alt",children:[Math.round(H*100),"%"]})]}),c.jsx(we,{min:0,max:1,step:.05,value:H,onChange:Ie,className:"range range-primary range-sm",disabled:q===0})]})]}):c.jsx("div",{className:"flex justify-center",children:c.jsx("button",{className:"btn btn-ghost btn gap-2 text-base-content/70",onClick:De,disabled:h||!L,children:h?c.jsxs(c.Fragment,{children:[e==="de"?"Hintergrund wird entfernt":"Removing background",c.jsx("span",{className:"loading loading-dots loading-xs"})]}):c.jsxs(c.Fragment,{children:[c.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:c.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M9.813 15.904L9 18.75l-.813-2.846a4.5 4.5 0 00-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 003.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 003.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 00-3.09 3.09zM18.259 8.715L18 9.75l-.259-1.035a3.375 3.375 0 00-2.455-2.456L14.25 6l1.036-.259a3.375 3.375 0 002.455-2.456L18 2.25l.259 1.035a3.375 3.375 0 002.456 2.456L21.75 6l-1.035.259a3.375 3.375 0 00-2.456 2.456zM16.894 20.567L16.5 21.75l-.394-1.183a2.25 2.25 0 00-1.423-1.423L13.5 18.75l1.183-.394a2.25 2.25 0 001.423-1.423l.394-1.183.394 1.183a2.25 2.25 0 001.423 1.423l1.183.394-1.183.394a2.25 2.25 0 00-1.423 1.423z"})}),e==="de"?"Hintergrund entfernen":"Remove background",!I&&c.jsx("span",{className:"badge badge-sm badge-outline",children:"API"})]})})}),y&&c.jsxs("div",{className:"alert alert-warning text-sm py-2",children:[c.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:c.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"})}),c.jsx("span",{children:y})]})]}):c.jsxs("div",{className:`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${h?"border-primary bg-primary/10 pointer-events-none":v?"border-primary bg-primary/10":"border-base-300 hover:border-primary hover:bg-base-200"}`,onDrop:J,onDragOver:V,onDragLeave:te,onClick:ie,children:[c.jsx("input",{ref:E,type:"file",accept:"image/*",className:"hidden",onChange:Ae}),h?c.jsxs("div",{className:"flex flex-col items-center gap-2",children:[c.jsx("span",{className:"loading loading-spinner loading-lg text-primary"}),c.jsx("p",{className:"font-medium",children:e==="de"?"Hintergrund wird entfernt...":"Removing background..."})]}):c.jsxs("div",{className:"flex flex-col items-center gap-2",children:[c.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:c.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"})}),c.jsx("p",{className:"font-medium",children:k.form.portrait.upload}),c.jsx("p",{className:"text-sm text-base-content/60",children:k.form.portrait.dragDrop})]})]}),c.jsx(kt,{isOpen:R,onClose:()=>P(!1),onSubmit:He})]})}function Bn(){const e=w(s=>s.appLanguage),t=w(s=>s.voucherConfig.language),n=w(s=>s.voucherConfig.hours);w(s=>s.voucherConfig.templateHue);const a=w(s=>s.setBillLanguage),r=w(s=>s.setHours);w(s=>s.setTemplateHue);const l=ne(e),i=[1,5,10];return c.jsxs("div",{className:"space-y-4",children:[c.jsx("div",{className:"form-control",children:c.jsxs("div",{className:"flex items-center justify-between gap-2",children:[c.jsx("span",{className:"label-text font-medium",children:l.form.voucher.billLanguage}),c.jsxs("div",{className:"join border border-base-300 rounded-lg shadow",children:[c.jsx("button",{className:`join-item btn btn-md ${t==="de"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>a("de"),children:l.form.voucher.billLanguageGerman}),c.jsx("button",{className:`join-item btn btn-md ${t==="en"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>a("en"),children:l.form.voucher.billLanguageEnglish})]})]})}),c.jsx("div",{className:"form-control",children:c.jsxs("div",{className:"flex items-center justify-between gap-2",children:[c.jsx("span",{className:"label-text font-medium",children:l.form.voucher.hours}),c.jsx("div",{className:"join border border-base-300 rounded-lg shadow",children:i.map(s=>c.jsxs("button",{className:`join-item btn btn-md ${n===s?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>r(s),children:[s,c.jsxs("span",{className:"hidden sm:inline",children:[" ",s===1?l.form.voucher.hourLabel:l.form.voucher.hoursLabel]})]},s))})]})}),!1]})}const ze=new Map,le=new Map;async function C(e){return ze.has(e)?ze.get(e):new Promise((t,n)=>{const a=new Image;a.crossOrigin="anonymous",a.onload=()=>{ze.set(e,a),t(a)},a.onerror=n,a.src=e})}function ce(e,t,n,a){e.drawImage(t,0,0,n,a)}async function Tt(e,t,n,a){if(t>=155&&t<=165)return C(e);const r=`${e}:${t}:${n}x${a}`;if(le.has(r))return C(le.get(r));const l=await C(e),i=document.createElement("canvas");i.width=n,i.height=a;const s=i.getContext("2d");if(!s)throw new Error("Failed to get canvas context");s.drawImage(l,0,0,n,a);const o=i.toDataURL("image/png"),u=await xt(o,t);if(le.size>20){const m=le.keys().next().value;m&&le.delete(m)}return le.set(r,u),C(u)}function Cn(e,t,n,a,r,l="de"){e.save(),e.beginPath(),e.ellipse(t,n,a,r,0,0,Math.PI*2),e.closePath(),e.setLineDash([20,10]),e.strokeStyle="rgba(100, 100, 100, 0.4)",e.lineWidth=3,e.stroke(),e.restore()}function Et(e,t,n,a,r,l,i=1,s=0,o=0){e.save(),e.beginPath(),e.ellipse(n,a,r,l,0,0,Math.PI*2),e.closePath(),e.clip();const u=t.width/t.height,m=r/l,f=r*2,p=l*2;let h,y;u>m?(y=p,h=p*u):(h=f,y=f/u),h*=i,y*=i;const I=Math.max(0,(h-f)/2),d=Math.max(0,(y-p)/2),k=n-h/2+s*I,E=a-y/2+o*d;e.drawImage(t,k,E,h,y),e.restore()}function et(e,t,n,a="#2a3a2a"){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()}function St(e,t,n,a="#2a3a2a"){e.save(),e.font=`${n.fontSize}px "Times New Roman", serif`,e.textAlign=n.align||"center",e.textBaseline="top",e.fillStyle=a;const r=n.maxWidth||400,l=n.lineHeight||n.fontSize*1.4,i=t.split(" "),s=[];let o="";for(const f of i){const p=o?`${o} ${f}`:f;e.measureText(p).width>r&&o?(s.push(o),o=f):o=p}o&&s.push(o);const u=s.length*l;let m=n.y-u/2;for(const f of s)e.fillText(f,n.x,m),m+=l;e.restore()}function Pt(e,t,n,a,r,l="#2a3a2a"){e.save(),e.font=`${r.fontSize}px "Times New Roman", serif`,e.textAlign=r.align||"center",e.textBaseline="middle",e.fillStyle=l;const i=r.lineHeight||r.fontSize*1.8,s=[t,n,a].filter(Boolean),o=(s.length-1)*i;let u=r.y-o/2;for(const m of s)m&&(e.fillText(m,r.x,u),u+=i);e.restore()}function Nn(e,t,n,a="#2a3a2a"){e.save(),e.strokeStyle=a,e.lineWidth=Math.max(2,t.labelFontSize/16),e.beginPath(),e.moveTo(t.x-t.width/2,t.y),e.lineTo(t.x+t.width/2,t.y),e.stroke(),e.font=`${t.labelFontSize}px "Times New Roman", serif`,e.textAlign="center",e.textBaseline="top",e.fillStyle=a,e.fillText(n,t.x,t.y+t.labelFontSize*.3),e.restore()}async function Rt(e,t,n,a,r,l,i,s,o,u=1,m=0,f=0,p=0,h=1,y="de"){const I=e.getContext("2d");if(!I)return;const d=document.createElement("canvas");d.width=s,d.height=o;const k=d.getContext("2d");if(!k)return;k.clearRect(0,0,s,o);const E=await Tt(t,p,s,o);ce(k,E,s,o);const v=await C(n);if(ce(k,v,s,o),r)try{const P=await C(r);Et(k,P,i.portrait.x,i.portrait.y,i.portrait.radiusX,i.portrait.radiusY,u,m,f)}catch(P){console.error("Failed to load portrait:",P)}else Cn(k,i.portrait.x,i.portrait.y,i.portrait.radiusX,i.portrait.radiusY,y);const S=await C(a);ce(k,S,s,o);const R=s/3633;At(k,h,y,R),l&&et(k,l,i.namePlate),e.width=s,e.height=o,I.drawImage(d,0,0)}async function Lt(e,t,n,a,r,l,i,s,o,u,m,f=0,p=1,h="de"){const y=e.getContext("2d");if(!y)return;const I=document.createElement("canvas");I.width=u,I.height=m;const d=I.getContext("2d");if(!d)return;d.clearRect(0,0,u,m);const k=await Tt(t,f,u,m);ce(d,k,u,m);const E=await C(n);ce(d,E,u,m);const v=await C(a);ce(d,v,u,m);const S=u/3633;if(At(d,p,h,S),o.contactInfo&&(r||l||i)&&Pt(d,r,l,i,o.contactInfo),o.description&&s&&St(d,s,o.description),r&&et(d,r,o.namePlate),o.signature){const R=h==="de"?"Unterschrift":"Signature";Nn(d,o.signature,R)}e.width=u,e.height=m,y.drawImage(I,0,0)}const he=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:me&&me.tagName.toUpperCase()==="SCRIPT"&&me.src||new URL("index.cjs",document.baseURI).href}<"u"&&"/"||"/",X={background:`${he}templates/background.webp`,frontFrame:`${he}templates/front_frame.webp`,backFrame:`${he}templates/back_frame.webp`},pe={1:`${he}templates/1.png`,5:`${he}templates/5.png`,10:`${he}templates/10.png`},Bt={de:{banner:{1:"EINE STUNDE",5:"FÜNF STUNDEN",10:"ZEHN STUNDEN"}},en:{banner:{1:"ONE HOUR",5:"FIVE HOURS",10:"TEN HOURS"}}},ae=3633,re=1920,Ce=.5,jn=Math.round(ae*Ce),An=Math.round(re*Ce),Ct=320,Nt=335,$={badges:{topLeft:{x:286,y:235},topRight:{x:3340,y:230},bottomLeft:{x:282,y:1665},bottomRight:{x:3345,y:1665}},banner:{centerX:1816,centerY:3820,radius:3610,fontSize:103,color:"#2a3a2a"}},Ee=new Map,se=new Map,Ve=new Map,Ge=new Map,Ke=new Map;function jt(e,t,n,a,r,l,i){e.save(),e.font=`900 ${l}px "Times New Roman", Georgia, serif`,e.fillStyle=i,e.textAlign="center",e.textBaseline="middle";const o=e.measureText(t).width/r,u=-Math.PI/2-o/2,m=t.split(""),f=[];for(const h of m)f.push(e.measureText(h).width);let p=u;for(let h=0;h<m.length;h++){const y=m[h],I=f[h],d=p+I/2/r,k=n+r*Math.cos(d),E=a+r*Math.sin(d);e.save(),e.translate(k,E),e.rotate(d+Math.PI/2),e.fillText(y,0,0),e.restore(),p+=I/r}e.restore()}let _={background:null,frontFrame:null,backFrame:null,badges:{1:null,5:null,10:null}};async function Dn(){const[e,t,n,a,r,l]=await Promise.all([C(X.background),C(X.frontFrame),C(X.backFrame),C(pe[1]),C(pe[5]),C(pe[10])]);_={background:e,frontFrame:t,backFrame:n,badges:{1:a,5:r,10:l}}}function Hn(e,t){const n=Math.round(ae*e),a=Math.round(re*e),r=document.createElement("canvas");r.width=n,r.height=a;const l=r.getContext("2d");if(!l)throw new Error("Failed to get canvas context");l.drawImage(t,0,0,n,a);const i=e<1?.8:.95;return r.toDataURL("image/jpeg",i)}function Mn(e,t){const n=Math.round(ae*e),a=Math.round(re*e),r=document.createElement("canvas");r.width=n,r.height=a;const l=r.getContext("2d");if(!l)throw new Error("Failed to get canvas context");const i=Ct*e,s=Nt*e,o=$.badges,u=(m,f)=>{const p=f/2,h=m.x*e-p,y=m.y*e-p;l.drawImage(t,h,y,f,f)};return u(o.topLeft,i),u(o.topRight,i),u(o.bottomLeft,s),u(o.bottomRight,s),r.toDataURL("image/png")}function At(e,t,n,a=1){const r=Bt[n].banner[t];jt(e,r,$.banner.centerX*a,$.banner.centerY*a,$.banner.radius*a,$.banner.fontSize*a,$.banner.color)}function Dt(e,t,n,a,r,l,i){const s=Math.round(ae*a),o=Math.round(re*a),u=document.createElement("canvas");u.width=s,u.height=o;const m=u.getContext("2d");if(!m)throw new Error("Failed to get canvas context");m.drawImage(r,0,0,s,o);{const p=Ct*a,h=Nt*a,y=$.badges,I=(d,k)=>{const E=k/2,v=d.x*a-E,S=d.y*a-E;m.drawImage(i,v,S,k,k)};I(y.topLeft,p),I(y.topRight,p),I(y.bottomLeft,h),I(y.bottomRight,h)}if(m.drawImage(l,0,0,s,o),n==="front"){const p=Bt[t].banner[e];jt(m,p,$.banner.centerX*a,$.banner.centerY*a,$.banner.radius*a,$.banner.fontSize*a,$.banner.color)}const f=a<1?.8:.95;return u.toDataURL("image/jpeg",f)}async function Ht(e,t,n){const a=`${e}-${t}-${n}`;if(Ee.has(a))return Ee.get(a);const r=_.background||await C(X.background),l=n==="front"?_.frontFrame||await C(X.frontFrame):_.backFrame||await C(X.backFrame),i=_.badges[e]||await C(pe[e]),s=Dt(e,t,n,Ce,r,l,i);return Ee.set(a,s),s}async function Fe(e,t,n){const a=`${e}-${t}-${n}`;if(se.has(a))return se.get(a);const r=_.background||await C(X.background),l=n==="front"?_.frontFrame||await C(X.frontFrame):_.backFrame||await C(X.backFrame),i=_.badges[e]||await C(pe[e]),s=Dt(e,t,n,1,r,l,i);if(se.size>4){const o=se.keys().next().value;o&&se.delete(o)}return se.set(a,s),s}function Un(){return{width:ae,height:re}}function On(){Ee.clear(),se.clear(),Ve.clear(),Ge.clear(),Ke.clear()}async function qe(e,t,n="front",a=Ce){const r=`bg-${a}`;let l=Ve.get(r);if(!l){const m=_.background||await C(X.background);l=Hn(a,m),Ve.set(r,l)}const i=`badges-${e}-${a}`;let s=Ge.get(i);if(!s){const m=_.badges[e]||await C(pe[e]);s=Mn(a,m),Ge.set(i,s)}const o=`${n}-${a}`;let u=Ke.get(o);if(!u){const m=n==="front"?_.frontFrame||await C(X.frontFrame):_.backFrame||await C(X.backFrame),f=Math.round(ae*a),p=Math.round(re*a),h=document.createElement("canvas");h.width=f,h.height=p;const y=h.getContext("2d");if(!y)throw new Error("Failed to get canvas context");y.drawImage(m,0,0,f,p),u=h.toDataURL("image/png"),Ke.set(o,u)}return{background:l,badges:s,frame:u}}async function Yn(){const e=[1,5,10],t=["de","en"],n=["front","back"],a=[];for(const r of e)for(const l of t)for(const i of n)a.push(Ht(r,l,i));await Promise.all(a)}function tt(e,t){return{front:"",back:"",width:ae,height:re}}const Ne={front:{portrait:{x:1810,y:918,radiusX:570,radiusY:605},namePlate:{x:1816,y:1765,fontSize:85,maxWidth:898,align:"center"}},back:{portrait:{x:0,y:0,radiusX:0,radiusY:0},namePlate:{x:1816,y:1770,fontSize:85,maxWidth:898,align:"center"},contactInfo:{x:898,y:939,fontSize:93,lineHeight:165,align:"center"},description:{x:2721,y:939,fontSize:85,maxWidth:1177,lineHeight:124,align:"center"},signature:{x:1820,y:1445,width:950,height:145,labelFontSize:85}}},de=Ne,ge=Ne;function nt(e){return Ne}const Ze=.75;function Wn(e){const t=nt(),n=Ze,a=r=>({portrait:{x:r.portrait.x*n,y:r.portrait.y*n,radiusX:r.portrait.radiusX*n,radiusY:r.portrait.radiusY*n},namePlate:{x:r.namePlate.x*n,y:r.namePlate.y*n,fontSize:r.namePlate.fontSize*n,maxWidth:r.namePlate.maxWidth?r.namePlate.maxWidth*n:void 0,lineHeight:r.namePlate.lineHeight?r.namePlate.lineHeight*n:void 0,align:r.namePlate.align},contactInfo:r.contactInfo?{x:r.contactInfo.x*n,y:r.contactInfo.y*n,fontSize:r.contactInfo.fontSize*n,maxWidth:r.contactInfo.maxWidth?r.contactInfo.maxWidth*n:void 0,lineHeight:r.contactInfo.lineHeight?r.contactInfo.lineHeight*n:void 0,align:r.contactInfo.align}:void 0,description:r.description?{x:r.description.x*n,y:r.description.y*n,fontSize:r.description.fontSize*n,maxWidth:r.description.maxWidth?r.description.maxWidth*n:void 0,lineHeight:r.description.lineHeight?r.description.lineHeight*n:void 0,align:r.description.align}:void 0,signature:r.signature?{x:r.signature.x*n,y:r.signature.y*n,width:r.signature.width*n,height:r.signature.height*n,labelFontSize:r.signature.labelFontSize*n}:void 0});return{front:a(t.front),back:a(t.back)}}function _n(e,t){const n=tt();return{...n,width:Math.round(n.width*Ze),height:Math.round(n.height*Ze)}}function zn(e,t){const[n,a]=g.useState(e);return g.useEffect(()=>{const r=setTimeout(()=>a(e),t);return()=>clearTimeout(r)},[e,t]),n}function $n({onPortraitClick:e,onFileDrop:t}={}){const n=w(x=>x.appLanguage),a=w(x=>x.voucherConfig.language),r=w(x=>x.voucherConfig.hours),l=w(x=>x.voucherConfig.description),i=w(x=>x.voucherConfig.templateHue),s=w(x=>x.personalInfo),o=w(x=>x.portrait),u=w(x=>x.currentSide),m=w(x=>x.flipSide),f=w(x=>x.setPortraitPan),p=zn(i,150),h=ne(n),y=g.useRef(null),I=g.useRef(null),d=g.useRef(null),[k,E]=g.useState(!1),[v,S]=g.useState(!1),[R,P]=g.useState(!1),[D,j]=g.useState(!1),L=g.useRef(null),B=g.useRef(null),Y=g.useRef(!1),q=g.useRef(0),H=_n(),O=Wn(),Z=o.useEnhanced&&o.enhanced?o.enhanced:o.original,oe=Qe(a,r,l),[K,J]=g.useState(""),[V,te]=g.useState(""),[ie,Ae]=g.useState(""),[Q,ye]=g.useState(""),[ee,De]=g.useState(""),[xe,He]=g.useState(""),[ve,Ie]=g.useState(!0);g.useEffect(()=>{let x=!0;Ie(!0);async function N(){const[U,z]=await Promise.all([qe(r,a,"front"),qe(r,a,"back")]);x&&(J(U.background),te(U.badges),Ae(U.frame),ye(z.background),De(z.badges),He(z.frame),Ie(!1))}return N(),()=>{x=!1}},[r,a]),g.useEffect(()=>{!y.current||!K||!V||!ie||Rt(y.current,K,V,ie,Z,s.name,O.front,H.width,H.height,o.zoom,o.panX,o.panY,p,r,a)},[H,K,V,ie,Z,s.name,O,o.zoom,o.panX,o.panY,p,r,a]),g.useEffect(()=>{!I.current||!Q||!ee||!xe||Lt(I.current,Q,ee,xe,s.name,s.email,s.phone,oe,O.back,H.width,H.height,p,r,a)},[H,Q,ee,xe,s,oe,O,p,r,a]);const b=()=>{E(!k),m()};g.useEffect(()=>{E(u==="back")},[u]);const T=g.useCallback((x,N)=>{if(!d.current||u!=="front")return!1;const U=d.current.getBoundingClientRect(),z=U.width/H.width,Me=U.height/H.height,ke=(x-U.left)/z,Ue=(N-U.top)/Me,{x:Oe,y:Ye,radiusX:We,radiusY:Zt}=O.front.portrait,ot=(ke-Oe)/We,it=(Ue-Ye)/Zt;return ot*ot+it*it<=1},[u,H.width,H.height,O.front.portrait]),M=5,A=g.useCallback((x,N)=>{o.original&&(S(!0),L.current={x,y:N,panX:o.panX,panY:o.panY})},[o.original,o.panX,o.panY]),G=g.useCallback((x,N)=>{if(!v||!L.current||!d.current)return;const U=performance.now();if(U-q.current<33)return;q.current=U;const z=d.current.getBoundingClientRect(),ke=4/Math.max(z.width,z.height)*o.zoom,Ue=(x-L.current.x)*ke,Oe=(N-L.current.y)*ke,Ye=Math.max(-1,Math.min(1,L.current.panX+Ue)),We=Math.max(-1,Math.min(1,L.current.panY+Oe));f(Ye,We)},[v,f,o.zoom]),W=g.useCallback(()=>{S(!1),L.current=null,B.current=null},[]),at=g.useCallback(()=>{e&&e()},[e]),_t=x=>{T(x.clientX,x.clientY)&&(x.preventDefault(),B.current={x:x.clientX,y:x.clientY},Y.current=!1)},zt=x=>{if(P(T(x.clientX,x.clientY)),B.current&&o.original){const N=x.clientX-B.current.x,U=x.clientY-B.current.y;Math.sqrt(N*N+U*U)>M&&!v&&(Y.current=!0,A(B.current.x,B.current.y))}v&&G(x.clientX,x.clientY)},$t=x=>{B.current&&!Y.current&&T(x.clientX,x.clientY)&&at(),W()},Xt=()=>{W(),P(!1)},Vt=x=>{if(x.touches.length===1){const N=x.touches[0];T(N.clientX,N.clientY)&&(B.current={x:N.clientX,y:N.clientY},Y.current=!1)}},Gt=x=>{if(x.touches.length===1&&B.current&&o.original){const N=x.touches[0],U=N.clientX-B.current.x,z=N.clientY-B.current.y;Math.sqrt(U*U+z*z)>M&&!v&&(Y.current=!0,A(B.current.x,B.current.y)),v&&G(N.clientX,N.clientY)}},Kt=()=>{B.current&&!Y.current&&T(B.current.x,B.current.y)&&at(),W()},rt=g.useRef(!1);g.useEffect(()=>{rt.current=v},[v]),g.useEffect(()=>{const x=d.current;if(!x)return;const N=U=>{rt.current&&U.preventDefault()};return x.addEventListener("touchmove",N,{passive:!1}),()=>{x.removeEventListener("touchmove",N)}},[]);const Ft=u==="front"&&o.original,qt=H.width/H.height;return c.jsxs("div",{className:"space-y-2",children:[c.jsxs("div",{className:"flex justify-between items-center mb-6",children:[c.jsxs("div",{className:"join border border-base-300 rounded-lg",children:[c.jsx("button",{className:`join-item btn btn-md ${u==="front"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>u!=="front"&&b(),children:h.preview.front}),c.jsx("button",{className:`join-item btn btn-md ${u==="back"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>u!=="back"&&b(),children:h.preview.back})]}),c.jsxs("button",{className:"btn btn-ghost btn-md",onClick:b,children:[c.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:c.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"})}),c.jsx("span",{className:"hidden sm:inline",children:h.preview.flip})]})]}),c.jsxs("div",{className:"relative w-full overflow-visible",style:{aspectRatio:qt,perspective:"1500px"},children:[ve&&c.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-base-300 rounded-lg z-10",children:c.jsx("span",{className:"loading loading-spinner loading-lg text-primary"})}),c.jsxs("div",{ref:d,className:`relative w-full h-full shadow-lg ${R&&Ft?v?"cursor-grabbing":"cursor-grab":""} ${ve?"opacity-0":"opacity-100"} transition-opacity duration-300`,style:{transformStyle:"preserve-3d",transition:"transform 0.6s ease-in-out, opacity 0.3s ease-in-out",transform:k?"rotateY(180deg)":"rotateY(0deg)"},onMouseDown:_t,onMouseMove:zt,onMouseUp:$t,onMouseLeave:Xt,onTouchStart:Vt,onTouchMove:Gt,onTouchEnd:Kt,onDragOver:x=>{x.preventDefault(),u==="front"&&j(!0)},onDragLeave:x=>{x.preventDefault(),j(!1)},onDrop:x=>{if(x.preventDefault(),j(!1),u==="front"&&t){const N=x.dataTransfer.files[0];N&&N.type.startsWith("image/")&&t(N)}},children:[c.jsx("canvas",{ref:y,className:"absolute inset-0 w-full h-full",style:{backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden"}}),c.jsx("canvas",{ref:I,className:"absolute inset-0 w-full h-full",style:{backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden",transform:"rotateY(180deg)"}}),u==="front"&&!o.original&&c.jsx("div",{className:`absolute flex flex-col items-center justify-center transition-colors duration-300 ease-in-out pointer-events-none ${D?"bg-primary/20":"hover:bg-base-content/5"}`,style:{left:`${(O.front.portrait.x-O.front.portrait.radiusX)/H.width*100}%`,top:`${(O.front.portrait.y-O.front.portrait.radiusY)/H.height*100}%`,width:`${O.front.portrait.radiusX*2/H.width*100}%`,height:`${O.front.portrait.radiusY*2/H.height*100}%`,borderRadius:"50%",backfaceVisibility:"hidden",WebkitBackfaceVisibility:"hidden"},children:c.jsxs("button",{className:"btn btn-dash hover:btn-dash hover:border-base-content/60 flex flex-col items-center gap-0.5 sm:gap-1 h-auto py-1.5 px-2.5 sm:py-3 sm:px-4 bg-base-100/20 hover:bg-base-100/30",children:[c.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",className:"w-7 h-6 sm:w-10 sm:h-9 text-base-content/50",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round",children:[c.jsx("circle",{cx:"12",cy:"8",r:"4"}),c.jsx("path",{d:"M4 21c0-4 4-6 8-6s8 2 8 6"})]}),c.jsx("span",{className:"text-[10px] sm:text-xs text-center leading-tight whitespace-pre-line",children:n==="de"?`Foto
2
2
  hochladen`:`Upload
3
- photo`})]})})]})]})]})}function Vn(){const e=g.useRef(null),t=g.useRef(null);return{frontCanvasRef:e,backCanvasRef:t}}const Kn=`
3
+ photo`})]})})]})]})]})}function Xn(){const e=g.useRef(null),t=g.useRef(null);return{frontCanvasRef:e,backCanvasRef:t}}const Vn=`
4
+ // Translations for banner text
5
+ const TRANSLATIONS = {
6
+ de: {
7
+ banner: {
8
+ 1: 'EINE STUNDE',
9
+ 5: 'FÜNF STUNDEN',
10
+ 10: 'ZEHN STUNDEN',
11
+ },
12
+ },
13
+ en: {
14
+ banner: {
15
+ 1: 'ONE HOUR',
16
+ 5: 'FIVE HOURS',
17
+ 10: 'TEN HOURS',
18
+ },
19
+ },
20
+ };
21
+
22
+ // Banner arc text settings (at full 3633x1920 resolution)
23
+ const BANNER_CONFIG = {
24
+ centerX: 1816,
25
+ centerY: 3820,
26
+ radius: 3610,
27
+ fontSize: 103,
28
+ color: '#2a3a2a',
29
+ };
30
+
4
31
  // RGB to HSL conversion
5
32
  function rgbToHsl(r, g, b) {
6
33
  r /= 255;
@@ -201,6 +228,72 @@ function drawContactInfo(ctx, name, email, phone, x, y, fontSize, lineHeight, al
201
228
  ctx.restore();
202
229
  }
203
230
 
231
+ // Draw text along an arc (curved text for banner)
232
+ function drawTextOnArc(ctx, text, centerX, centerY, radius, fontSize, color) {
233
+ ctx.save();
234
+ ctx.font = '900 ' + fontSize + 'px "Times New Roman", Georgia, serif';
235
+ ctx.fillStyle = color;
236
+ ctx.textAlign = 'center';
237
+ ctx.textBaseline = 'middle';
238
+
239
+ // Measure total text width
240
+ const textWidth = ctx.measureText(text).width;
241
+
242
+ // Calculate the angle span based on text width and radius
243
+ const angleSpan = textWidth / radius;
244
+
245
+ // Center the text on the arc (at -90 degrees = top of circle)
246
+ const startAngle = -Math.PI / 2 - angleSpan / 2;
247
+
248
+ // Get individual character widths
249
+ const chars = text.split('');
250
+ const charWidths = [];
251
+ for (const char of chars) {
252
+ charWidths.push(ctx.measureText(char).width);
253
+ }
254
+
255
+ // Draw each character
256
+ let currentAngle = startAngle;
257
+
258
+ for (let i = 0; i < chars.length; i++) {
259
+ const char = chars[i];
260
+ const charWidth = charWidths[i];
261
+
262
+ // Angle for this character's center
263
+ const charAngle = currentAngle + (charWidth / 2) / radius;
264
+
265
+ // Calculate position on arc
266
+ const x = centerX + radius * Math.cos(charAngle);
267
+ const y = centerY + radius * Math.sin(charAngle);
268
+
269
+ ctx.save();
270
+ ctx.translate(x, y);
271
+ // Rotate to follow the arc tangent, +90° to make text upright
272
+ ctx.rotate(charAngle + Math.PI / 2);
273
+ ctx.fillText(char, 0, 0);
274
+ ctx.restore();
275
+
276
+ // Move to next character
277
+ currentAngle += charWidth / radius;
278
+ }
279
+
280
+ ctx.restore();
281
+ }
282
+
283
+ // Draw banner text on both sides
284
+ function drawBannerText(ctx, hours, language) {
285
+ const bannerText = TRANSLATIONS[language].banner[hours];
286
+ drawTextOnArc(
287
+ ctx,
288
+ bannerText,
289
+ BANNER_CONFIG.centerX,
290
+ BANNER_CONFIG.centerY,
291
+ BANNER_CONFIG.radius,
292
+ BANNER_CONFIG.fontSize,
293
+ BANNER_CONFIG.color
294
+ );
295
+ }
296
+
204
297
  self.onmessage = async (e) => {
205
298
  const {
206
299
  frontTemplateUrl,
@@ -218,6 +311,7 @@ self.onmessage = async (e) => {
218
311
  phone,
219
312
  description,
220
313
  language,
314
+ hours,
221
315
  } = e.data;
222
316
 
223
317
  try {
@@ -276,6 +370,9 @@ self.onmessage = async (e) => {
276
370
  );
277
371
  }
278
372
 
373
+ // Draw banner text on front
374
+ drawBannerText(frontCtx, hours, language);
375
+
279
376
  // Render back side
280
377
  backCtx.drawImage(backTemplate, 0, 0, templateWidth, templateHeight);
281
378
 
@@ -349,6 +446,9 @@ self.onmessage = async (e) => {
349
446
  backCtx.fillText(signatureLabel, sig.x, sig.y + sig.labelFontSize * 0.3);
350
447
  }
351
448
 
449
+ // Draw banner text on back
450
+ drawBannerText(backCtx, hours, language);
451
+
352
452
  // Convert canvases to blobs and then to ArrayBuffer for transfer
353
453
  const [frontBlob, backBlob] = await Promise.all([
354
454
  frontCanvas.convertToBlob({ type: 'image/jpeg', quality: 0.95 }),
@@ -375,4 +475,4 @@ self.onmessage = async (e) => {
375
475
  });
376
476
  }
377
477
  };
378
- `;let Xe=null,gt=null;function qn(){if(!Xe){const e=new Blob([Kn],{type:"application/javascript"});gt=URL.createObjectURL(e),Xe=new Worker(gt,{type:"module"})}return Xe}async function Ve(e){const n=await(await fetch(e)).blob();return URL.createObjectURL(n)}function mt(e,t){const n=new Uint8Array(e);let a="";for(let r=0;r<n.length;r++)a+=String.fromCharCode(n[r]);return`data:${t};base64,${btoa(a)}`}async function Ut(e){const{frontTemplateSrc:t,backTemplateSrc:n,templateWidth:a,templateHeight:r,layout:l,portrait:i,portraitZoom:s=1,portraitPanX:o=0,portraitPanY:u=0,templateHue:m=160,name:f,email:p,phone:h,description:y,language:v="de"}=e,[d,k]=await Promise.all([Ve(t),Ve(n)]);let I=null;return i&&(I=await Ve(i)),new Promise((T,P)=>{const S=qn(),H=setTimeout(()=>{S.removeEventListener("message",C),S.removeEventListener("error",N),URL.revokeObjectURL(d),URL.revokeObjectURL(k),I&&URL.revokeObjectURL(I),P(new Error("PDF generation timed out. Please try again."))},6e4),C=L=>{if(clearTimeout(H),S.removeEventListener("message",C),S.removeEventListener("error",N),URL.revokeObjectURL(d),URL.revokeObjectURL(k),I&&URL.revokeObjectURL(I),L.data.type==="success")try{const{frontImageData:B,backImageData:z,width:F,height:M}=L.data;if(!B||!z||!F||!M){P(new Error("Invalid response from worker"));return}const Y=mt(B,"image/jpeg"),Z=mt(z,"image/jpeg"),te=600,W=F/te*25.4,J=M/te*25.4,q=new tn.jsPDF({orientation:W>J?"landscape":"portrait",unit:"mm",format:[W,J]});q.addImage(Y,"JPEG",0,0,W,J),q.addPage([W,J]),q.addImage(Z,"JPEG",0,0,W,J);const fe=q.output("blob");T(fe)}catch(B){P(B)}else P(new Error(L.data.error))},N=L=>{S.removeEventListener("message",C),S.removeEventListener("error",N),URL.revokeObjectURL(d),URL.revokeObjectURL(k),I&&URL.revokeObjectURL(I),P(new Error(L.message))};S.addEventListener("message",C),S.addEventListener("error",N),S.postMessage({type:"generate",frontTemplateUrl:d,backTemplateUrl:k,portraitUrl:I,templateWidth:a,templateHeight:r,templateHue:m,portraitZoom:s,portraitPanX:o,portraitPanY:u,layout:{front:{portrait:l.front.portrait,namePlate:l.front.namePlate},back:{namePlate:l.back.namePlate,contactInfo:l.back.contactInfo,description:l.back.description,signature:l.back.signature}},name:f,email:p,phone:h,description:y,language:v})})}function Yt(e,t){const n=URL.createObjectURL(e),a=document.createElement("a");a.href=n,a.download=t,document.body.appendChild(a),a.click(),document.body.removeChild(a),URL.revokeObjectURL(n)}async function Ot(e){const t=await Ut(e);Yt(t,e.filename)}function Gn(){const e=w(d=>d.appLanguage),t=w(d=>d.voucherConfig.language),n=w(d=>d.voucherConfig.hours),a=w(d=>d.voucherConfig.description),r=w(d=>d.voucherConfig.templateHue),l=w(d=>d.personalInfo),i=w(d=>d.portrait),s=w(d=>d.isExporting),o=w(d=>d.setIsExporting),u=ne(e),m=nt(),f=at(),p=i.useEnhanced&&i.enhanced?i.enhanced:i.original,h=et(t,n,a),y=l.name.trim().length>0&&l.email.trim().length>0&&l.phone.trim().length>0&&i.original!==null,v=async()=>{if(!(!y||s)){o(!0);try{const[d,k]=await Promise.all([Fe(n,t,"front"),Fe(n,t,"back")]),I=`zeitgutschein-${n}h-${l.name.replace(/\s+/g,"-").toLowerCase()}.pdf`;await Ot({frontTemplateSrc:d,backTemplateSrc:k,templateWidth:m.width,templateHeight:m.height,layout:f,portrait:p,portraitZoom:i.zoom,portraitPanX:i.panX,portraitPanY:i.panY,templateHue:r,name:l.name,email:l.email,phone:l.phone,description:h,filename:I,language:t})}catch(d){console.error("PDF export failed:",d)}finally{o(!1)}}};return c.jsxs("button",{className:`btn btn-primary w-full btn-md ${y?"":"btn-disabled"}`,onClick:v,disabled:!y,"aria-busy":s,children:[s?c.jsx("span",{className:"loading loading-spinner loading-sm"}):c.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:c.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"})}),u.export.button]})}function zt(){const e=w(a=>a.appLanguage),t=w(a=>a.setAppLanguage),n=a=>{t(a)};return c.jsxs("div",{className:"join",children:[c.jsx("button",{className:`join-item btn btn-sm ${e==="de"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>n("de"),children:"DE"}),c.jsx("button",{className:`join-item btn btn-sm ${e==="en"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>n("en"),children:"EN"})]})}function Fn(){const e=w(n=>n.appLanguage),t=ne(e);return c.jsxs("div",{className:"navbar bg-currency-green text-currency-cream shadow-lg shrink-0",children:[c.jsx("div",{className:"navbar-start",children:c.jsx("a",{className:"btn btn-ghost text-xl font-currency font-bold",children:t.header.title})}),c.jsx("div",{className:"navbar-center hidden sm:flex",children:c.jsx("span",{className:"text-sm opacity-80",children:t.header.subtitle})}),c.jsx("div",{className:"navbar-end",children:c.jsx(zt,{})})]})}const Re="/",Zn={id:"time-voucher-classic-de",name:"Zeitgutschein Classic",type:"time-voucher",category:"classic",images:{front:`${Re}templates/front_hdpi_de.jpg`,back:`${Re}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:le.front.portrait,name:le.front.namePlate},back:{name:le.back.namePlate,contactInfo:le.back.contactInfo,description:le.back.description}},languages:["de"]},Jn={id:"time-voucher-classic-en",name:"Time Voucher Classic",type:"time-voucher",category:"classic",images:{front:`${Re}templates/front_ldpi_en.png`,back:`${Re}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:ue.front.portrait,name:ue.front.namePlate},back:{name:ue.back.namePlate,contactInfo:ue.back.contactInfo,description:ue.back.description}},languages:["en"]},ht=[Zn,Jn],Wt={async listTemplates(e){let t=[...ht];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},async getTemplate(e){const t=ht.find(n=>n.id===e);if(!t)throw new Error(`Template not found: ${e}`);return t}};function Qn(e){return e==="de"?"time-voucher-classic-de":"time-voucher-classic-en"}let Ne=Wt;function ea(e){Ne=e}function ta(){return Ne}async function na(e){return Ne.listTemplates(e)}async function aa(e){return Ne.getTemplate(e)}exports.ApiKeyModal=Tt;exports.BillPreview=Xn;exports.ExportButton=Gn;exports.Header=Fn;exports.LAYOUT_HDPI=le;exports.LAYOUT_LDPI=ue;exports.LanguageToggle=zt;exports.PREVIEW_HEIGHT=Hn;exports.PREVIEW_WIDTH=Dn;exports.PersonalInfoForm=wn;exports.PortraitUpload=Bn;exports.TEMPLATE_HEIGHT=re;exports.TEMPLATE_LAYOUT=Ce;exports.TEMPLATE_WIDTH=ae;exports.TouchSlider=we;exports.VoucherConfig=jn;exports.applyEngravingEffect=bt;exports.applyHueShift=wt;exports.clearCompositorCache=On;exports.composeTemplate=At;exports.composeTemplateFullRes=Fe;exports.downloadBlob=Yt;exports.drawContactInfo=Lt;exports.drawMultilineText=St;exports.drawOvalPortrait=Et;exports.drawTemplate=ie;exports.drawText=tt;exports.enhancePortrait=Ln;exports.exportBillAsPDF=Ot;exports.formatDescription=et;exports.generateBillPDF=Ut;exports.getApiKey=Be;exports.getDefaultTemplateId=Qn;exports.getLayout=at;exports.getRemoveBackgroundEndpoint=In;exports.getTemplate=nt;exports.getTemplateById=aa;exports.getTemplateDimensions=Yn;exports.getTemplateLayers=Ze;exports.getTemplateProvider=ta;exports.hasApiKey=Te;exports.hasCustomEndpoint=Tn;exports.listTemplates=na;exports.loadImage=R;exports.preloadAllTemplates=zn;exports.preloadBaseImages=Mn;exports.removeBackground=It;exports.renderBackSide=Bt;exports.renderFrontSide=Rt;exports.resizeImage=pt;exports.setApiKey=kt;exports.setRemoveBackgroundEndpoint=kn;exports.setTemplateProvider=ea;exports.staticTemplateProvider=Wt;exports.t=ne;exports.useBillCanvasRefs=Vn;exports.useBillStore=w;
478
+ `;let $e=null,dt=null;function Gn(){if(!$e){const e=new Blob([Vn],{type:"application/javascript"});dt=URL.createObjectURL(e),$e=new Worker(dt,{type:"module"})}return $e}async function Xe(e){const n=await(await fetch(e)).blob();return URL.createObjectURL(n)}function gt(e,t){const n=new Uint8Array(e);let a="";for(let r=0;r<n.length;r++)a+=String.fromCharCode(n[r]);return`data:${t};base64,${btoa(a)}`}async function Mt(e){const{frontTemplateSrc:t,backTemplateSrc:n,templateWidth:a,templateHeight:r,layout:l,portrait:i,portraitZoom:s=1,portraitPanX:o=0,portraitPanY:u=0,templateHue:m=160,name:f,email:p,phone:h,description:y,language:I="de",hours:d=1}=e,[k,E]=await Promise.all([Xe(t),Xe(n)]);let v=null;return i&&(v=await Xe(i)),new Promise((S,R)=>{const P=Gn(),D=setTimeout(()=>{P.removeEventListener("message",j),P.removeEventListener("error",L),URL.revokeObjectURL(k),URL.revokeObjectURL(E),v&&URL.revokeObjectURL(v),R(new Error("PDF generation timed out. Please try again."))},6e4),j=B=>{if(clearTimeout(D),P.removeEventListener("message",j),P.removeEventListener("error",L),URL.revokeObjectURL(k),URL.revokeObjectURL(E),v&&URL.revokeObjectURL(v),B.data.type==="success")try{const{frontImageData:Y,backImageData:q,width:H,height:O}=B.data;if(!Y||!q||!H||!O){R(new Error("Invalid response from worker"));return}const Z=gt(Y,"image/jpeg"),oe=gt(q,"image/jpeg"),K=600,J=H/K*25.4,V=O/K*25.4,te=new en.jsPDF({orientation:J>V?"landscape":"portrait",unit:"mm",format:[J,V]});te.addImage(Z,"JPEG",0,0,J,V),te.addPage([J,V]),te.addImage(oe,"JPEG",0,0,J,V);const ie=te.output("blob");S(ie)}catch(Y){R(Y)}else R(new Error(B.data.error))},L=B=>{P.removeEventListener("message",j),P.removeEventListener("error",L),URL.revokeObjectURL(k),URL.revokeObjectURL(E),v&&URL.revokeObjectURL(v),R(new Error(B.message))};P.addEventListener("message",j),P.addEventListener("error",L),P.postMessage({type:"generate",frontTemplateUrl:k,backTemplateUrl:E,portraitUrl:v,templateWidth:a,templateHeight:r,templateHue:m,portraitZoom:s,portraitPanX:o,portraitPanY:u,layout:{front:{portrait:l.front.portrait,namePlate:l.front.namePlate},back:{namePlate:l.back.namePlate,contactInfo:l.back.contactInfo,description:l.back.description,signature:l.back.signature}},name:f,email:p,phone:h,description:y,language:I,hours:d})})}function Ut(e,t){const n=URL.createObjectURL(e),a=document.createElement("a");a.href=n,a.download=t,document.body.appendChild(a),a.click(),document.body.removeChild(a),URL.revokeObjectURL(n)}async function Ot(e){const t=await Mt(e);Ut(t,e.filename)}function Kn(){const e=w(d=>d.appLanguage),t=w(d=>d.voucherConfig.language),n=w(d=>d.voucherConfig.hours),a=w(d=>d.voucherConfig.description),r=w(d=>d.voucherConfig.templateHue),l=w(d=>d.personalInfo),i=w(d=>d.portrait),s=w(d=>d.isExporting),o=w(d=>d.setIsExporting),u=ne(e),m=tt(),f=nt(),p=i.useEnhanced&&i.enhanced?i.enhanced:i.original,h=Qe(t,n,a),y=l.name.trim().length>0&&l.email.trim().length>0&&l.phone.trim().length>0&&i.original!==null,I=async()=>{if(!(!y||s)){o(!0);try{const[d,k]=await Promise.all([Fe(n,t,"front"),Fe(n,t,"back")]),E=`zeitgutschein-${n}h-${l.name.replace(/\s+/g,"-").toLowerCase()}.pdf`;await Ot({frontTemplateSrc:d,backTemplateSrc:k,templateWidth:m.width,templateHeight:m.height,layout:f,portrait:p,portraitZoom:i.zoom,portraitPanX:i.panX,portraitPanY:i.panY,templateHue:r,name:l.name,email:l.email,phone:l.phone,description:h,filename:E,language:t,hours:n})}catch(d){console.error("PDF export failed:",d)}finally{o(!1)}}};return c.jsxs("button",{className:`btn btn-primary w-full btn-md ${y?"":"btn-disabled"}`,onClick:I,disabled:!y,"aria-busy":s,children:[s?c.jsx("span",{className:"loading loading-spinner loading-sm"}):c.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:c.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"})}),u.export.button]})}function Yt(){const e=w(a=>a.appLanguage),t=w(a=>a.setAppLanguage),n=a=>{t(a)};return c.jsxs("div",{className:"join",children:[c.jsx("button",{className:`join-item btn btn-sm ${e==="de"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>n("de"),children:"DE"}),c.jsx("button",{className:`join-item btn btn-sm ${e==="en"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>n("en"),children:"EN"})]})}function Fn(){const e=w(n=>n.appLanguage),t=ne(e);return c.jsxs("div",{className:"navbar bg-currency-green text-currency-cream shadow-lg shrink-0",children:[c.jsx("div",{className:"navbar-start",children:c.jsx("a",{className:"btn btn-ghost text-xl font-currency font-bold",children:t.header.title})}),c.jsx("div",{className:"navbar-center hidden sm:flex",children:c.jsx("span",{className:"text-sm opacity-80",children:t.header.subtitle})}),c.jsx("div",{className:"navbar-end",children:c.jsx(Yt,{})})]})}const Le="/",qn={id:"time-voucher-classic-de",name:"Zeitgutschein Classic",type:"time-voucher",category:"classic",images:{front:`${Le}templates/front_hdpi_de.jpg`,back:`${Le}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:de.front.portrait,name:de.front.namePlate},back:{name:de.back.namePlate,contactInfo:de.back.contactInfo,description:de.back.description}},languages:["de"]},Zn={id:"time-voucher-classic-en",name:"Time Voucher Classic",type:"time-voucher",category:"classic",images:{front:`${Le}templates/front_ldpi_en.png`,back:`${Le}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:ge.front.portrait,name:ge.front.namePlate},back:{name:ge.back.namePlate,contactInfo:ge.back.contactInfo,description:ge.back.description}},languages:["en"]},mt=[qn,Zn],Wt={async listTemplates(e){let t=[...mt];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},async getTemplate(e){const t=mt.find(n=>n.id===e);if(!t)throw new Error(`Template not found: ${e}`);return t}};function Jn(e){return e==="de"?"time-voucher-classic-de":"time-voucher-classic-en"}let je=Wt;function Qn(e){je=e}function ea(){return je}async function ta(e){return je.listTemplates(e)}async function na(e){return je.getTemplate(e)}exports.ApiKeyModal=kt;exports.BillPreview=$n;exports.ExportButton=Kn;exports.Header=Fn;exports.LAYOUT_HDPI=de;exports.LAYOUT_LDPI=ge;exports.LanguageToggle=Yt;exports.PREVIEW_HEIGHT=An;exports.PREVIEW_WIDTH=jn;exports.PersonalInfoForm=xn;exports.PortraitUpload=Ln;exports.TEMPLATE_HEIGHT=re;exports.TEMPLATE_LAYOUT=Ne;exports.TEMPLATE_WIDTH=ae;exports.TouchSlider=we;exports.VoucherConfig=Bn;exports.applyEngravingEffect=ft;exports.applyHueShift=xt;exports.clearCompositorCache=On;exports.composeTemplate=Ht;exports.composeTemplateFullRes=Fe;exports.downloadBlob=Ut;exports.drawContactInfo=Pt;exports.drawMultilineText=St;exports.drawOvalPortrait=Et;exports.drawTemplate=ce;exports.drawText=et;exports.enhancePortrait=Pn;exports.exportBillAsPDF=Ot;exports.formatDescription=Qe;exports.generateBillPDF=Mt;exports.getApiKey=Be;exports.getDefaultTemplateId=Jn;exports.getLayout=nt;exports.getRemoveBackgroundEndpoint=In;exports.getTemplate=tt;exports.getTemplateById=na;exports.getTemplateDimensions=Un;exports.getTemplateLayers=qe;exports.getTemplateProvider=ea;exports.hasApiKey=Te;exports.hasCustomEndpoint=kn;exports.listTemplates=ta;exports.loadImage=C;exports.preloadAllTemplates=Yn;exports.preloadBaseImages=Dn;exports.removeBackground=It;exports.renderBackSide=Lt;exports.renderFrontSide=Rt;exports.resizeImage=ht;exports.setApiKey=vt;exports.setRemoveBackgroundEndpoint=vn;exports.setTemplateProvider=Qn;exports.staticTemplateProvider=Wt;exports.t=ne;exports.useBillCanvasRefs=Xn;exports.useBillStore=w;
package/dist/index.d.ts CHANGED
@@ -250,6 +250,7 @@ declare interface PDFGeneratorOptions {
250
250
  description: string;
251
251
  filename: string;
252
252
  language?: 'de' | 'en';
253
+ hours?: HourValue;
253
254
  }
254
255
 
255
256
  export declare interface PersonalInfo {