@antontranelis/money-printer 1.0.21 → 1.0.22

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,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("react/jsx-runtime"),mt=require("zustand"),gt=require("zustand/middleware"),m=require("react"),ft=require("jspdf");var ne=typeof document<"u"?document.currentScript:null;const De={personalInfo:{name:"",email:"",phone:""},voucherConfig:{hours:1,description:"",language:"de",templateHue:160},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},x=mt.create()(gt.persist(e=>({...De,setPersonalInfo:t=>e(n=>({personalInfo:{...n.personalInfo,...t}})),setVoucherConfig:t=>e(n=>({voucherConfig:{...n.voucherConfig,...t}})),setPortrait:(t,n=null)=>e(r=>({portrait:{...r.portrait,original:t,enhanced:n,useEnhanced:!1,zoom:r.portrait.original&&t?r.portrait.zoom:1,panX:r.portrait.original&&t?r.portrait.panX:0,panY:r.portrait.original&&t?r.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(r=>({portrait:{...r.portrait,panX:t,panY:n}})),setPortraitRawImage:t=>e(n=>({portrait:{...n.portrait,rawImage:t}})),setPortraitBgRemoved:(t,n)=>e(r=>({portrait:{...r.portrait,bgRemoved:t,bgRemovedImage:n!==void 0?n:r.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}),setLanguage: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:()=>e(De)}),{name:"money-generator-storage",partialize:e=>({personalInfo:e.personalInfo,voucherConfig:e.voucherConfig,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:!1,bgOpacity:0,bgBlur:0,engravingIntensity:e.portrait.engravingIntensity}})})),bt={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?"},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 {hours} {hourLabel} meiner Zeit oder ein gleichwertiges Dankeschön"}},xt={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?"},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:"This voucher entitles you to {hours} {hourLabel} of my time or an equivalent thank you"}},wt={de:bt,en:xt};function G(e){return wt[e]}function Se(e,t,n){if(n&&n.trim())return n;const r=G(e),a=t===1?r.form.voucher.hourLabel:r.form.voucher.hoursLabel;return r.bill.descriptionText.replace("{hours}",t.toString()).replace("{hourLabel}",a)}function yt(){const e=x(a=>a.voucherConfig.language),t=x(a=>a.personalInfo),n=x(a=>a.setPersonalInfo),r=G(e);return i.jsxs("div",{className:"space-y-4",children:[i.jsxs("div",{className:"form-control",children:[i.jsx("label",{className:"label",children:i.jsx("span",{className:"label-text font-medium",children:r.form.personalInfo.name})}),i.jsx("input",{type:"text",placeholder:r.form.personalInfo.namePlaceholder,className:"input input-bordered w-full",value:t.name,onChange:a=>n({name:a.target.value})})]}),i.jsxs("div",{className:"form-control",children:[i.jsx("label",{className:"label",children:i.jsx("span",{className:"label-text font-medium",children:r.form.personalInfo.email})}),i.jsx("input",{type:"email",placeholder:r.form.personalInfo.emailPlaceholder,className:"input input-bordered w-full",value:t.email,onChange:a=>n({email:a.target.value})})]}),i.jsxs("div",{className:"form-control",children:[i.jsx("label",{className:"label",children:i.jsx("span",{className:"label-text font-medium",children:r.form.personalInfo.phone})}),i.jsx("input",{type:"tel",placeholder:r.form.personalInfo.phonePlaceholder,className:"input input-bordered w-full",value:t.phone,onChange:a=>n({phone:a.target.value})})]})]})}const vt=1024,ee=new Map;let W=null,He=null;function Te(e,t){return W||(W=document.createElement("canvas"),He=W.getContext("2d",{willReadFrequently:!0})),(W.width!==e||W.height!==t)&&(W.width=e,W.height=t),He}function ie(e){const t=ee.get(e);return t?Promise.resolve(t):new Promise((n,r)=>{const a=new Image;a.onload=()=>{if(ee.size>10){const o=ee.keys().next().value;o&&ee.delete(o)}ee.set(e,a),n(a)},a.onerror=()=>r(new Error("Failed to load image")),a.src=e})}function It(){ee.clear()}async function kt(e,t=vt){const n=await ie(e),r=Math.max(n.width,n.height);if(r<=t)return e;const a=t/r,o=Math.round(n.width*a),s=Math.round(n.height*a),d=document.createElement("canvas"),c=d.getContext("2d");if(!c)throw new Error("Failed to get canvas context");return d.width=o,d.height=s,c.drawImage(n,0,0,o,s),d.toDataURL("image/jpeg",.9)}async function ye(e,t,n,r=0){const[a,o]=await Promise.all([ie(e),ie(t)]),s=Te(a.width,a.height);if(s.clearRect(0,0,a.width,a.height),n>0){const d=r*20;s.save(),s.globalAlpha=n,d>0&&(s.filter=`blur(${d}px)`),s.drawImage(o,0,0,a.width,a.height),s.restore()}return s.drawImage(a,0,0),W.toDataURL("image/png")}async function _e(e,t=.5){const n=await ie(e),r=Te(n.width,n.height);r.drawImage(n,0,0);const a=r.getImageData(0,0,n.width,n.height),o=a.data,s=new Uint32Array(o.buffer),d=1+t*.8,c=1-t;for(let u=0;u<s.length;u++){const p=s[u],h=p&255,w=p>>8&255,g=p>>16&255,v=p>>24&255;if(v===0)continue;let k=(((77*h+150*w+29*g>>8)/255-.5)*d+.5)*255;k<0?k=0:k>255&&(k=255);let P=k*.9+25,T=k*.78+15,I=k*.55+5;P>255&&(P=255),T>255&&(T=255),I>255&&(I=255);const C=h*c+P*t|0,E=w*c+T*t|0,D=g*c+I*t|0;s[u]=v<<24|D<<16|E<<8|C}return r.putImageData(a,0,0),W.toDataURL("image/png")}function Pt(e,t,n){e/=255,t/=255,n/=255;const r=Math.max(e,t,n),a=Math.min(e,t,n),o=(r+a)/2;let s=0,d=0;if(r!==a){const c=r-a;switch(d=o>.5?c/(2-r-a):c/(r+a),r){case e:s=((t-n)/c+(t<n?6:0))/6;break;case t:s=((n-e)/c+2)/6;break;case n:s=((e-t)/c+4)/6;break}}return[s,d,o]}function Ct(e,t,n){if(t===0){const s=Math.round(n*255);return[s,s,s]}const r=(s,d,c)=>(c<0&&(c+=1),c>1&&(c-=1),c<1/6?s+(d-s)*6*c:c<1/2?d:c<2/3?s+(d-s)*(2/3-c)*6:s),a=n<.5?n*(1+t):n+t-n*t,o=2*n-a;return[Math.round(r(o,a,e+1/3)*255),Math.round(r(o,a,e)*255),Math.round(r(o,a,e-1/3)*255)]}async function ze(e,t){if(t>=155&&t<=165)return e;const n=await ie(e),r=Te(n.width,n.height);r.drawImage(n,0,0);const a=r.getImageData(0,0,n.width,n.height),o=a.data,s=new Uint32Array(o.buffer),d=t%360/360,c=60/360,u=260/360,p=1e5,h=s.length;for(let w=0;w<h;w+=p){const g=Math.min(w+p,h);for(let v=w;v<g;v++){const b=s[v],k=b&255,P=b>>8&255,T=b>>16&255,I=b>>24&255;if(I===0)continue;const[C,E,D]=Pt(k,P,T);if(E<.06||C<c||C>u)continue;const B=d,[L,_,j]=Ct(B,E,D);s[v]=I<<24|j<<16|_<<8|L}g<h&&await new Promise(v=>setTimeout(v,0))}return r.putImageData(a,0,0),W.toDataURL("image/png")}const St="https://api.stability.ai/v1/generation",Tt="https://api.stability.ai/v2beta/stable-image/edit/remove-background",We="stability_api_key";let ae=null;function Rt(e){ae=e}function Et(){return ae}function jt(){return ae!==null}const Bt={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"},Me=[{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 Lt(e,t){const n=e/t;let r=Me[0],a=1/0;for(const o of Me){const s=o.width/o.height,d=Math.abs(n-s);d<a&&(a=d,r=o)}return r}function Nt(e){return new Promise((t,n)=>{const r=new Image;r.onload=()=>{const a=Lt(r.width,r.height),o=document.createElement("canvas");o.width=a.width,o.height=a.height;const s=o.getContext("2d");if(!s){n(new Error("Failed to get canvas context"));return}const d=r.width/r.height,c=a.width/a.height;let u=0,p=0,h=r.width,w=r.height;d>c?(h=r.height*c,u=(r.width-h)/2):(w=r.width/c,p=(r.height-w)/2),s.drawImage(r,u,p,h,w,0,0,a.width,a.height),t(o.toDataURL("image/png"))},r.onerror=()=>n(new Error("Failed to load image")),r.src=e})}function Xe(e){var s;const t=e.split(","),n=((s=t[0].match(/:(.*?);/))==null?void 0:s[1])||"image/png",r=atob(t[1]),a=r.length,o=new Uint8Array(a);for(let d=0;d<a;d++)o[d]=r.charCodeAt(d);return new Blob([o],{type:n})}function he(){var t;const e=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:ne&&ne.tagName.toUpperCase()==="SCRIPT"&&ne.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(We):null}function $e(e){localStorage.setItem(We,e)}function Pe(){return ae?!0:he()!==null}async function Dt(e){const t=he();if(!t)throw new Error("No Stability AI API key configured");const{imageDataUrl:n,style:r,strength:a=.35}=e,o=await Nt(n),s=Xe(o),d=new FormData;d.append("init_image",s,"portrait.png"),d.append("init_image_mode","IMAGE_STRENGTH"),d.append("image_strength",String(1-a)),d.append("text_prompts[0][text]",Bt[r]),d.append("text_prompts[0][weight]","1"),d.append("cfg_scale","7"),d.append("samples","1"),d.append("steps","30");const u=await fetch(`${St}/stable-diffusion-xl-1024-v1-0/image-to-image`,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"},body:d});if(!u.ok){const h=await u.text();throw console.error("Stability AI error:",h),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 p=await u.json();if(!p.artifacts||p.artifacts.length===0)throw new Error("No image generated");return`data:image/png;base64,${p.artifacts[0].base64}`}async function Oe(e){if(ae){const s=await fetch(ae,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({imageDataUrl:e})});if(!s.ok){const c=await s.json().catch(()=>({}));throw new Error(c.error||`API error: ${s.status}`)}return(await s.json()).imageDataUrl}const t=he();if(!t)throw new Error("No Stability AI API key configured");const n=Xe(e),r=new FormData;r.append("image",n,"image.png"),r.append("output_format","png");const a=await fetch(Tt,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"image/*"},body:r});if(!a.ok){const s=await a.text();throw console.error("Stability AI remove background error:",s),a.status===401?new Error("Invalid API key"):a.status===402?new Error("Insufficient credits"):a.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${a.status}`)}const o=await a.blob();return new Promise((s,d)=>{const c=new FileReader;c.onload=()=>s(c.result),c.onerror=()=>d(new Error("Failed to read result")),c.readAsDataURL(o)})}function Ht(){const[e,t]=m.useState(!1),[n,r]=m.useState(!1),[a,o]=m.useState(null),[s,d]=m.useState(()=>Pe());m.useEffect(()=>{d(Pe())},[]);const c=m.useCallback(()=>o(null),[]),u=m.useCallback(w=>{$e(w),d(!0),o(null)},[]),p=m.useCallback(async(w,g=.5)=>{t(!0),o(null);try{return await _e(w,g)}catch(v){const b=v instanceof Error?v.message:"Enhancement failed";throw o(b),v}finally{t(!1)}},[]),h=m.useCallback(async w=>{r(!0),o(null);try{return await Oe(w)}catch(g){const v=g instanceof Error?g.message:"Background removal failed";throw o(v),g}finally{r(!1)}},[]);return{enhance:p,removeBg:h,isEnhancing:e,isRemovingBg:n,error:a,hasKey:s,setApiKey:u,clearError:c}}function Fe({isOpen:e,onClose:t,onSubmit:n}){const r=x(u=>u.voucherConfig.language),[a,o]=m.useState("");if(!e)return null;const s=u=>{u.preventDefault(),a.trim()&&(n(a.trim()),o(""),t())},c={de:{title:"Stability AI API Key",description:"Um die AI-Bildverbesserung zu nutzen, benötigst du einen Stability AI API Key. Du kannst ihn auf platform.stability.ai erhalten.",placeholder:"sk-...",submit:"Speichern",cancel:"Abbrechen",hint:"Der Key wird lokal in deinem Browser gespeichert."},en:{title:"Stability AI API Key",description:"To use AI image enhancement, you need a Stability AI API key. You can get one at platform.stability.ai.",placeholder:"sk-...",submit:"Save",cancel:"Cancel",hint:"The key is stored locally in your browser."}}[r];return i.jsxs("dialog",{className:"modal modal-open",children:[i.jsxs("div",{className:"modal-box",children:[i.jsx("h3",{className:"font-bold text-lg",children:c.title}),i.jsx("p",{className:"py-4 text-sm opacity-80",children:c.description}),i.jsxs("form",{onSubmit:s,children:[i.jsxs("div",{className:"form-control",children:[i.jsx("input",{type:"password",placeholder:c.placeholder,className:"input input-bordered w-full",value:a,onChange:u=>o(u.target.value),autoFocus:!0}),i.jsx("label",{className:"label",children:i.jsx("span",{className:"label-text-alt",children:c.hint})})]}),i.jsxs("div",{className:"modal-action",children:[i.jsx("button",{type:"button",className:"btn btn-ghost",onClick:t,children:c.cancel}),i.jsx("button",{type:"submit",className:"btn btn-primary",disabled:!a.trim(),children:c.submit})]})]})]}),i.jsx("form",{method:"dialog",className:"modal-backdrop",children:i.jsx("button",{onClick:t,children:"close"})})]})}function Mt(){const e=x(l=>l.voucherConfig.language),t=x(l=>l.portrait),n=x(l=>l.setPortrait),r=x(l=>l.setPortraitZoom),a=x(l=>l.setPortraitPan),o=x(l=>l.setPortraitRawImage),s=x(l=>l.setPortraitBgRemoved),d=x(l=>l.setPortraitBgOpacity),c=x(l=>l.setPortraitBgBlur),u=x(l=>l.setPortraitEngravingIntensity),{enhance:p,removeBg:h,isEnhancing:w,isRemovingBg:g,error:v,hasKey:b,setApiKey:k}=Ht(),P=G(e),T=m.useRef(null),I=m.useRef(null),[C,E]=m.useState(!1),[D,B]=m.useState(!1),[L,_]=m.useState(!1),j=m.useRef(null),H=m.useRef(null),M=m.useRef(null),R=t.rawImage,z=t.bgRemovedImage,A=t.bgRemoved,X=t.bgOpacity,V=t.bgBlur,se=t.engravingIntensity;m.useEffect(()=>{t.original&&!t.rawImage&&o(t.original)},[t.original,t.rawImage,o]),m.useEffect(()=>()=>{H.current&&clearTimeout(H.current),M.current&&clearTimeout(M.current)},[]);const re=m.useCallback(async l=>{if(!l.type.startsWith("image/"))return;const y=new FileReader;y.onload=async S=>{var ue;const U=(ue=S.target)==null?void 0:ue.result,de=await kt(U);o(de),n(de),s(!1,null),u(0)},y.readAsDataURL(l)},[n,o,s,u]),ge=m.useCallback(l=>{l.preventDefault(),E(!1);const y=l.dataTransfer.files[0];y&&re(y)},[re]),f=m.useCallback(l=>{l.preventDefault(),E(!0)},[]),N=m.useCallback(l=>{l.preventDefault(),E(!1)},[]),$=()=>{var l;(l=T.current)==null||l.click()},Z=l=>{var S;const y=(S=l.target.files)==null?void 0:S[0];y&&re(y)},O=m.useCallback(async(l,y)=>{try{return await p(l,y)}catch(S){return console.error("Enhancement failed:",S),l}},[p]),J=m.useCallback(async l=>{try{const y=await h(l);return s(!0,y),y}catch(y){return console.error("Background removal failed:",y),l}},[h,s]),F=m.useCallback(async()=>{const l=x.getState().portrait;if(!l.rawImage)return;let y;l.bgRemoved&&l.bgRemovedImage?y=await ye(l.bgRemovedImage,l.rawImage,l.bgOpacity,l.bgBlur):y=l.rawImage,l.engravingIntensity>0&&(y=await O(y,l.engravingIntensity)),n(y)},[O,n]),oe=async()=>{if(!R)return;if(!A&&!b){B(!0);return}if(!A){const y=await J(R),S=x.getState().portrait;let U=await ye(y,R,S.bgOpacity,S.bgBlur);S.engravingIntensity>0&&(U=await O(U,S.engravingIntensity)),n(U)}else{s(!1,null);const y=x.getState().portrait.engravingIntensity;if(y>0){const S=await O(R,y);n(S)}else n(R)}},fe=l=>{u(l),H.current&&clearTimeout(H.current),R&&(H.current=setTimeout(F,150))},be=async l=>{if(k(l),!R)return;const y=await J(R),S=x.getState().portrait;let U=await ye(y,R,S.bgOpacity,S.bgBlur);S.engravingIntensity>0&&(U=await O(U,S.engravingIntensity)),n(U)},xe=l=>{d(l),M.current&&clearTimeout(M.current),!(!R||!z)&&(M.current=setTimeout(F,150))},le=l=>{c(l),M.current&&clearTimeout(M.current),!(!R||!z)&&(M.current=setTimeout(F,150))},ce=()=>{n(null),o(null),s(!1,null),d(0),c(0),u(0),It()},Le=(l,y)=>{t.zoom<=1||(_(!0),j.current={x:l,y,panX:t.panX,panY:t.panY})},Ne=(l,y)=>{if(!L||!j.current||!I.current)return;const S=I.current.getBoundingClientRect(),U=2/Math.max(S.width,S.height),de=(l-j.current.x)*U,ue=(y-j.current.y)*U,pt=Math.max(-1,Math.min(1,j.current.panX+de)),ht=Math.max(-1,Math.min(1,j.current.panY+ue));a(pt,ht)},we=()=>{_(!1),j.current=null},ot=l=>{l.preventDefault(),Le(l.clientX,l.clientY)},it=l=>{Ne(l.clientX,l.clientY)},st=()=>{we()},lt=()=>{we()},ct=l=>{l.touches.length===1&&Le(l.touches[0].clientX,l.touches[0].clientY)},dt=l=>{l.touches.length===1&&Ne(l.touches[0].clientX,l.touches[0].clientY)},ut=()=>{we()};return i.jsxs("div",{className:"space-y-4",children:[t.original?i.jsxs("div",{className:"flex flex-col items-center space-y-4",children:[i.jsxs("div",{className:"relative",children:[i.jsx("div",{ref:I,className:`w-32 h-32 rounded-full overflow-hidden border-4 border-currency-gold shadow-lg ${t.zoom>1?"cursor-grab":""} ${L?"cursor-grabbing":""}`,onMouseDown:ot,onMouseMove:it,onMouseUp:st,onMouseLeave:lt,onTouchStart:ct,onTouchMove:dt,onTouchEnd:ut,children:i.jsx("img",{src:t.original||"",alt:"Portrait",className:"w-full h-full object-cover pointer-events-none select-none",style:{transform:`scale(${t.zoom}) translate(${t.panX*50*(t.zoom-1)}%, ${t.panY*50*(t.zoom-1)}%)`},draggable:!1})}),i.jsx("button",{className:"btn btn-circle btn-xs btn-error absolute -top-1 -right-1",onClick:ce,children:i.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:i.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),i.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[i.jsxs("div",{className:"form-control w-full",children:[i.jsxs("label",{className:"label",children:[i.jsx("span",{className:"label-text",children:P.form.portrait.zoom}),i.jsxs("span",{className:"label-text-alt",children:[Math.round(t.zoom*100),"%"]})]}),i.jsx("input",{type:"range",min:"0.5",max:"2",step:"0.05",value:t.zoom,onChange:l=>{const y=parseFloat(l.target.value);r(y),y<=1&&(t.panX!==0||t.panY!==0)&&a(0,0)},className:"range range-primary range-sm"})]}),i.jsxs("div",{className:"form-control w-full",children:[i.jsxs("label",{className:"label",children:[i.jsxs("span",{className:"label-text flex items-center gap-2",children:[e==="de"?"Sepia-Effekt":"Sepia effect",w&&i.jsx("span",{className:"loading loading-spinner loading-xs"})]}),i.jsxs("span",{className:"label-text-alt",children:[Math.round(se*100),"%"]})]}),i.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",value:se,onChange:l=>fe(parseFloat(l.target.value)),className:"range range-secondary range-sm",disabled:w||!R})]})]}),A?i.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[i.jsxs("div",{className:"form-control w-full",children:[i.jsxs("label",{className:"label",children:[i.jsx("span",{className:"label-text",children:e==="de"?"Hintergrund":"Background"}),i.jsxs("span",{className:"label-text-alt",children:[Math.round(X*100),"%"]})]}),i.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",value:X,onChange:l=>xe(parseFloat(l.target.value)),className:"range range-primary range-sm"})]}),i.jsxs("div",{className:"form-control w-full",children:[i.jsxs("label",{className:"label",children:[i.jsx("span",{className:"label-text",children:e==="de"?"Unschärfe":"Blur"}),i.jsxs("span",{className:"label-text-alt",children:[Math.round(V*100),"%"]})]}),i.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",value:V,onChange:l=>le(parseFloat(l.target.value)),className:"range range-primary range-sm"})]})]}):i.jsx("div",{className:"form-control",children:i.jsxs("label",{className:"label cursor-pointer justify-start gap-3",children:[i.jsx("input",{type:"checkbox",className:`toggle toggle-primary ${g?"opacity-50":""}`,checked:A,onChange:oe,disabled:g||!R}),i.jsxs("span",{className:"label-text flex items-center gap-2",children:[g?i.jsxs(i.Fragment,{children:[i.jsx("span",{className:"loading loading-spinner loading-xs"}),e==="de"?"Hintergrund wird entfernt...":"Removing background..."]}):e==="de"?"Hintergrund entfernen":"Remove background",!b&&i.jsx("span",{className:"badge badge-sm badge-outline",children:"API"})]})]})}),v&&i.jsxs("div",{className:"alert alert-warning text-sm py-2",children:[i.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:i.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"})}),i.jsx("span",{children:v})]})]}):i.jsxs("div",{className:`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${g?"border-primary bg-primary/10 pointer-events-none":C?"border-primary bg-primary/10":"border-base-300 hover:border-primary hover:bg-base-200"}`,onDrop:ge,onDragOver:f,onDragLeave:N,onClick:$,children:[i.jsx("input",{ref:T,type:"file",accept:"image/*",className:"hidden",onChange:Z}),g?i.jsxs("div",{className:"flex flex-col items-center gap-2",children:[i.jsx("span",{className:"loading loading-spinner loading-lg text-primary"}),i.jsx("p",{className:"font-medium",children:e==="de"?"Hintergrund wird entfernt...":"Removing background..."})]}):i.jsxs("div",{className:"flex flex-col items-center gap-2",children:[i.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:i.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"})}),i.jsx("p",{className:"font-medium",children:P.form.portrait.upload}),i.jsx("p",{className:"text-sm text-base-content/60",children:P.form.portrait.dragDrop})]})]}),i.jsx(Fe,{isOpen:D,onClose:()=>B(!1),onSubmit:be})]})}function At(){return null}const Y=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:ne&&ne.tagName.toUpperCase()==="SCRIPT"&&ne.src||new URL("index.cjs",document.baseURI).href}<"u"&&"/"||"/",Re={en:{1:{front:`${Y}templates/front_ldpi_en.png`,back:`${Y}templates/back_ldpi_en.png`,width:1536,height:1024},5:{front:`${Y}templates/front_ldpi_en.png`,back:`${Y}templates/back_ldpi_en.png`,width:1536,height:1024},10:{front:`${Y}templates/front_ldpi_en.png`,back:`${Y}templates/back_ldpi_en.png`,width:1536,height:1024}},de:{1:{front:`${Y}templates/front_hdpi_de.webp`,back:`${Y}templates/back_hdpi_de.webp`,width:6144,height:3200},5:{front:`${Y}templates/front_hdpi_de.webp`,back:`${Y}templates/back_hdpi_de.webp`,width:6144,height:3200},10:{front:`${Y}templates/front_hdpi_de.webp`,back:`${Y}templates/back_hdpi_de.webp`,width:6144,height:3200}}},q={front:{portrait:{x:768,y:490,radiusX:236,radiusY:258},namePlate:{x:768,y:848,fontSize:36,maxWidth:380,align:"center"}},back:{portrait:{x:0,y:0,radiusX:0,radiusY:0},namePlate:{x:768,y:832,fontSize:36,maxWidth:380,align:"center"},contactInfo:{x:380,y:500,fontSize:38,lineHeight:55,align:"center"},description:{x:1150,y:500,fontSize:38,maxWidth:480,lineHeight:42,align:"center"}}},K={front:{portrait:{x:3074,y:1530,radiusX:942,radiusY:1020},namePlate:{x:3072,y:2950,fontSize:144,maxWidth:1520,align:"center"}},back:{portrait:{x:0,y:0,radiusX:0,radiusY:0},namePlate:{x:3072,y:2930,fontSize:144,maxWidth:1520,align:"center"},contactInfo:{x:1520,y:1680,fontSize:160,lineHeight:280,align:"center"},description:{x:4600,y:1680,fontSize:145,maxWidth:2e3,lineHeight:210,align:"center"}}};function Ee(e){return e==="de"?K:q}function qe(e,t){return Re[e][t]}const Ce=.25;function Ut(e){const t=Ee(e),n=Ce,r=a=>({portrait:{x:a.portrait.x*n,y:a.portrait.y*n,radiusX:a.portrait.radiusX*n,radiusY:a.portrait.radiusY*n},namePlate:{x:a.namePlate.x*n,y:a.namePlate.y*n,fontSize:a.namePlate.fontSize*n,maxWidth:a.namePlate.maxWidth?a.namePlate.maxWidth*n:void 0,lineHeight:a.namePlate.lineHeight?a.namePlate.lineHeight*n:void 0,align:a.namePlate.align},contactInfo:a.contactInfo?{x:a.contactInfo.x*n,y:a.contactInfo.y*n,fontSize:a.contactInfo.fontSize*n,maxWidth:a.contactInfo.maxWidth?a.contactInfo.maxWidth*n:void 0,lineHeight:a.contactInfo.lineHeight?a.contactInfo.lineHeight*n:void 0,align:a.contactInfo.align}:void 0,description:a.description?{x:a.description.x*n,y:a.description.y*n,fontSize:a.description.fontSize*n,maxWidth:a.description.maxWidth?a.description.maxWidth*n:void 0,lineHeight:a.description.lineHeight?a.description.lineHeight*n:void 0,align:a.description.align}:void 0});return{front:r(t.front),back:r(t.back)}}function Yt(e,t){const n=Re[e][t];return{...n,width:Math.round(n.width*Ce),height:Math.round(n.height*Ce)}}const ve=new Map,Q=new Map;async function te(e){return ve.has(e)?ve.get(e):new Promise((t,n)=>{const r=new Image;r.crossOrigin="anonymous",r.onload=()=>{ve.set(e,r),t(r)},r.onerror=n,r.src=e})}function je(e,t,n,r){e.drawImage(t,0,0,n,r)}async function Ke(e,t,n,r){if(t>=155&&t<=165)return te(e);const a=`${e}:${t}:${n}x${r}`;if(Q.has(a))return te(Q.get(a));const o=await te(e),s=document.createElement("canvas");s.width=n,s.height=r;const d=s.getContext("2d");if(!d)throw new Error("Failed to get canvas context");d.drawImage(o,0,0,n,r);const c=s.toDataURL("image/png"),u=await ze(c,t);if(Q.size>20){const p=Q.keys().next().value;p&&Q.delete(p)}return Q.set(a,u),te(u)}function Ge(e,t,n,r,a,o,s=1,d=0,c=0){e.save(),e.beginPath(),e.ellipse(n,r,a,o,0,0,Math.PI*2),e.closePath(),e.clip();const u=t.width/t.height,p=a/o,h=a*2,w=o*2;let g,v;u>p?(v=w,g=w*u):(g=h,v=h/u),g*=s,v*=s;const b=Math.max(0,(g-h)/2),k=Math.max(0,(v-w)/2),P=n-g/2+d*b,T=r-v/2+c*k;e.drawImage(t,P,T,g,v),e.restore()}function Be(e,t,n,r="#2a3a2a"){e.save(),e.font=`${n.fontSize}px "Times New Roman", serif`,e.textAlign=n.align||"center",e.textBaseline="middle",e.fillStyle=r,n.maxWidth?e.fillText(t,n.x,n.y,n.maxWidth):e.fillText(t,n.x,n.y),e.restore()}function Ve(e,t,n,r="#2a3a2a"){e.save(),e.font=`${n.fontSize}px "Times New Roman", serif`,e.textAlign=n.align||"center",e.textBaseline="top",e.fillStyle=r;const a=n.maxWidth||400,o=n.lineHeight||n.fontSize*1.4,s=t.split(" "),d=[];let c="";for(const h of s){const w=c?`${c} ${h}`:h;e.measureText(w).width>a&&c?(d.push(c),c=h):c=w}c&&d.push(c);const u=d.length*o;let p=n.y-u/2;for(const h of d)e.fillText(h,n.x,p),p+=o;e.restore()}function Ze(e,t,n,r,a,o="#2a3a2a"){e.save(),e.font=`${a.fontSize}px "Times New Roman", serif`,e.textAlign=a.align||"center",e.textBaseline="middle",e.fillStyle=o;const s=a.lineHeight||a.fontSize*1.8,d=[t,n,r].filter(Boolean),c=(d.length-1)*s;let u=a.y-c/2;for(const p of d)p&&(e.fillText(p,a.x,u),u+=s);e.restore()}async function Je(e,t,n,r,a,o,s,d=1,c=0,u=0,p=0){const h=e.getContext("2d");if(!h)return;e.width=o,e.height=s,h.clearRect(0,0,o,s);const w=await Ke(t,p,o,s);if(je(h,w,o,s),n)try{const g=await te(n);Ge(h,g,a.portrait.x,a.portrait.y,a.portrait.radiusX,a.portrait.radiusY,d,c,u)}catch(g){console.error("Failed to load portrait:",g)}r&&Be(h,r,a.namePlate)}async function Qe(e,t,n,r,a,o,s,d,c,u=0){const p=e.getContext("2d");if(!p)return;e.width=d,e.height=c,p.clearRect(0,0,d,c);const h=await Ke(t,u,d,c);je(p,h,d,c),s.contactInfo&&(n||r||a)&&Ze(p,n,r,a,s.contactInfo),s.description&&o&&Ve(p,o,s.description),n&&Be(p,n,s.namePlate)}function _t(e,t){const[n,r]=m.useState(e);return m.useEffect(()=>{const a=setTimeout(()=>r(e),t);return()=>clearTimeout(a)},[e,t]),n}function zt(){const e=x(f=>f.voucherConfig.language),t=x(f=>f.voucherConfig.hours),n=x(f=>f.voucherConfig.description),r=x(f=>f.voucherConfig.templateHue),a=x(f=>f.personalInfo),o=x(f=>f.portrait),s=x(f=>f.currentSide),d=x(f=>f.flipSide),c=x(f=>f.setPortraitPan),u=_t(r,150),p=G(e),h=m.useRef(null),w=m.useRef(null),g=m.useRef(null),[v,b]=m.useState(!1),[k,P]=m.useState(!1),T=m.useRef(null),I=Yt(e,t),C=Ut(e),E=o.useEnhanced&&o.enhanced?o.enhanced:o.original,D=Se(e,t,n);m.useEffect(()=>{h.current&&Je(h.current,I.front,E,a.name,C.front,I.width,I.height,o.zoom,o.panX,o.panY,u)},[I,E,a.name,C,o.zoom,o.panX,o.panY,u]),m.useEffect(()=>{w.current&&Qe(w.current,I.back,a.name,a.email,a.phone,D,C.back,I.width,I.height,u)},[I,a,D,C,u]);const B=()=>{b(!0),setTimeout(()=>{d(),b(!1)},150)},L=m.useCallback((f,N)=>{if(!g.current||s!=="front"||!o.original)return!1;const $=g.current.getBoundingClientRect(),Z=$.width/I.width,O=$.height/I.height,J=(f-$.left)/Z,F=(N-$.top)/O,{x:oe,y:fe,radiusX:be,radiusY:xe}=C.front.portrait,le=(J-oe)/be,ce=(F-fe)/xe;return le*le+ce*ce<=1},[s,o.original,I.width,I.height,C.front.portrait]),_=m.useCallback((f,N)=>{o.zoom<=1||!L(f,N)||(P(!0),T.current={x:f,y:N,panX:o.panX,panY:o.panY})},[o.zoom,o.panX,o.panY,L]),j=m.useCallback((f,N)=>{if(!k||!T.current||!g.current)return;const $=g.current.getBoundingClientRect(),Z=3/Math.max($.width,$.height),O=(f-T.current.x)*Z,J=(N-T.current.y)*Z,F=Math.max(-1,Math.min(1,T.current.panX+O)),oe=Math.max(-1,Math.min(1,T.current.panY+J));c(F,oe)},[k,c]),H=m.useCallback(()=>{P(!1),T.current=null},[]),M=f=>{o.zoom>1&&L(f.clientX,f.clientY)&&(f.preventDefault(),_(f.clientX,f.clientY))},R=f=>{j(f.clientX,f.clientY)},z=()=>H(),A=()=>H(),X=f=>{if(f.touches.length===1){const N=f.touches[0];o.zoom>1&&L(N.clientX,N.clientY)&&_(N.clientX,N.clientY)}},V=f=>{f.touches.length===1&&j(f.touches[0].clientX,f.touches[0].clientY)},se=()=>H(),re=s==="front"&&o.original&&o.zoom>1,ge=I.width/I.height;return i.jsxs("div",{className:"space-y-4",children:[i.jsxs("div",{className:"flex justify-between items-center",children:[i.jsxs("div",{className:"tabs tabs-boxed bg-base-200",children:[i.jsx("button",{className:`tab ${s==="front"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>s!=="front"&&B(),children:p.preview.front}),i.jsx("button",{className:`tab ${s==="back"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>s!=="back"&&B(),children:p.preview.back})]}),i.jsxs("button",{className:"btn btn-ghost btn-sm",onClick:B,children:[i.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:i.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"})}),p.preview.flip]})]}),i.jsxs("div",{ref:g,className:`relative w-full overflow-hidden shadow-lg ${re?k?"cursor-grabbing":"cursor-grab":""}`,style:{aspectRatio:ge},onMouseDown:M,onMouseMove:R,onMouseUp:z,onMouseLeave:A,onTouchStart:X,onTouchMove:V,onTouchEnd:se,children:[i.jsx("canvas",{ref:h,className:`absolute inset-0 w-full h-full transition-all duration-300 ${s==="front"?v?"opacity-0 scale-95":"opacity-100 scale-100":"opacity-0 scale-95 pointer-events-none"}`}),i.jsx("canvas",{ref:w,className:`absolute inset-0 w-full h-full transition-all duration-300 ${s==="back"?v?"opacity-0 scale-95":"opacity-100 scale-100":"opacity-0 scale-95 pointer-events-none"}`})]})]})}function Wt(){const e=m.useRef(null),t=m.useRef(null);return{frontCanvasRef:e,backCanvasRef:t}}const Xt=`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("react/jsx-runtime"),mt=require("zustand"),gt=require("zustand/middleware"),m=require("react"),ft=require("jspdf");var ne=typeof document<"u"?document.currentScript:null;const De={personalInfo:{name:"",email:"",phone:""},voucherConfig:{hours:1,description:"",language:"de",templateHue:160},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},x=mt.create()(gt.persist(e=>({...De,setPersonalInfo:t=>e(n=>({personalInfo:{...n.personalInfo,...t}})),setVoucherConfig:t=>e(n=>({voucherConfig:{...n.voucherConfig,...t}})),setPortrait:(t,n=null)=>e(r=>({portrait:{...r.portrait,original:t,enhanced:n,useEnhanced:!1,zoom:r.portrait.original&&t?r.portrait.zoom:1,panX:r.portrait.original&&t?r.portrait.panX:0,panY:r.portrait.original&&t?r.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(r=>({portrait:{...r.portrait,panX:t,panY:n}})),setPortraitRawImage:t=>e(n=>({portrait:{...n.portrait,rawImage:t}})),setPortraitBgRemoved:(t,n)=>e(r=>({portrait:{...r.portrait,bgRemoved:t,bgRemovedImage:n!==void 0?n:r.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}),setLanguage: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:()=>e(De)}),{name:"money-generator-storage",partialize:e=>({personalInfo:e.personalInfo,voucherConfig:e.voucherConfig,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:!1,bgOpacity:0,bgBlur:0,engravingIntensity:e.portrait.engravingIntensity}})})),bt={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?"},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 {hours} {hourLabel} meiner Zeit oder ein gleichwertiges Dankeschön"}},xt={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?"},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:"This voucher entitles you to {hours} {hourLabel} of my time or an equivalent thank you"}},wt={de:bt,en:xt};function G(e){return wt[e]}function Se(e,t,n){if(n&&n.trim())return n;const r=G(e),a=t===1?r.form.voucher.hourLabel:r.form.voucher.hoursLabel;return r.bill.descriptionText.replace("{hours}",t.toString()).replace("{hourLabel}",a)}function yt(){const e=x(a=>a.voucherConfig.language),t=x(a=>a.personalInfo),n=x(a=>a.setPersonalInfo),r=G(e);return i.jsxs("div",{className:"space-y-4",children:[i.jsxs("div",{className:"form-control",children:[i.jsx("label",{className:"label",children:i.jsx("span",{className:"label-text font-medium",children:r.form.personalInfo.name})}),i.jsx("input",{type:"text",placeholder:r.form.personalInfo.namePlaceholder,className:"input input-bordered w-full",value:t.name,onChange:a=>n({name:a.target.value})})]}),i.jsxs("div",{className:"form-control",children:[i.jsx("label",{className:"label",children:i.jsx("span",{className:"label-text font-medium",children:r.form.personalInfo.email})}),i.jsx("input",{type:"email",placeholder:r.form.personalInfo.emailPlaceholder,className:"input input-bordered w-full",value:t.email,onChange:a=>n({email:a.target.value})})]}),i.jsxs("div",{className:"form-control",children:[i.jsx("label",{className:"label",children:i.jsx("span",{className:"label-text font-medium",children:r.form.personalInfo.phone})}),i.jsx("input",{type:"tel",placeholder:r.form.personalInfo.phonePlaceholder,className:"input input-bordered w-full",value:t.phone,onChange:a=>n({phone:a.target.value})})]})]})}const vt=1024,ee=new Map;let W=null,He=null;function Te(e,t){return W||(W=document.createElement("canvas"),He=W.getContext("2d",{willReadFrequently:!0})),(W.width!==e||W.height!==t)&&(W.width=e,W.height=t),He}function ie(e){const t=ee.get(e);return t?Promise.resolve(t):new Promise((n,r)=>{const a=new Image;a.onload=()=>{if(ee.size>10){const o=ee.keys().next().value;o&&ee.delete(o)}ee.set(e,a),n(a)},a.onerror=()=>r(new Error("Failed to load image")),a.src=e})}function It(){ee.clear()}async function kt(e,t=vt){const n=await ie(e),r=Math.max(n.width,n.height);if(r<=t)return e;const a=t/r,o=Math.round(n.width*a),s=Math.round(n.height*a),d=document.createElement("canvas"),c=d.getContext("2d");if(!c)throw new Error("Failed to get canvas context");return d.width=o,d.height=s,c.drawImage(n,0,0,o,s),d.toDataURL("image/jpeg",.9)}async function ye(e,t,n,r=0){const[a,o]=await Promise.all([ie(e),ie(t)]),s=Te(a.width,a.height);if(s.clearRect(0,0,a.width,a.height),n>0){const d=r*20;s.save(),s.globalAlpha=n,d>0&&(s.filter=`blur(${d}px)`),s.drawImage(o,0,0,a.width,a.height),s.restore()}return s.drawImage(a,0,0),W.toDataURL("image/png")}async function _e(e,t=.5){const n=await ie(e),r=Te(n.width,n.height);r.clearRect(0,0,n.width,n.height),r.drawImage(n,0,0);const a=r.getImageData(0,0,n.width,n.height),o=a.data,s=new Uint32Array(o.buffer),d=1+t*.8,c=1-t;for(let u=0;u<s.length;u++){const p=s[u],h=p&255,w=p>>8&255,g=p>>16&255,v=p>>24&255;if(v===0)continue;let k=(((77*h+150*w+29*g>>8)/255-.5)*d+.5)*255;k<0?k=0:k>255&&(k=255);let P=k*.9+25,T=k*.78+15,I=k*.55+5;P>255&&(P=255),T>255&&(T=255),I>255&&(I=255);const C=h*c+P*t|0,E=w*c+T*t|0,D=g*c+I*t|0;s[u]=v<<24|D<<16|E<<8|C}return r.putImageData(a,0,0),W.toDataURL("image/png")}function Pt(e,t,n){e/=255,t/=255,n/=255;const r=Math.max(e,t,n),a=Math.min(e,t,n),o=(r+a)/2;let s=0,d=0;if(r!==a){const c=r-a;switch(d=o>.5?c/(2-r-a):c/(r+a),r){case e:s=((t-n)/c+(t<n?6:0))/6;break;case t:s=((n-e)/c+2)/6;break;case n:s=((e-t)/c+4)/6;break}}return[s,d,o]}function Ct(e,t,n){if(t===0){const s=Math.round(n*255);return[s,s,s]}const r=(s,d,c)=>(c<0&&(c+=1),c>1&&(c-=1),c<1/6?s+(d-s)*6*c:c<1/2?d:c<2/3?s+(d-s)*(2/3-c)*6:s),a=n<.5?n*(1+t):n+t-n*t,o=2*n-a;return[Math.round(r(o,a,e+1/3)*255),Math.round(r(o,a,e)*255),Math.round(r(o,a,e-1/3)*255)]}async function ze(e,t){if(t>=155&&t<=165)return e;const n=await ie(e),r=Te(n.width,n.height);r.clearRect(0,0,n.width,n.height),r.drawImage(n,0,0);const a=r.getImageData(0,0,n.width,n.height),o=a.data,s=new Uint32Array(o.buffer),d=t%360/360,c=60/360,u=260/360,p=1e5,h=s.length;for(let w=0;w<h;w+=p){const g=Math.min(w+p,h);for(let v=w;v<g;v++){const b=s[v],k=b&255,P=b>>8&255,T=b>>16&255,I=b>>24&255;if(I===0)continue;const[C,E,D]=Pt(k,P,T);if(E<.06||C<c||C>u)continue;const B=d,[L,_,j]=Ct(B,E,D);s[v]=I<<24|j<<16|_<<8|L}g<h&&await new Promise(v=>setTimeout(v,0))}return r.putImageData(a,0,0),W.toDataURL("image/png")}const St="https://api.stability.ai/v1/generation",Tt="https://api.stability.ai/v2beta/stable-image/edit/remove-background",We="stability_api_key";let ae=null;function Rt(e){ae=e}function Et(){return ae}function jt(){return ae!==null}const Bt={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"},Me=[{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 Lt(e,t){const n=e/t;let r=Me[0],a=1/0;for(const o of Me){const s=o.width/o.height,d=Math.abs(n-s);d<a&&(a=d,r=o)}return r}function Nt(e){return new Promise((t,n)=>{const r=new Image;r.onload=()=>{const a=Lt(r.width,r.height),o=document.createElement("canvas");o.width=a.width,o.height=a.height;const s=o.getContext("2d");if(!s){n(new Error("Failed to get canvas context"));return}const d=r.width/r.height,c=a.width/a.height;let u=0,p=0,h=r.width,w=r.height;d>c?(h=r.height*c,u=(r.width-h)/2):(w=r.width/c,p=(r.height-w)/2),s.drawImage(r,u,p,h,w,0,0,a.width,a.height),t(o.toDataURL("image/png"))},r.onerror=()=>n(new Error("Failed to load image")),r.src=e})}function Xe(e){var s;const t=e.split(","),n=((s=t[0].match(/:(.*?);/))==null?void 0:s[1])||"image/png",r=atob(t[1]),a=r.length,o=new Uint8Array(a);for(let d=0;d<a;d++)o[d]=r.charCodeAt(d);return new Blob([o],{type:n})}function he(){var t;const e=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:ne&&ne.tagName.toUpperCase()==="SCRIPT"&&ne.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(We):null}function $e(e){localStorage.setItem(We,e)}function Pe(){return ae?!0:he()!==null}async function Dt(e){const t=he();if(!t)throw new Error("No Stability AI API key configured");const{imageDataUrl:n,style:r,strength:a=.35}=e,o=await Nt(n),s=Xe(o),d=new FormData;d.append("init_image",s,"portrait.png"),d.append("init_image_mode","IMAGE_STRENGTH"),d.append("image_strength",String(1-a)),d.append("text_prompts[0][text]",Bt[r]),d.append("text_prompts[0][weight]","1"),d.append("cfg_scale","7"),d.append("samples","1"),d.append("steps","30");const u=await fetch(`${St}/stable-diffusion-xl-1024-v1-0/image-to-image`,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"},body:d});if(!u.ok){const h=await u.text();throw console.error("Stability AI error:",h),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 p=await u.json();if(!p.artifacts||p.artifacts.length===0)throw new Error("No image generated");return`data:image/png;base64,${p.artifacts[0].base64}`}async function Oe(e){if(ae){const s=await fetch(ae,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({imageDataUrl:e})});if(!s.ok){const c=await s.json().catch(()=>({}));throw new Error(c.error||`API error: ${s.status}`)}return(await s.json()).imageDataUrl}const t=he();if(!t)throw new Error("No Stability AI API key configured");const n=Xe(e),r=new FormData;r.append("image",n,"image.png"),r.append("output_format","png");const a=await fetch(Tt,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"image/*"},body:r});if(!a.ok){const s=await a.text();throw console.error("Stability AI remove background error:",s),a.status===401?new Error("Invalid API key"):a.status===402?new Error("Insufficient credits"):a.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${a.status}`)}const o=await a.blob();return new Promise((s,d)=>{const c=new FileReader;c.onload=()=>s(c.result),c.onerror=()=>d(new Error("Failed to read result")),c.readAsDataURL(o)})}function Ht(){const[e,t]=m.useState(!1),[n,r]=m.useState(!1),[a,o]=m.useState(null),[s,d]=m.useState(()=>Pe());m.useEffect(()=>{d(Pe())},[]);const c=m.useCallback(()=>o(null),[]),u=m.useCallback(w=>{$e(w),d(!0),o(null)},[]),p=m.useCallback(async(w,g=.5)=>{t(!0),o(null);try{return await _e(w,g)}catch(v){const b=v instanceof Error?v.message:"Enhancement failed";throw o(b),v}finally{t(!1)}},[]),h=m.useCallback(async w=>{r(!0),o(null);try{return await Oe(w)}catch(g){const v=g instanceof Error?g.message:"Background removal failed";throw o(v),g}finally{r(!1)}},[]);return{enhance:p,removeBg:h,isEnhancing:e,isRemovingBg:n,error:a,hasKey:s,setApiKey:u,clearError:c}}function Fe({isOpen:e,onClose:t,onSubmit:n}){const r=x(u=>u.voucherConfig.language),[a,o]=m.useState("");if(!e)return null;const s=u=>{u.preventDefault(),a.trim()&&(n(a.trim()),o(""),t())},c={de:{title:"Stability AI API Key",description:"Um die AI-Bildverbesserung zu nutzen, benötigst du einen Stability AI API Key. Du kannst ihn auf platform.stability.ai erhalten.",placeholder:"sk-...",submit:"Speichern",cancel:"Abbrechen",hint:"Der Key wird lokal in deinem Browser gespeichert."},en:{title:"Stability AI API Key",description:"To use AI image enhancement, you need a Stability AI API key. You can get one at platform.stability.ai.",placeholder:"sk-...",submit:"Save",cancel:"Cancel",hint:"The key is stored locally in your browser."}}[r];return i.jsxs("dialog",{className:"modal modal-open",children:[i.jsxs("div",{className:"modal-box",children:[i.jsx("h3",{className:"font-bold text-lg",children:c.title}),i.jsx("p",{className:"py-4 text-sm opacity-80",children:c.description}),i.jsxs("form",{onSubmit:s,children:[i.jsxs("div",{className:"form-control",children:[i.jsx("input",{type:"password",placeholder:c.placeholder,className:"input input-bordered w-full",value:a,onChange:u=>o(u.target.value),autoFocus:!0}),i.jsx("label",{className:"label",children:i.jsx("span",{className:"label-text-alt",children:c.hint})})]}),i.jsxs("div",{className:"modal-action",children:[i.jsx("button",{type:"button",className:"btn btn-ghost",onClick:t,children:c.cancel}),i.jsx("button",{type:"submit",className:"btn btn-primary",disabled:!a.trim(),children:c.submit})]})]})]}),i.jsx("form",{method:"dialog",className:"modal-backdrop",children:i.jsx("button",{onClick:t,children:"close"})})]})}function Mt(){const e=x(l=>l.voucherConfig.language),t=x(l=>l.portrait),n=x(l=>l.setPortrait),r=x(l=>l.setPortraitZoom),a=x(l=>l.setPortraitPan),o=x(l=>l.setPortraitRawImage),s=x(l=>l.setPortraitBgRemoved),d=x(l=>l.setPortraitBgOpacity),c=x(l=>l.setPortraitBgBlur),u=x(l=>l.setPortraitEngravingIntensity),{enhance:p,removeBg:h,isEnhancing:w,isRemovingBg:g,error:v,hasKey:b,setApiKey:k}=Ht(),P=G(e),T=m.useRef(null),I=m.useRef(null),[C,E]=m.useState(!1),[D,B]=m.useState(!1),[L,_]=m.useState(!1),j=m.useRef(null),H=m.useRef(null),M=m.useRef(null),R=t.rawImage,z=t.bgRemovedImage,A=t.bgRemoved,X=t.bgOpacity,V=t.bgBlur,se=t.engravingIntensity;m.useEffect(()=>{t.original&&!t.rawImage&&o(t.original)},[t.original,t.rawImage,o]),m.useEffect(()=>()=>{H.current&&clearTimeout(H.current),M.current&&clearTimeout(M.current)},[]);const re=m.useCallback(async l=>{if(!l.type.startsWith("image/"))return;const y=new FileReader;y.onload=async S=>{var ue;const U=(ue=S.target)==null?void 0:ue.result,de=await kt(U);o(de),n(de),s(!1,null),u(0)},y.readAsDataURL(l)},[n,o,s,u]),ge=m.useCallback(l=>{l.preventDefault(),E(!1);const y=l.dataTransfer.files[0];y&&re(y)},[re]),f=m.useCallback(l=>{l.preventDefault(),E(!0)},[]),N=m.useCallback(l=>{l.preventDefault(),E(!1)},[]),$=()=>{var l;(l=T.current)==null||l.click()},Z=l=>{var S;const y=(S=l.target.files)==null?void 0:S[0];y&&re(y)},O=m.useCallback(async(l,y)=>{try{return await p(l,y)}catch(S){return console.error("Enhancement failed:",S),l}},[p]),J=m.useCallback(async l=>{try{const y=await h(l);return s(!0,y),y}catch(y){return console.error("Background removal failed:",y),l}},[h,s]),F=m.useCallback(async()=>{const l=x.getState().portrait;if(!l.rawImage)return;let y;l.bgRemoved&&l.bgRemovedImage?y=await ye(l.bgRemovedImage,l.rawImage,l.bgOpacity,l.bgBlur):y=l.rawImage,l.engravingIntensity>0&&(y=await O(y,l.engravingIntensity)),n(y)},[O,n]),oe=async()=>{if(!R)return;if(!A&&!b){B(!0);return}if(!A){const y=await J(R),S=x.getState().portrait;let U=await ye(y,R,S.bgOpacity,S.bgBlur);S.engravingIntensity>0&&(U=await O(U,S.engravingIntensity)),n(U)}else{s(!1,null);const y=x.getState().portrait.engravingIntensity;if(y>0){const S=await O(R,y);n(S)}else n(R)}},fe=l=>{u(l),H.current&&clearTimeout(H.current),R&&(H.current=setTimeout(F,150))},be=async l=>{if(k(l),!R)return;const y=await J(R),S=x.getState().portrait;let U=await ye(y,R,S.bgOpacity,S.bgBlur);S.engravingIntensity>0&&(U=await O(U,S.engravingIntensity)),n(U)},xe=l=>{d(l),M.current&&clearTimeout(M.current),!(!R||!z)&&(M.current=setTimeout(F,150))},le=l=>{c(l),M.current&&clearTimeout(M.current),!(!R||!z)&&(M.current=setTimeout(F,150))},ce=()=>{n(null),o(null),s(!1,null),d(0),c(0),u(0),It()},Le=(l,y)=>{t.zoom<=1||(_(!0),j.current={x:l,y,panX:t.panX,panY:t.panY})},Ne=(l,y)=>{if(!L||!j.current||!I.current)return;const S=I.current.getBoundingClientRect(),U=2/Math.max(S.width,S.height),de=(l-j.current.x)*U,ue=(y-j.current.y)*U,pt=Math.max(-1,Math.min(1,j.current.panX+de)),ht=Math.max(-1,Math.min(1,j.current.panY+ue));a(pt,ht)},we=()=>{_(!1),j.current=null},ot=l=>{l.preventDefault(),Le(l.clientX,l.clientY)},it=l=>{Ne(l.clientX,l.clientY)},st=()=>{we()},lt=()=>{we()},ct=l=>{l.touches.length===1&&Le(l.touches[0].clientX,l.touches[0].clientY)},dt=l=>{l.touches.length===1&&Ne(l.touches[0].clientX,l.touches[0].clientY)},ut=()=>{we()};return i.jsxs("div",{className:"space-y-4",children:[t.original?i.jsxs("div",{className:"flex flex-col items-center space-y-4",children:[i.jsxs("div",{className:"relative",children:[i.jsx("div",{ref:I,className:`w-32 h-32 rounded-full overflow-hidden border-4 border-currency-gold shadow-lg ${t.zoom>1?"cursor-grab":""} ${L?"cursor-grabbing":""}`,onMouseDown:ot,onMouseMove:it,onMouseUp:st,onMouseLeave:lt,onTouchStart:ct,onTouchMove:dt,onTouchEnd:ut,children:i.jsx("img",{src:t.original||"",alt:"Portrait",className:"w-full h-full object-cover pointer-events-none select-none",style:{transform:`scale(${t.zoom}) translate(${t.panX*50*(t.zoom-1)}%, ${t.panY*50*(t.zoom-1)}%)`},draggable:!1})}),i.jsx("button",{className:"btn btn-circle btn-xs btn-error absolute -top-1 -right-1",onClick:ce,children:i.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:i.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),i.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[i.jsxs("div",{className:"form-control w-full",children:[i.jsxs("label",{className:"label",children:[i.jsx("span",{className:"label-text",children:P.form.portrait.zoom}),i.jsxs("span",{className:"label-text-alt",children:[Math.round(t.zoom*100),"%"]})]}),i.jsx("input",{type:"range",min:"0.5",max:"2",step:"0.05",value:t.zoom,onChange:l=>{const y=parseFloat(l.target.value);r(y),y<=1&&(t.panX!==0||t.panY!==0)&&a(0,0)},className:"range range-primary range-sm"})]}),i.jsxs("div",{className:"form-control w-full",children:[i.jsxs("label",{className:"label",children:[i.jsxs("span",{className:"label-text flex items-center gap-2",children:[e==="de"?"Sepia-Effekt":"Sepia effect",w&&i.jsx("span",{className:"loading loading-spinner loading-xs"})]}),i.jsxs("span",{className:"label-text-alt",children:[Math.round(se*100),"%"]})]}),i.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",value:se,onChange:l=>fe(parseFloat(l.target.value)),className:"range range-secondary range-sm",disabled:w||!R})]})]}),A?i.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[i.jsxs("div",{className:"form-control w-full",children:[i.jsxs("label",{className:"label",children:[i.jsx("span",{className:"label-text",children:e==="de"?"Hintergrund":"Background"}),i.jsxs("span",{className:"label-text-alt",children:[Math.round(X*100),"%"]})]}),i.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",value:X,onChange:l=>xe(parseFloat(l.target.value)),className:"range range-primary range-sm"})]}),i.jsxs("div",{className:"form-control w-full",children:[i.jsxs("label",{className:"label",children:[i.jsx("span",{className:"label-text",children:e==="de"?"Unschärfe":"Blur"}),i.jsxs("span",{className:"label-text-alt",children:[Math.round(V*100),"%"]})]}),i.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",value:V,onChange:l=>le(parseFloat(l.target.value)),className:"range range-primary range-sm"})]})]}):i.jsx("div",{className:"form-control",children:i.jsxs("label",{className:"label cursor-pointer justify-start gap-3",children:[i.jsx("input",{type:"checkbox",className:`toggle toggle-primary ${g?"opacity-50":""}`,checked:A,onChange:oe,disabled:g||!R}),i.jsxs("span",{className:"label-text flex items-center gap-2",children:[g?i.jsxs(i.Fragment,{children:[i.jsx("span",{className:"loading loading-spinner loading-xs"}),e==="de"?"Hintergrund wird entfernt...":"Removing background..."]}):e==="de"?"Hintergrund entfernen":"Remove background",!b&&i.jsx("span",{className:"badge badge-sm badge-outline",children:"API"})]})]})}),v&&i.jsxs("div",{className:"alert alert-warning text-sm py-2",children:[i.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:i.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"})}),i.jsx("span",{children:v})]})]}):i.jsxs("div",{className:`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${g?"border-primary bg-primary/10 pointer-events-none":C?"border-primary bg-primary/10":"border-base-300 hover:border-primary hover:bg-base-200"}`,onDrop:ge,onDragOver:f,onDragLeave:N,onClick:$,children:[i.jsx("input",{ref:T,type:"file",accept:"image/*",className:"hidden",onChange:Z}),g?i.jsxs("div",{className:"flex flex-col items-center gap-2",children:[i.jsx("span",{className:"loading loading-spinner loading-lg text-primary"}),i.jsx("p",{className:"font-medium",children:e==="de"?"Hintergrund wird entfernt...":"Removing background..."})]}):i.jsxs("div",{className:"flex flex-col items-center gap-2",children:[i.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:i.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"})}),i.jsx("p",{className:"font-medium",children:P.form.portrait.upload}),i.jsx("p",{className:"text-sm text-base-content/60",children:P.form.portrait.dragDrop})]})]}),i.jsx(Fe,{isOpen:D,onClose:()=>B(!1),onSubmit:be})]})}function At(){return null}const Y=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:ne&&ne.tagName.toUpperCase()==="SCRIPT"&&ne.src||new URL("index.cjs",document.baseURI).href}<"u"&&"/"||"/",Re={en:{1:{front:`${Y}templates/front_ldpi_en.png`,back:`${Y}templates/back_ldpi_en.png`,width:1536,height:1024},5:{front:`${Y}templates/front_ldpi_en.png`,back:`${Y}templates/back_ldpi_en.png`,width:1536,height:1024},10:{front:`${Y}templates/front_ldpi_en.png`,back:`${Y}templates/back_ldpi_en.png`,width:1536,height:1024}},de:{1:{front:`${Y}templates/front_hdpi_de.webp`,back:`${Y}templates/back_hdpi_de.webp`,width:6144,height:3200},5:{front:`${Y}templates/front_hdpi_de.webp`,back:`${Y}templates/back_hdpi_de.webp`,width:6144,height:3200},10:{front:`${Y}templates/front_hdpi_de.webp`,back:`${Y}templates/back_hdpi_de.webp`,width:6144,height:3200}}},q={front:{portrait:{x:768,y:490,radiusX:236,radiusY:258},namePlate:{x:768,y:848,fontSize:36,maxWidth:380,align:"center"}},back:{portrait:{x:0,y:0,radiusX:0,radiusY:0},namePlate:{x:768,y:832,fontSize:36,maxWidth:380,align:"center"},contactInfo:{x:380,y:500,fontSize:38,lineHeight:55,align:"center"},description:{x:1150,y:500,fontSize:38,maxWidth:480,lineHeight:42,align:"center"}}},K={front:{portrait:{x:3074,y:1530,radiusX:942,radiusY:1020},namePlate:{x:3072,y:2950,fontSize:144,maxWidth:1520,align:"center"}},back:{portrait:{x:0,y:0,radiusX:0,radiusY:0},namePlate:{x:3072,y:2930,fontSize:144,maxWidth:1520,align:"center"},contactInfo:{x:1520,y:1680,fontSize:160,lineHeight:280,align:"center"},description:{x:4600,y:1680,fontSize:145,maxWidth:2e3,lineHeight:210,align:"center"}}};function Ee(e){return e==="de"?K:q}function qe(e,t){return Re[e][t]}const Ce=.25;function Ut(e){const t=Ee(e),n=Ce,r=a=>({portrait:{x:a.portrait.x*n,y:a.portrait.y*n,radiusX:a.portrait.radiusX*n,radiusY:a.portrait.radiusY*n},namePlate:{x:a.namePlate.x*n,y:a.namePlate.y*n,fontSize:a.namePlate.fontSize*n,maxWidth:a.namePlate.maxWidth?a.namePlate.maxWidth*n:void 0,lineHeight:a.namePlate.lineHeight?a.namePlate.lineHeight*n:void 0,align:a.namePlate.align},contactInfo:a.contactInfo?{x:a.contactInfo.x*n,y:a.contactInfo.y*n,fontSize:a.contactInfo.fontSize*n,maxWidth:a.contactInfo.maxWidth?a.contactInfo.maxWidth*n:void 0,lineHeight:a.contactInfo.lineHeight?a.contactInfo.lineHeight*n:void 0,align:a.contactInfo.align}:void 0,description:a.description?{x:a.description.x*n,y:a.description.y*n,fontSize:a.description.fontSize*n,maxWidth:a.description.maxWidth?a.description.maxWidth*n:void 0,lineHeight:a.description.lineHeight?a.description.lineHeight*n:void 0,align:a.description.align}:void 0});return{front:r(t.front),back:r(t.back)}}function Yt(e,t){const n=Re[e][t];return{...n,width:Math.round(n.width*Ce),height:Math.round(n.height*Ce)}}const ve=new Map,Q=new Map;async function te(e){return ve.has(e)?ve.get(e):new Promise((t,n)=>{const r=new Image;r.crossOrigin="anonymous",r.onload=()=>{ve.set(e,r),t(r)},r.onerror=n,r.src=e})}function je(e,t,n,r){e.drawImage(t,0,0,n,r)}async function Ke(e,t,n,r){if(t>=155&&t<=165)return te(e);const a=`${e}:${t}:${n}x${r}`;if(Q.has(a))return te(Q.get(a));const o=await te(e),s=document.createElement("canvas");s.width=n,s.height=r;const d=s.getContext("2d");if(!d)throw new Error("Failed to get canvas context");d.drawImage(o,0,0,n,r);const c=s.toDataURL("image/png"),u=await ze(c,t);if(Q.size>20){const p=Q.keys().next().value;p&&Q.delete(p)}return Q.set(a,u),te(u)}function Ge(e,t,n,r,a,o,s=1,d=0,c=0){e.save(),e.beginPath(),e.ellipse(n,r,a,o,0,0,Math.PI*2),e.closePath(),e.clip();const u=t.width/t.height,p=a/o,h=a*2,w=o*2;let g,v;u>p?(v=w,g=w*u):(g=h,v=h/u),g*=s,v*=s;const b=Math.max(0,(g-h)/2),k=Math.max(0,(v-w)/2),P=n-g/2+d*b,T=r-v/2+c*k;e.drawImage(t,P,T,g,v),e.restore()}function Be(e,t,n,r="#2a3a2a"){e.save(),e.font=`${n.fontSize}px "Times New Roman", serif`,e.textAlign=n.align||"center",e.textBaseline="middle",e.fillStyle=r,n.maxWidth?e.fillText(t,n.x,n.y,n.maxWidth):e.fillText(t,n.x,n.y),e.restore()}function Ve(e,t,n,r="#2a3a2a"){e.save(),e.font=`${n.fontSize}px "Times New Roman", serif`,e.textAlign=n.align||"center",e.textBaseline="top",e.fillStyle=r;const a=n.maxWidth||400,o=n.lineHeight||n.fontSize*1.4,s=t.split(" "),d=[];let c="";for(const h of s){const w=c?`${c} ${h}`:h;e.measureText(w).width>a&&c?(d.push(c),c=h):c=w}c&&d.push(c);const u=d.length*o;let p=n.y-u/2;for(const h of d)e.fillText(h,n.x,p),p+=o;e.restore()}function Ze(e,t,n,r,a,o="#2a3a2a"){e.save(),e.font=`${a.fontSize}px "Times New Roman", serif`,e.textAlign=a.align||"center",e.textBaseline="middle",e.fillStyle=o;const s=a.lineHeight||a.fontSize*1.8,d=[t,n,r].filter(Boolean),c=(d.length-1)*s;let u=a.y-c/2;for(const p of d)p&&(e.fillText(p,a.x,u),u+=s);e.restore()}async function Je(e,t,n,r,a,o,s,d=1,c=0,u=0,p=0){const h=e.getContext("2d");if(!h)return;e.width=o,e.height=s,h.clearRect(0,0,o,s);const w=await Ke(t,p,o,s);if(je(h,w,o,s),n)try{const g=await te(n);Ge(h,g,a.portrait.x,a.portrait.y,a.portrait.radiusX,a.portrait.radiusY,d,c,u)}catch(g){console.error("Failed to load portrait:",g)}r&&Be(h,r,a.namePlate)}async function Qe(e,t,n,r,a,o,s,d,c,u=0){const p=e.getContext("2d");if(!p)return;e.width=d,e.height=c,p.clearRect(0,0,d,c);const h=await Ke(t,u,d,c);je(p,h,d,c),s.contactInfo&&(n||r||a)&&Ze(p,n,r,a,s.contactInfo),s.description&&o&&Ve(p,o,s.description),n&&Be(p,n,s.namePlate)}function _t(e,t){const[n,r]=m.useState(e);return m.useEffect(()=>{const a=setTimeout(()=>r(e),t);return()=>clearTimeout(a)},[e,t]),n}function zt(){const e=x(f=>f.voucherConfig.language),t=x(f=>f.voucherConfig.hours),n=x(f=>f.voucherConfig.description),r=x(f=>f.voucherConfig.templateHue),a=x(f=>f.personalInfo),o=x(f=>f.portrait),s=x(f=>f.currentSide),d=x(f=>f.flipSide),c=x(f=>f.setPortraitPan),u=_t(r,150),p=G(e),h=m.useRef(null),w=m.useRef(null),g=m.useRef(null),[v,b]=m.useState(!1),[k,P]=m.useState(!1),T=m.useRef(null),I=Yt(e,t),C=Ut(e),E=o.useEnhanced&&o.enhanced?o.enhanced:o.original,D=Se(e,t,n);m.useEffect(()=>{h.current&&Je(h.current,I.front,E,a.name,C.front,I.width,I.height,o.zoom,o.panX,o.panY,u)},[I,E,a.name,C,o.zoom,o.panX,o.panY,u]),m.useEffect(()=>{w.current&&Qe(w.current,I.back,a.name,a.email,a.phone,D,C.back,I.width,I.height,u)},[I,a,D,C,u]);const B=()=>{b(!0),setTimeout(()=>{d(),b(!1)},150)},L=m.useCallback((f,N)=>{if(!g.current||s!=="front"||!o.original)return!1;const $=g.current.getBoundingClientRect(),Z=$.width/I.width,O=$.height/I.height,J=(f-$.left)/Z,F=(N-$.top)/O,{x:oe,y:fe,radiusX:be,radiusY:xe}=C.front.portrait,le=(J-oe)/be,ce=(F-fe)/xe;return le*le+ce*ce<=1},[s,o.original,I.width,I.height,C.front.portrait]),_=m.useCallback((f,N)=>{o.zoom<=1||!L(f,N)||(P(!0),T.current={x:f,y:N,panX:o.panX,panY:o.panY})},[o.zoom,o.panX,o.panY,L]),j=m.useCallback((f,N)=>{if(!k||!T.current||!g.current)return;const $=g.current.getBoundingClientRect(),Z=3/Math.max($.width,$.height),O=(f-T.current.x)*Z,J=(N-T.current.y)*Z,F=Math.max(-1,Math.min(1,T.current.panX+O)),oe=Math.max(-1,Math.min(1,T.current.panY+J));c(F,oe)},[k,c]),H=m.useCallback(()=>{P(!1),T.current=null},[]),M=f=>{o.zoom>1&&L(f.clientX,f.clientY)&&(f.preventDefault(),_(f.clientX,f.clientY))},R=f=>{j(f.clientX,f.clientY)},z=()=>H(),A=()=>H(),X=f=>{if(f.touches.length===1){const N=f.touches[0];o.zoom>1&&L(N.clientX,N.clientY)&&_(N.clientX,N.clientY)}},V=f=>{f.touches.length===1&&j(f.touches[0].clientX,f.touches[0].clientY)},se=()=>H(),re=s==="front"&&o.original&&o.zoom>1,ge=I.width/I.height;return i.jsxs("div",{className:"space-y-4",children:[i.jsxs("div",{className:"flex justify-between items-center",children:[i.jsxs("div",{className:"tabs tabs-boxed bg-base-200",children:[i.jsx("button",{className:`tab ${s==="front"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>s!=="front"&&B(),children:p.preview.front}),i.jsx("button",{className:`tab ${s==="back"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>s!=="back"&&B(),children:p.preview.back})]}),i.jsxs("button",{className:"btn btn-ghost btn-sm",onClick:B,children:[i.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:i.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"})}),p.preview.flip]})]}),i.jsxs("div",{ref:g,className:`relative w-full overflow-hidden shadow-lg ${re?k?"cursor-grabbing":"cursor-grab":""}`,style:{aspectRatio:ge},onMouseDown:M,onMouseMove:R,onMouseUp:z,onMouseLeave:A,onTouchStart:X,onTouchMove:V,onTouchEnd:se,children:[i.jsx("canvas",{ref:h,className:`absolute inset-0 w-full h-full transition-all duration-300 ${s==="front"?v?"opacity-0 scale-95":"opacity-100 scale-100":"opacity-0 scale-95 pointer-events-none"}`}),i.jsx("canvas",{ref:w,className:`absolute inset-0 w-full h-full transition-all duration-300 ${s==="back"?v?"opacity-0 scale-95":"opacity-100 scale-100":"opacity-0 scale-95 pointer-events-none"}`})]})]})}function Wt(){const e=m.useRef(null),t=m.useRef(null);return{frontCanvasRef:e,backCanvasRef:t}}const Xt=`
2
2
  // RGB to HSL conversion
3
3
  function rgbToHsl(r, g, b) {
4
4
  r /= 255;
package/dist/index.js CHANGED
@@ -357,21 +357,21 @@ async function Ie(e, t, n, r = 0) {
357
357
  }
358
358
  async function ut(e, t = 0.5) {
359
359
  const n = await ce(e), r = Te(n.width, n.height);
360
- r.drawImage(n, 0, 0);
360
+ r.clearRect(0, 0, n.width, n.height), r.drawImage(n, 0, 0);
361
361
  const a = r.getImageData(0, 0, n.width, n.height), o = a.data, i = new Uint32Array(o.buffer), c = 1 + t * 0.8, l = 1 - t;
362
362
  for (let u = 0; u < i.length; u++) {
363
- const p = i[u], h = p & 255, y = p >> 8 & 255, m = p >> 16 & 255, x = p >> 24 & 255;
363
+ const h = i[u], p = h & 255, y = h >> 8 & 255, m = h >> 16 & 255, x = h >> 24 & 255;
364
364
  if (x === 0) continue;
365
- let k = (((77 * h + 150 * y + 29 * m >> 8) / 255 - 0.5) * c + 0.5) * 255;
365
+ let k = (((77 * p + 150 * y + 29 * m >> 8) / 255 - 0.5) * c + 0.5) * 255;
366
366
  k < 0 ? k = 0 : k > 255 && (k = 255);
367
367
  let P = k * 0.9 + 25, T = k * 0.78 + 15, I = k * 0.55 + 5;
368
368
  P > 255 && (P = 255), T > 255 && (T = 255), I > 255 && (I = 255);
369
- const C = h * l + P * t | 0, B = y * l + T * t | 0, M = m * l + I * t | 0;
370
- i[u] = x << 24 | M << 16 | B << 8 | C;
369
+ const C = p * l + P * t | 0, R = y * l + T * t | 0, M = m * l + I * t | 0;
370
+ i[u] = x << 24 | M << 16 | R << 8 | C;
371
371
  }
372
372
  return r.putImageData(a, 0, 0), F.toDataURL("image/png");
373
373
  }
374
- function pt(e, t, n) {
374
+ function ht(e, t, n) {
375
375
  e /= 255, t /= 255, n /= 255;
376
376
  const r = Math.max(e, t, n), a = Math.min(e, t, n), o = (r + a) / 2;
377
377
  let i = 0, c = 0;
@@ -391,7 +391,7 @@ function pt(e, t, n) {
391
391
  }
392
392
  return [i, c, o];
393
393
  }
394
- function ht(e, t, n) {
394
+ function pt(e, t, n) {
395
395
  if (t === 0) {
396
396
  const i = Math.round(n * 255);
397
397
  return [i, i, i];
@@ -407,19 +407,19 @@ async function mt(e, t) {
407
407
  if (t >= 155 && t <= 165)
408
408
  return e;
409
409
  const n = await ce(e), r = Te(n.width, n.height);
410
- r.drawImage(n, 0, 0);
411
- const a = r.getImageData(0, 0, n.width, n.height), o = a.data, i = new Uint32Array(o.buffer), c = t % 360 / 360, l = 60 / 360, u = 260 / 360, p = 1e5, h = i.length;
412
- for (let y = 0; y < h; y += p) {
413
- const m = Math.min(y + p, h);
410
+ r.clearRect(0, 0, n.width, n.height), r.drawImage(n, 0, 0);
411
+ const a = r.getImageData(0, 0, n.width, n.height), o = a.data, i = new Uint32Array(o.buffer), c = t % 360 / 360, l = 60 / 360, u = 260 / 360, h = 1e5, p = i.length;
412
+ for (let y = 0; y < p; y += h) {
413
+ const m = Math.min(y + h, p);
414
414
  for (let x = y; x < m; x++) {
415
415
  const b = i[x], k = b & 255, P = b >> 8 & 255, T = b >> 16 & 255, I = b >> 24 & 255;
416
416
  if (I === 0) continue;
417
- const [C, B, M] = pt(k, P, T);
418
- if (B < 0.06 || C < l || C > u) continue;
419
- const L = c, [H, $, R] = ht(L, B, M);
420
- i[x] = I << 24 | R << 16 | $ << 8 | H;
417
+ const [C, R, M] = ht(k, P, T);
418
+ if (R < 0.06 || C < l || C > u) continue;
419
+ const L = c, [H, $, B] = pt(L, R, M);
420
+ i[x] = I << 24 | B << 16 | $ << 8 | H;
421
421
  }
422
- m < h && await new Promise((x) => setTimeout(x, 0));
422
+ m < p && await new Promise((x) => setTimeout(x, 0));
423
423
  }
424
424
  return r.putImageData(a, 0, 0), F.toDataURL("image/png");
425
425
  }
@@ -470,8 +470,8 @@ function yt(e) {
470
470
  return;
471
471
  }
472
472
  const c = r.width / r.height, l = a.width / a.height;
473
- let u = 0, p = 0, h = r.width, y = r.height;
474
- c > l ? (h = r.height * l, u = (r.width - h) / 2) : (y = r.width / l, p = (r.height - y) / 2), i.drawImage(r, u, p, h, y, 0, 0, a.width, a.height), t(o.toDataURL("image/png"));
473
+ let u = 0, h = 0, p = r.width, y = r.height;
474
+ c > l ? (p = r.height * l, u = (r.width - p) / 2) : (y = r.width / l, h = (r.height - y) / 2), i.drawImage(r, u, h, p, y, 0, 0, a.width, a.height), t(o.toDataURL("image/png"));
475
475
  }, r.onerror = () => n(new Error("Failed to load image")), r.src = e;
476
476
  });
477
477
  }
@@ -508,13 +508,13 @@ async function Zt(e) {
508
508
  body: c
509
509
  });
510
510
  if (!u.ok) {
511
- const h = await u.text();
512
- throw console.error("Stability AI error:", h), 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}`);
511
+ const p = await u.text();
512
+ throw console.error("Stability AI error:", p), 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}`);
513
513
  }
514
- const p = await u.json();
515
- if (!p.artifacts || p.artifacts.length === 0)
514
+ const h = await u.json();
515
+ if (!h.artifacts || h.artifacts.length === 0)
516
516
  throw new Error("No image generated");
517
- return `data:image/png;base64,${p.artifacts[0].base64}`;
517
+ return `data:image/png;base64,${h.artifacts[0].base64}`;
518
518
  }
519
519
  async function xt(e) {
520
520
  if (re) {
@@ -561,7 +561,7 @@ function It() {
561
561
  }, []);
562
562
  const l = N(() => o(null), []), u = N((y) => {
563
563
  vt(y), c(!0), o(null);
564
- }, []), p = N(
564
+ }, []), h = N(
565
565
  async (y, m = 0.5) => {
566
566
  t(!0), o(null);
567
567
  try {
@@ -574,7 +574,7 @@ function It() {
574
574
  }
575
575
  },
576
576
  []
577
- ), h = N(
577
+ ), p = N(
578
578
  async (y) => {
579
579
  r(!0), o(null);
580
580
  try {
@@ -589,8 +589,8 @@ function It() {
589
589
  []
590
590
  );
591
591
  return {
592
- enhance: p,
593
- removeBg: h,
592
+ enhance: h,
593
+ removeBg: p,
594
594
  isEnhancing: e,
595
595
  isRemovingBg: n,
596
596
  error: a,
@@ -651,7 +651,7 @@ function kt({ isOpen: e, onClose: t, onSubmit: n }) {
651
651
  ] });
652
652
  }
653
653
  function Jt() {
654
- const e = w((s) => s.voucherConfig.language), t = w((s) => s.portrait), n = w((s) => s.setPortrait), r = w((s) => s.setPortraitZoom), a = w((s) => s.setPortraitPan), o = w((s) => s.setPortraitRawImage), i = w((s) => s.setPortraitBgRemoved), c = w((s) => s.setPortraitBgOpacity), l = w((s) => s.setPortraitBgBlur), u = w((s) => s.setPortraitEngravingIntensity), { enhance: p, removeBg: h, isEnhancing: y, isRemovingBg: m, error: x, hasKey: b, setApiKey: k } = It(), P = oe(e), T = W(null), I = W(null), [C, B] = X(!1), [M, L] = X(!1), [H, $] = X(!1), R = W(null), A = W(null), U = W(null), E = t.rawImage, O = t.bgRemovedImage, Y = t.bgRemoved, j = t.bgOpacity, V = t.bgBlur, de = t.engravingIntensity;
654
+ const e = w((s) => s.voucherConfig.language), t = w((s) => s.portrait), n = w((s) => s.setPortrait), r = w((s) => s.setPortraitZoom), a = w((s) => s.setPortraitPan), o = w((s) => s.setPortraitRawImage), i = w((s) => s.setPortraitBgRemoved), c = w((s) => s.setPortraitBgOpacity), l = w((s) => s.setPortraitBgBlur), u = w((s) => s.setPortraitEngravingIntensity), { enhance: h, removeBg: p, isEnhancing: y, isRemovingBg: m, error: x, hasKey: b, setApiKey: k } = It(), P = oe(e), T = W(null), I = W(null), [C, R] = X(!1), [M, L] = X(!1), [H, $] = X(!1), B = W(null), A = W(null), U = W(null), E = t.rawImage, O = t.bgRemovedImage, Y = t.bgRemoved, j = t.bgOpacity, V = t.bgBlur, de = t.engravingIntensity;
655
655
  ae(() => {
656
656
  t.original && !t.rawImage && o(t.original);
657
657
  }, [t.original, t.rawImage, o]), ae(() => () => {
@@ -664,22 +664,22 @@ function Jt() {
664
664
  const v = new FileReader();
665
665
  v.onload = async (S) => {
666
666
  var me;
667
- const z = (me = S.target) == null ? void 0 : me.result, he = await dt(z);
668
- o(he), n(he), i(!1, null), u(0);
667
+ const z = (me = S.target) == null ? void 0 : me.result, pe = await dt(z);
668
+ o(pe), n(pe), i(!1, null), u(0);
669
669
  }, v.readAsDataURL(s);
670
670
  },
671
671
  [n, o, i, u]
672
672
  ), be = N(
673
673
  (s) => {
674
- s.preventDefault(), B(!1);
674
+ s.preventDefault(), R(!1);
675
675
  const v = s.dataTransfer.files[0];
676
676
  v && ie(v);
677
677
  },
678
678
  [ie]
679
679
  ), g = N((s) => {
680
- s.preventDefault(), B(!0);
680
+ s.preventDefault(), R(!0);
681
681
  }, []), D = N((s) => {
682
- s.preventDefault(), B(!1);
682
+ s.preventDefault(), R(!1);
683
683
  }, []), K = () => {
684
684
  var s;
685
685
  (s = T.current) == null || s.click();
@@ -689,18 +689,18 @@ function Jt() {
689
689
  v && ie(v);
690
690
  }, q = N(async (s, v) => {
691
691
  try {
692
- return await p(s, v);
692
+ return await h(s, v);
693
693
  } catch (S) {
694
694
  return console.error("Enhancement failed:", S), s;
695
695
  }
696
- }, [p]), J = N(async (s) => {
696
+ }, [h]), J = N(async (s) => {
697
697
  try {
698
- const v = await h(s);
698
+ const v = await p(s);
699
699
  return i(!0, v), v;
700
700
  } catch (v) {
701
701
  return console.error("Background removal failed:", v), s;
702
702
  }
703
- }, [h, i]), G = N(async () => {
703
+ }, [p, i]), G = N(async () => {
704
704
  const s = w.getState().portrait;
705
705
  if (!s.rawImage) return;
706
706
  let v;
@@ -735,33 +735,33 @@ function Jt() {
735
735
  c(s), U.current && clearTimeout(U.current), !(!E || !O) && (U.current = setTimeout(G, 150));
736
736
  }, ue = (s) => {
737
737
  l(s), U.current && clearTimeout(U.current), !(!E || !O) && (U.current = setTimeout(G, 150));
738
- }, pe = () => {
738
+ }, he = () => {
739
739
  n(null), o(null), i(!1, null), c(0), l(0), u(0), ct();
740
- }, Be = (s, v) => {
741
- t.zoom <= 1 || ($(!0), R.current = {
740
+ }, Re = (s, v) => {
741
+ t.zoom <= 1 || ($(!0), B.current = {
742
742
  x: s,
743
743
  y: v,
744
744
  panX: t.panX,
745
745
  panY: t.panY
746
746
  });
747
- }, Re = (s, v) => {
748
- if (!H || !R.current || !I.current) return;
749
- const S = I.current.getBoundingClientRect(), z = 2 / Math.max(S.width, S.height), he = (s - R.current.x) * z, me = (v - R.current.y) * z, Qe = Math.max(-1, Math.min(1, R.current.panX + he)), et = Math.max(-1, Math.min(1, R.current.panY + me));
747
+ }, Be = (s, v) => {
748
+ if (!H || !B.current || !I.current) return;
749
+ const S = I.current.getBoundingClientRect(), z = 2 / Math.max(S.width, S.height), pe = (s - B.current.x) * z, me = (v - B.current.y) * z, Qe = Math.max(-1, Math.min(1, B.current.panX + pe)), et = Math.max(-1, Math.min(1, B.current.panY + me));
750
750
  a(Qe, et);
751
751
  }, xe = () => {
752
- $(!1), R.current = null;
752
+ $(!1), B.current = null;
753
753
  }, je = (s) => {
754
- s.preventDefault(), Be(s.clientX, s.clientY);
754
+ s.preventDefault(), Re(s.clientX, s.clientY);
755
755
  }, Ke = (s) => {
756
- Re(s.clientX, s.clientY);
756
+ Be(s.clientX, s.clientY);
757
757
  }, qe = () => {
758
758
  xe();
759
759
  }, Ge = () => {
760
760
  xe();
761
761
  }, Ve = (s) => {
762
- s.touches.length === 1 && Be(s.touches[0].clientX, s.touches[0].clientY);
763
- }, Ze = (s) => {
764
762
  s.touches.length === 1 && Re(s.touches[0].clientX, s.touches[0].clientY);
763
+ }, Ze = (s) => {
764
+ s.touches.length === 1 && Be(s.touches[0].clientX, s.touches[0].clientY);
765
765
  }, Je = () => {
766
766
  xe();
767
767
  };
@@ -798,7 +798,7 @@ function Jt() {
798
798
  "button",
799
799
  {
800
800
  className: "btn btn-circle btn-xs btn-error absolute -top-1 -right-1",
801
- onClick: pe,
801
+ onClick: he,
802
802
  children: /* @__PURE__ */ d(
803
803
  "svg",
804
804
  {
@@ -1217,17 +1217,17 @@ async function Oe(e, t, n, r) {
1217
1217
  c.drawImage(o, 0, 0, n, r);
1218
1218
  const l = i.toDataURL("image/png"), u = await mt(l, t);
1219
1219
  if (Q.size > 20) {
1220
- const p = Q.keys().next().value;
1221
- p && Q.delete(p);
1220
+ const h = Q.keys().next().value;
1221
+ h && Q.delete(h);
1222
1222
  }
1223
1223
  return Q.set(a, u), le(u);
1224
1224
  }
1225
1225
  function Tt(e, t, n, r, a, o, i = 1, c = 0, l = 0) {
1226
1226
  e.save(), e.beginPath(), e.ellipse(n, r, a, o, 0, 0, Math.PI * 2), e.closePath(), e.clip();
1227
- const u = t.width / t.height, p = a / o, h = a * 2, y = o * 2;
1227
+ const u = t.width / t.height, h = a / o, p = a * 2, y = o * 2;
1228
1228
  let m, x;
1229
- u > p ? (x = y, m = y * u) : (m = h, x = h / u), m *= i, x *= i;
1230
- const b = Math.max(0, (m - h) / 2), k = Math.max(0, (x - y) / 2), P = n - m / 2 + c * b, T = r - x / 2 + l * k;
1229
+ u > h ? (x = y, m = y * u) : (m = p, x = p / u), m *= i, x *= i;
1230
+ const b = Math.max(0, (m - p) / 2), k = Math.max(0, (x - y) / 2), P = n - m / 2 + c * b, T = r - x / 2 + l * k;
1231
1231
  e.drawImage(t, P, T, m, x), e.restore();
1232
1232
  }
1233
1233
  function Fe(e, t, n, r = "#2a3a2a") {
@@ -1237,35 +1237,35 @@ function Et(e, t, n, r = "#2a3a2a") {
1237
1237
  e.save(), e.font = `${n.fontSize}px "Times New Roman", serif`, e.textAlign = n.align || "center", e.textBaseline = "top", e.fillStyle = r;
1238
1238
  const a = n.maxWidth || 400, o = n.lineHeight || n.fontSize * 1.4, i = t.split(" "), c = [];
1239
1239
  let l = "";
1240
- for (const h of i) {
1241
- const y = l ? `${l} ${h}` : h;
1242
- e.measureText(y).width > a && l ? (c.push(l), l = h) : l = y;
1240
+ for (const p of i) {
1241
+ const y = l ? `${l} ${p}` : p;
1242
+ e.measureText(y).width > a && l ? (c.push(l), l = p) : l = y;
1243
1243
  }
1244
1244
  l && c.push(l);
1245
1245
  const u = c.length * o;
1246
- let p = n.y - u / 2;
1247
- for (const h of c)
1248
- e.fillText(h, n.x, p), p += o;
1246
+ let h = n.y - u / 2;
1247
+ for (const p of c)
1248
+ e.fillText(p, n.x, h), h += o;
1249
1249
  e.restore();
1250
1250
  }
1251
- function Bt(e, t, n, r, a, o = "#2a3a2a") {
1251
+ function Rt(e, t, n, r, a, o = "#2a3a2a") {
1252
1252
  e.save(), e.font = `${a.fontSize}px "Times New Roman", serif`, e.textAlign = a.align || "center", e.textBaseline = "middle", e.fillStyle = o;
1253
1253
  const i = a.lineHeight || a.fontSize * 1.8, c = [t, n, r].filter(Boolean), l = (c.length - 1) * i;
1254
1254
  let u = a.y - l / 2;
1255
- for (const p of c)
1256
- p && (e.fillText(p, a.x, u), u += i);
1255
+ for (const h of c)
1256
+ h && (e.fillText(h, a.x, u), u += i);
1257
1257
  e.restore();
1258
1258
  }
1259
- async function Rt(e, t, n, r, a, o, i, c = 1, l = 0, u = 0, p = 0) {
1260
- const h = e.getContext("2d");
1261
- if (!h) return;
1262
- e.width = o, e.height = i, h.clearRect(0, 0, o, i);
1263
- const y = await Oe(t, p, o, i);
1264
- if ($e(h, y, o, i), n)
1259
+ async function Bt(e, t, n, r, a, o, i, c = 1, l = 0, u = 0, h = 0) {
1260
+ const p = e.getContext("2d");
1261
+ if (!p) return;
1262
+ e.width = o, e.height = i, p.clearRect(0, 0, o, i);
1263
+ const y = await Oe(t, h, o, i);
1264
+ if ($e(p, y, o, i), n)
1265
1265
  try {
1266
1266
  const m = await le(n);
1267
1267
  Tt(
1268
- h,
1268
+ p,
1269
1269
  m,
1270
1270
  a.portrait.x,
1271
1271
  a.portrait.y,
@@ -1278,14 +1278,14 @@ async function Rt(e, t, n, r, a, o, i, c = 1, l = 0, u = 0, p = 0) {
1278
1278
  } catch (m) {
1279
1279
  console.error("Failed to load portrait:", m);
1280
1280
  }
1281
- r && Fe(h, r, a.namePlate);
1281
+ r && Fe(p, r, a.namePlate);
1282
1282
  }
1283
1283
  async function Nt(e, t, n, r, a, o, i, c, l, u = 0) {
1284
- const p = e.getContext("2d");
1285
- if (!p) return;
1286
- e.width = c, e.height = l, p.clearRect(0, 0, c, l);
1287
- const h = await Oe(t, u, c, l);
1288
- $e(p, h, c, l), i.contactInfo && (n || r || a) && Bt(p, n, r, a, i.contactInfo), i.description && o && Et(p, o, i.description), n && Fe(p, n, i.namePlate);
1284
+ const h = e.getContext("2d");
1285
+ if (!h) return;
1286
+ e.width = c, e.height = l, h.clearRect(0, 0, c, l);
1287
+ const p = await Oe(t, u, c, l);
1288
+ $e(h, p, c, l), i.contactInfo && (n || r || a) && Rt(h, n, r, a, i.contactInfo), i.description && o && Et(h, o, i.description), n && Fe(h, n, i.namePlate);
1289
1289
  }
1290
1290
  function Lt(e, t) {
1291
1291
  const [n, r] = X(e);
@@ -1295,12 +1295,12 @@ function Lt(e, t) {
1295
1295
  }, [e, t]), n;
1296
1296
  }
1297
1297
  function en() {
1298
- const e = w((g) => g.voucherConfig.language), t = w((g) => g.voucherConfig.hours), n = w((g) => g.voucherConfig.description), r = w((g) => g.voucherConfig.templateHue), a = w((g) => g.personalInfo), o = w((g) => g.portrait), i = w((g) => g.currentSide), c = w((g) => g.flipSide), l = w((g) => g.setPortraitPan), u = Lt(r, 150), p = oe(e), h = W(null), y = W(null), m = W(null), [x, b] = X(!1), [k, P] = X(!1), T = W(null), I = St(e, t), C = Ct(e), B = o.useEnhanced && o.enhanced ? o.enhanced : o.original, M = Ye(e, t, n);
1298
+ const e = w((g) => g.voucherConfig.language), t = w((g) => g.voucherConfig.hours), n = w((g) => g.voucherConfig.description), r = w((g) => g.voucherConfig.templateHue), a = w((g) => g.personalInfo), o = w((g) => g.portrait), i = w((g) => g.currentSide), c = w((g) => g.flipSide), l = w((g) => g.setPortraitPan), u = Lt(r, 150), h = oe(e), p = W(null), y = W(null), m = W(null), [x, b] = X(!1), [k, P] = X(!1), T = W(null), I = St(e, t), C = Ct(e), R = o.useEnhanced && o.enhanced ? o.enhanced : o.original, M = Ye(e, t, n);
1299
1299
  ae(() => {
1300
- h.current && Rt(
1301
- h.current,
1300
+ p.current && Bt(
1301
+ p.current,
1302
1302
  I.front,
1303
- B,
1303
+ R,
1304
1304
  a.name,
1305
1305
  C.front,
1306
1306
  I.width,
@@ -1310,7 +1310,7 @@ function en() {
1310
1310
  o.panY,
1311
1311
  u
1312
1312
  );
1313
- }, [I, B, a.name, C, o.zoom, o.panX, o.panY, u]), ae(() => {
1313
+ }, [I, R, a.name, C, o.zoom, o.panX, o.panY, u]), ae(() => {
1314
1314
  y.current && Nt(
1315
1315
  y.current,
1316
1316
  I.back,
@@ -1330,8 +1330,8 @@ function en() {
1330
1330
  }, 150);
1331
1331
  }, H = N((g, D) => {
1332
1332
  if (!m.current || i !== "front" || !o.original) return !1;
1333
- const K = m.current.getBoundingClientRect(), Z = K.width / I.width, q = K.height / I.height, J = (g - K.left) / Z, G = (D - K.top) / q, { x: se, y: we, radiusX: ye, radiusY: ve } = C.front.portrait, ue = (J - se) / ye, pe = (G - we) / ve;
1334
- return ue * ue + pe * pe <= 1;
1333
+ const K = m.current.getBoundingClientRect(), Z = K.width / I.width, q = K.height / I.height, J = (g - K.left) / Z, G = (D - K.top) / q, { x: se, y: we, radiusX: ye, radiusY: ve } = C.front.portrait, ue = (J - se) / ye, he = (G - we) / ve;
1334
+ return ue * ue + he * he <= 1;
1335
1335
  }, [i, o.original, I.width, I.height, C.front.portrait]), $ = N((g, D) => {
1336
1336
  o.zoom <= 1 || !H(g, D) || (P(!0), T.current = {
1337
1337
  x: g,
@@ -1339,7 +1339,7 @@ function en() {
1339
1339
  panX: o.panX,
1340
1340
  panY: o.panY
1341
1341
  });
1342
- }, [o.zoom, o.panX, o.panY, H]), R = N((g, D) => {
1342
+ }, [o.zoom, o.panX, o.panY, H]), B = N((g, D) => {
1343
1343
  if (!k || !T.current || !m.current) return;
1344
1344
  const K = m.current.getBoundingClientRect(), Z = 3 / Math.max(K.width, K.height), q = (g - T.current.x) * Z, J = (D - T.current.y) * Z, G = Math.max(-1, Math.min(1, T.current.panX + q)), se = Math.max(-1, Math.min(1, T.current.panY + J));
1345
1345
  l(G, se);
@@ -1348,14 +1348,14 @@ function en() {
1348
1348
  }, []), U = (g) => {
1349
1349
  o.zoom > 1 && H(g.clientX, g.clientY) && (g.preventDefault(), $(g.clientX, g.clientY));
1350
1350
  }, E = (g) => {
1351
- R(g.clientX, g.clientY);
1351
+ B(g.clientX, g.clientY);
1352
1352
  }, O = () => A(), Y = () => A(), j = (g) => {
1353
1353
  if (g.touches.length === 1) {
1354
1354
  const D = g.touches[0];
1355
1355
  o.zoom > 1 && H(D.clientX, D.clientY) && $(D.clientX, D.clientY);
1356
1356
  }
1357
1357
  }, V = (g) => {
1358
- g.touches.length === 1 && R(g.touches[0].clientX, g.touches[0].clientY);
1358
+ g.touches.length === 1 && B(g.touches[0].clientX, g.touches[0].clientY);
1359
1359
  }, de = () => A(), ie = i === "front" && o.original && o.zoom > 1, be = I.width / I.height;
1360
1360
  return /* @__PURE__ */ f("div", { className: "space-y-4", children: [
1361
1361
  /* @__PURE__ */ f("div", { className: "flex justify-between items-center", children: [
@@ -1365,7 +1365,7 @@ function en() {
1365
1365
  {
1366
1366
  className: `tab ${i === "front" ? "tab-active bg-primary text-primary-content font-semibold" : ""}`,
1367
1367
  onClick: () => i !== "front" && L(),
1368
- children: p.preview.front
1368
+ children: h.preview.front
1369
1369
  }
1370
1370
  ),
1371
1371
  /* @__PURE__ */ d(
@@ -1373,7 +1373,7 @@ function en() {
1373
1373
  {
1374
1374
  className: `tab ${i === "back" ? "tab-active bg-primary text-primary-content font-semibold" : ""}`,
1375
1375
  onClick: () => i !== "back" && L(),
1376
- children: p.preview.back
1376
+ children: h.preview.back
1377
1377
  }
1378
1378
  )
1379
1379
  ] }),
@@ -1397,7 +1397,7 @@ function en() {
1397
1397
  )
1398
1398
  }
1399
1399
  ),
1400
- p.preview.flip
1400
+ h.preview.flip
1401
1401
  ] })
1402
1402
  ] }),
1403
1403
  /* @__PURE__ */ f(
@@ -1417,7 +1417,7 @@ function en() {
1417
1417
  /* @__PURE__ */ d(
1418
1418
  "canvas",
1419
1419
  {
1420
- ref: h,
1420
+ ref: p,
1421
1421
  className: `absolute inset-0 w-full h-full transition-all duration-300 ${i === "front" ? x ? "opacity-0 scale-95" : "opacity-100 scale-100" : "opacity-0 scale-95 pointer-events-none"}`
1422
1422
  }
1423
1423
  ),
@@ -1821,8 +1821,8 @@ async function Mt(e) {
1821
1821
  portraitZoom: c = 1,
1822
1822
  portraitPanX: l = 0,
1823
1823
  portraitPanY: u = 0,
1824
- templateHue: p = 160,
1825
- name: h,
1824
+ templateHue: h = 160,
1825
+ name: p,
1826
1826
  email: y,
1827
1827
  phone: m,
1828
1828
  description: x
@@ -1832,15 +1832,15 @@ async function Mt(e) {
1832
1832
  ]);
1833
1833
  let P = null;
1834
1834
  return i && (P = await Ce(i)), new Promise((T, I) => {
1835
- const C = Dt(), B = (L) => {
1836
- if (C.removeEventListener("message", B), C.removeEventListener("error", M), URL.revokeObjectURL(b), URL.revokeObjectURL(k), P && URL.revokeObjectURL(P), L.data.type === "success")
1835
+ const C = Dt(), R = (L) => {
1836
+ if (C.removeEventListener("message", R), C.removeEventListener("error", M), URL.revokeObjectURL(b), URL.revokeObjectURL(k), P && URL.revokeObjectURL(P), L.data.type === "success")
1837
1837
  try {
1838
- const { frontImageData: H, backImageData: $, width: R, height: A } = L.data;
1839
- if (!H || !$ || !R || !A) {
1838
+ const { frontImageData: H, backImageData: $, width: B, height: A } = L.data;
1839
+ if (!H || !$ || !B || !A) {
1840
1840
  I(new Error("Invalid response from worker"));
1841
1841
  return;
1842
1842
  }
1843
- const U = Ae(H, "image/jpeg"), E = Ae($, "image/jpeg"), O = R / 96 * 25.4, Y = A / 96 * 25.4, j = new rt({
1843
+ const U = Ae(H, "image/jpeg"), E = Ae($, "image/jpeg"), O = B / 96 * 25.4, Y = A / 96 * 25.4, j = new rt({
1844
1844
  orientation: O > Y ? "landscape" : "portrait",
1845
1845
  unit: "mm",
1846
1846
  format: [O, Y]
@@ -1854,16 +1854,16 @@ async function Mt(e) {
1854
1854
  else
1855
1855
  I(new Error(L.data.error));
1856
1856
  }, M = (L) => {
1857
- C.removeEventListener("message", B), C.removeEventListener("error", M), URL.revokeObjectURL(b), URL.revokeObjectURL(k), P && URL.revokeObjectURL(P), I(new Error(L.message));
1857
+ C.removeEventListener("message", R), C.removeEventListener("error", M), URL.revokeObjectURL(b), URL.revokeObjectURL(k), P && URL.revokeObjectURL(P), I(new Error(L.message));
1858
1858
  };
1859
- C.addEventListener("message", B), C.addEventListener("error", M), C.postMessage({
1859
+ C.addEventListener("message", R), C.addEventListener("error", M), C.postMessage({
1860
1860
  type: "generate",
1861
1861
  frontTemplateUrl: b,
1862
1862
  backTemplateUrl: k,
1863
1863
  portraitUrl: P,
1864
1864
  templateWidth: r,
1865
1865
  templateHeight: a,
1866
- templateHue: p,
1866
+ templateHue: h,
1867
1867
  portraitZoom: c,
1868
1868
  portraitPanX: l,
1869
1869
  portraitPanY: u,
@@ -1878,7 +1878,7 @@ async function Mt(e) {
1878
1878
  description: o.back.description
1879
1879
  }
1880
1880
  },
1881
- name: h,
1881
+ name: p,
1882
1882
  email: y,
1883
1883
  phone: m,
1884
1884
  description: x
@@ -1894,7 +1894,7 @@ async function Ut(e) {
1894
1894
  At(t, e.filename);
1895
1895
  }
1896
1896
  function nn() {
1897
- const e = w((b) => b.voucherConfig.language), t = w((b) => b.voucherConfig.hours), n = w((b) => b.voucherConfig.description), r = w((b) => b.voucherConfig.templateHue), a = w((b) => b.personalInfo), o = w((b) => b.portrait), i = w((b) => b.isExporting), c = w((b) => b.setIsExporting), l = oe(e), u = Pt(e, t), p = Xe(e), h = o.useEnhanced && o.enhanced ? o.enhanced : o.original, y = Ye(e, t, n), m = a.name.trim().length > 0 && a.email.trim().length > 0 && a.phone.trim().length > 0 && o.original !== null;
1897
+ const e = w((b) => b.voucherConfig.language), t = w((b) => b.voucherConfig.hours), n = w((b) => b.voucherConfig.description), r = w((b) => b.voucherConfig.templateHue), a = w((b) => b.personalInfo), o = w((b) => b.portrait), i = w((b) => b.isExporting), c = w((b) => b.setIsExporting), l = oe(e), u = Pt(e, t), h = Xe(e), p = o.useEnhanced && o.enhanced ? o.enhanced : o.original, y = Ye(e, t, n), m = a.name.trim().length > 0 && a.email.trim().length > 0 && a.phone.trim().length > 0 && o.original !== null;
1898
1898
  return /* @__PURE__ */ f(
1899
1899
  "button",
1900
1900
  {
@@ -1909,8 +1909,8 @@ function nn() {
1909
1909
  backTemplateSrc: u.back,
1910
1910
  templateWidth: u.width,
1911
1911
  templateHeight: u.height,
1912
- layout: p,
1913
- portrait: h,
1912
+ layout: h,
1913
+ portrait: p,
1914
1914
  portraitZoom: o.zoom,
1915
1915
  portraitPanX: o.panX,
1916
1916
  portraitPanY: o.panY,
@@ -2160,7 +2160,7 @@ export {
2160
2160
  ut as applyEngravingEffect,
2161
2161
  mt as applyHueShift,
2162
2162
  At as downloadBlob,
2163
- Bt as drawContactInfo,
2163
+ Rt as drawContactInfo,
2164
2164
  Et as drawMultilineText,
2165
2165
  Tt as drawOvalPortrait,
2166
2166
  $e as drawTemplate,
@@ -2182,7 +2182,7 @@ export {
2182
2182
  le as loadImage,
2183
2183
  xt as removeBackground,
2184
2184
  Nt as renderBackSide,
2185
- Rt as renderFrontSide,
2185
+ Bt as renderFrontSide,
2186
2186
  vt as setApiKey,
2187
2187
  qt as setRemoveBackgroundEndpoint,
2188
2188
  on as setTemplateProvider,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antontranelis/money-printer",
3
- "version": "1.0.21",
3
+ "version": "1.0.22",
4
4
  "description": "Create personalized time vouchers that look like real currency. React components for voucher generation with PDF export.",
5
5
  "type": "module",
6
6
  "license": "MIT",