@antontranelis/money-printer 1.0.23 → 1.0.24
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 +3 -3
- package/dist/index.js +132 -132
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=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 He={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},b=mt.create()(gt.persist(e=>({...He,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(He)}),{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 F(e){return wt[e]}function Te(e,t,n){if(n&&n.trim())return n;const r=F(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=b(a=>a.voucherConfig.language),t=b(a=>a.personalInfo),n=b(a=>a.setPersonalInfo),r=F(e);return o.jsxs("div",{className:"space-y-4",children:[o.jsxs("div",{className:"form-control",children:[o.jsx("label",{className:"label",children:o.jsx("span",{className:"label-text font-medium",children:r.form.personalInfo.name})}),o.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})})]}),o.jsxs("div",{className:"form-control",children:[o.jsx("label",{className:"label",children:o.jsx("span",{className:"label-text font-medium",children:r.form.personalInfo.email})}),o.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})})]}),o.jsxs("div",{className:"form-control",children:[o.jsx("label",{className:"label",children:o.jsx("span",{className:"label-text font-medium",children:r.form.personalInfo.phone})}),o.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,De=null;function je(e,t){return W||(W=document.createElement("canvas"),De=W.getContext("2d",{willReadFrequently:!0})),(W.width!==e||W.height!==t)&&(W.width=e,W.height=t),De}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 i=ee.keys().next().value;i&&ee.delete(i)}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,i=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=i,d.height=s,c.drawImage(n,0,0,i,s),d.toDataURL("image/jpeg",.9)}async function ye(e,t,n,r=0){const[a,i]=await Promise.all([ie(e),ie(t)]),s=je(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(i,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=je(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),i=a.data,s=new Uint32Array(i.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,j=k*.78+15,I=k*.55+5;P>255&&(P=255),j>255&&(j=255),I>255&&(I=255);const C=h*c+P*t|0,R=w*c+j*t|0,H=g*c+I*t|0;s[u]=v<<24|H<<16|R<<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),i=(r+a)/2;let s=0,d=0;if(r!==a){const c=r-a;switch(d=i>.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,i]}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,i=2*n-a;return[Math.round(r(i,a,e+1/3)*255),Math.round(r(i,a,e)*255),Math.round(r(i,a,e-1/3)*255)]}async function ze(e,t){if(t>=155&&t<=165)return e;const n=await ie(e),r=je(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),i=a.data,s=new Uint32Array(i.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 x=s[v],k=x&255,P=x>>8&255,j=x>>16&255,I=x>>24&255;if(I===0)continue;const[C,R,H]=Pt(k,P,j);if(R<.06||C<c||C>u)continue;const B=d,[N,_,E]=Ct(B,R,H);s[v]=I<<24|E<<16|_<<8|N}g<h&&await new Promise(v=>setTimeout(v,0))}return r.putImageData(a,0,0),W.toDataURL("image/png")}const Tt="https://api.stability.ai/v1/generation",jt="https://api.stability.ai/v2beta/stable-image/edit/remove-background",We="stability_api_key";let ae=null;function St(e){ae=e}function Rt(){return ae}function Et(){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 Nt(e,t){const n=e/t;let r=Me[0],a=1/0;for(const i of Me){const s=i.width/i.height,d=Math.abs(n-s);d<a&&(a=d,r=i)}return r}function Lt(e){return new Promise((t,n)=>{const r=new Image;r.onload=()=>{const a=Nt(r.width,r.height),i=document.createElement("canvas");i.width=a.width,i.height=a.height;const s=i.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(i.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,i=new Uint8Array(a);for(let d=0;d<a;d++)i[d]=r.charCodeAt(d);return new Blob([i],{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 Ht(e){const t=he();if(!t)throw new Error("No Stability AI API key configured");const{imageDataUrl:n,style:r,strength:a=.35}=e,i=await Lt(n),s=Xe(i),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(`${Tt}/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(jt,{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 i=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(i)})}function Dt(){const[e,t]=m.useState(!1),[n,r]=m.useState(!1),[a,i]=m.useState(null),[s,d]=m.useState(()=>Pe());m.useEffect(()=>{d(Pe())},[]);const c=m.useCallback(()=>i(null),[]),u=m.useCallback(w=>{$e(w),d(!0),i(null)},[]),p=m.useCallback(async(w,g=.5)=>{t(!0),i(null);try{return await _e(w,g)}catch(v){const x=v instanceof Error?v.message:"Enhancement failed";throw i(x),v}finally{t(!1)}},[]),h=m.useCallback(async w=>{r(!0),i(null);try{return await Oe(w)}catch(g){const v=g instanceof Error?g.message:"Background removal failed";throw i(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=b(u=>u.voucherConfig.language),[a,i]=m.useState("");if(!e)return null;const s=u=>{u.preventDefault(),a.trim()&&(n(a.trim()),i(""),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 o.jsxs("dialog",{className:"modal modal-open",children:[o.jsxs("div",{className:"modal-box",children:[o.jsx("h3",{className:"font-bold text-lg",children:c.title}),o.jsx("p",{className:"py-4 text-sm opacity-80",children:c.description}),o.jsxs("form",{onSubmit:s,children:[o.jsxs("div",{className:"form-control",children:[o.jsx("input",{type:"password",placeholder:c.placeholder,className:"input input-bordered w-full",value:a,onChange:u=>i(u.target.value),autoFocus:!0}),o.jsx("label",{className:"label",children:o.jsx("span",{className:"label-text-alt",children:c.hint})})]}),o.jsxs("div",{className:"modal-action",children:[o.jsx("button",{type:"button",className:"btn btn-ghost",onClick:t,children:c.cancel}),o.jsx("button",{type:"submit",className:"btn btn-primary",disabled:!a.trim(),children:c.submit})]})]})]}),o.jsx("form",{method:"dialog",className:"modal-backdrop",children:o.jsx("button",{onClick:t,children:"close"})})]})}function Mt(){const e=b(l=>l.voucherConfig.language),t=b(l=>l.portrait),n=b(l=>l.setPortrait),r=b(l=>l.setPortraitZoom),a=b(l=>l.setPortraitPan),i=b(l=>l.setPortraitRawImage),s=b(l=>l.setPortraitBgRemoved),d=b(l=>l.setPortraitBgOpacity),c=b(l=>l.setPortraitBgBlur),u=b(l=>l.setPortraitEngravingIntensity),{enhance:p,removeBg:h,isEnhancing:w,isRemovingBg:g,error:v,hasKey:x,setApiKey:k}=Dt(),P=F(e),j=m.useRef(null),I=m.useRef(null),[C,R]=m.useState(!1),[H,B]=m.useState(!1),[N,_]=m.useState(!1),E=m.useRef(null),D=m.useRef(null),M=m.useRef(null),S=t.rawImage,z=t.bgRemovedImage,A=t.bgRemoved,X=t.bgOpacity,V=t.bgBlur,se=t.engravingIntensity;m.useEffect(()=>{t.original&&!t.rawImage&&i(t.original)},[t.original,t.rawImage,i]),m.useEffect(()=>()=>{D.current&&clearTimeout(D.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 T=>{var ue;const U=(ue=T.target)==null?void 0:ue.result,de=await kt(U);i(de),n(de),s(!1,null),u(0)},y.readAsDataURL(l)},[n,i,s,u]),ge=m.useCallback(l=>{l.preventDefault(),R(!1);const y=l.dataTransfer.files[0];y&&re(y)},[re]),f=m.useCallback(l=>{l.preventDefault(),R(!0)},[]),L=m.useCallback(l=>{l.preventDefault(),R(!1)},[]),$=()=>{var l;(l=j.current)==null||l.click()},Z=l=>{var T;const y=(T=l.target.files)==null?void 0:T[0];y&&re(y)},O=m.useCallback(async(l,y)=>{try{return await p(l,y)}catch(T){return console.error("Enhancement failed:",T),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]),q=m.useCallback(async()=>{const l=b.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(!S)return;if(!A&&!x){B(!0);return}if(!A){const y=await J(S),T=b.getState().portrait;let U=await ye(y,S,T.bgOpacity,T.bgBlur);T.engravingIntensity>0&&(U=await O(U,T.engravingIntensity)),n(U)}else{s(!1,null);const y=b.getState().portrait.engravingIntensity;if(y>0){const T=await O(S,y);n(T)}else n(S)}},fe=l=>{u(l),D.current&&clearTimeout(D.current),S&&(D.current=setTimeout(q,150))},be=async l=>{if(k(l),!S)return;const y=await J(S),T=b.getState().portrait;let U=await ye(y,S,T.bgOpacity,T.bgBlur);T.engravingIntensity>0&&(U=await O(U,T.engravingIntensity)),n(U)},xe=l=>{d(l),M.current&&clearTimeout(M.current),!(!S||!z)&&(M.current=setTimeout(q,150))},le=l=>{c(l),M.current&&clearTimeout(M.current),!(!S||!z)&&(M.current=setTimeout(q,150))},ce=()=>{n(null),i(null),s(!1,null),d(0),c(0),u(0),It()},Ne=(l,y)=>{t.zoom<=1||(_(!0),E.current={x:l,y,panX:t.panX,panY:t.panY})},Le=(l,y)=>{if(!N||!E.current||!I.current)return;const T=I.current.getBoundingClientRect(),U=2/Math.max(T.width,T.height),de=(l-E.current.x)*U,ue=(y-E.current.y)*U,pt=Math.max(-1,Math.min(1,E.current.panX+de)),ht=Math.max(-1,Math.min(1,E.current.panY+ue));a(pt,ht)},we=()=>{_(!1),E.current=null},ot=l=>{l.preventDefault(),Ne(l.clientX,l.clientY)},it=l=>{Le(l.clientX,l.clientY)},st=()=>{we()},lt=()=>{we()},ct=l=>{l.touches.length===1&&Ne(l.touches[0].clientX,l.touches[0].clientY)},dt=l=>{l.touches.length===1&&Le(l.touches[0].clientX,l.touches[0].clientY)},ut=()=>{we()};return o.jsxs("div",{className:"space-y-4",children:[t.original?o.jsxs("div",{className:"flex flex-col items-center space-y-4",children:[o.jsxs("div",{className:"relative",children:[o.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":""} ${N?"cursor-grabbing":""}`,onMouseDown:ot,onMouseMove:it,onMouseUp:st,onMouseLeave:lt,onTouchStart:ct,onTouchMove:dt,onTouchEnd:ut,children:o.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})}),o.jsx("button",{className:"btn btn-circle btn-xs btn-error absolute -top-1 -right-1",onClick:ce,children:o.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:o.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),o.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[o.jsxs("div",{className:"form-control w-full",children:[o.jsxs("label",{className:"label",children:[o.jsx("span",{className:"label-text",children:P.form.portrait.zoom}),o.jsxs("span",{className:"label-text-alt",children:[Math.round(t.zoom*100),"%"]})]}),o.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"})]}),o.jsxs("div",{className:"form-control w-full",children:[o.jsxs("label",{className:"label",children:[o.jsxs("span",{className:"label-text flex items-center gap-2",children:[e==="de"?"Sepia-Effekt":"Sepia effect",w&&o.jsx("span",{className:"loading loading-spinner loading-xs"})]}),o.jsxs("span",{className:"label-text-alt",children:[Math.round(se*100),"%"]})]}),o.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||!S})]})]}),A?o.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[o.jsxs("div",{className:"form-control w-full",children:[o.jsxs("label",{className:"label",children:[o.jsx("span",{className:"label-text",children:e==="de"?"Hintergrund":"Background"}),o.jsxs("span",{className:"label-text-alt",children:[Math.round(X*100),"%"]})]}),o.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"})]}),o.jsxs("div",{className:"form-control w-full",children:[o.jsxs("label",{className:"label",children:[o.jsx("span",{className:"label-text",children:e==="de"?"Unschärfe":"Blur"}),o.jsxs("span",{className:"label-text-alt",children:[Math.round(V*100),"%"]})]}),o.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"})]})]}):o.jsx("div",{className:"form-control",children:o.jsxs("label",{className:"label cursor-pointer justify-start gap-3",children:[o.jsx("input",{type:"checkbox",className:`toggle toggle-primary ${g?"opacity-50":""}`,checked:A,onChange:oe,disabled:g||!S}),o.jsxs("span",{className:"label-text flex items-center gap-2",children:[g?o.jsxs(o.Fragment,{children:[o.jsx("span",{className:"loading loading-spinner loading-xs"}),e==="de"?"Hintergrund wird entfernt...":"Removing background..."]}):e==="de"?"Hintergrund entfernen":"Remove background",!x&&o.jsx("span",{className:"badge badge-sm badge-outline",children:"API"})]})]})}),v&&o.jsxs("div",{className:"alert alert-warning text-sm py-2",children:[o.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:o.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"})}),o.jsx("span",{children:v})]})]}):o.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:L,onClick:$,children:[o.jsx("input",{ref:j,type:"file",accept:"image/*",className:"hidden",onChange:Z}),g?o.jsxs("div",{className:"flex flex-col items-center gap-2",children:[o.jsx("span",{className:"loading loading-spinner loading-lg text-primary"}),o.jsx("p",{className:"font-medium",children:e==="de"?"Hintergrund wird entfernt...":"Removing background..."})]}):o.jsxs("div",{className:"flex flex-col items-center gap-2",children:[o.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:o.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"})}),o.jsx("p",{className:"font-medium",children:P.form.portrait.upload}),o.jsx("p",{className:"text-sm text-base-content/60",children:P.form.portrait.dragDrop})]})]}),o.jsx(Fe,{isOpen:H,onClose:()=>B(!1),onSubmit:be})]})}function At(){const e=b(a=>a.voucherConfig.language),t=b(a=>a.voucherConfig.templateHue),n=b(a=>a.setTemplateHue),r=F(e);return o.jsx("div",{className:"space-y-4",children:o.jsxs("div",{className:"form-control",children:[o.jsxs("label",{className:"label",children:[o.jsx("span",{className:"label-text font-medium",children:r.form.billColor.label}),o.jsxs("span",{className:"label-text-alt",children:[t,"°"]})]}),o.jsx("input",{type:"range",min:"0",max:"360",value:t,onChange:a=>n(Number(a.target.value)),className:"range range-primary",style:{background:`linear-gradient(to right,
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),pt=require("zustand"),gt=require("zustand/middleware"),p=require("react"),ft=require("jspdf");var ne=typeof document<"u"?document.currentScript:null;const He={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},b=pt.create()(gt.persist(e=>({...He,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(He)}),{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 F(e){return wt[e]}function Te(e,t,n){if(n&&n.trim())return n;const r=F(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=b(a=>a.voucherConfig.language),t=b(a=>a.personalInfo),n=b(a=>a.setPersonalInfo),r=F(e);return o.jsxs("div",{className:"space-y-4",children:[o.jsxs("div",{className:"form-control",children:[o.jsx("label",{className:"label",children:o.jsx("span",{className:"label-text font-medium",children:r.form.personalInfo.name})}),o.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})})]}),o.jsxs("div",{className:"form-control",children:[o.jsx("label",{className:"label",children:o.jsx("span",{className:"label-text font-medium",children:r.form.personalInfo.email})}),o.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})})]}),o.jsxs("div",{className:"form-control",children:[o.jsx("label",{className:"label",children:o.jsx("span",{className:"label-text font-medium",children:r.form.personalInfo.phone})}),o.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,De=null;function je(e,t){return W||(W=document.createElement("canvas"),De=W.getContext("2d",{willReadFrequently:!0})),(W.width!==e||W.height!==t)&&(W.width=e,W.height=t),De}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 i=ee.keys().next().value;i&&ee.delete(i)}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,i=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=i,d.height=s,c.drawImage(n,0,0,i,s),d.toDataURL("image/jpeg",.9)}async function ye(e,t,n,r=0){const[a,i]=await Promise.all([ie(e),ie(t)]),s=je(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(i,0,0,a.width,a.height),s.restore()}return s.drawImage(a,0,0),W.toDataURL("image/png")}async function Ye(e,t=.5){const n=await ie(e),r=je(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),i=a.data,s=new Uint32Array(i.buffer),d=1+t*.8,c=1-t;for(let u=0;u<s.length;u++){const h=s[u],m=h&255,w=h>>8&255,g=h>>16&255,v=h>>24&255;if(v===0)continue;let k=(((77*m+150*w+29*g>>8)/255-.5)*d+.5)*255;k<0?k=0:k>255&&(k=255);let P=k*.9+25,j=k*.78+15,I=k*.55+5;P>255&&(P=255),j>255&&(j=255),I>255&&(I=255);const C=m*c+P*t|0,R=w*c+j*t|0,H=g*c+I*t|0;s[u]=v<<24|H<<16|R<<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),i=(r+a)/2;let s=0,d=0;if(r!==a){const c=r-a;switch(d=i>.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,i]}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,i=2*n-a;return[Math.round(r(i,a,e+1/3)*255),Math.round(r(i,a,e)*255),Math.round(r(i,a,e-1/3)*255)]}async function _e(e,t){if(t>=155&&t<=165)return e;const n=await ie(e),r=je(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),i=a.data,s=new Uint32Array(i.buffer),d=t%360/360,c=60/360,u=260/360,h=1e5,m=s.length;for(let w=0;w<m;w+=h){const g=Math.min(w+h,m);for(let v=w;v<g;v++){const x=s[v],k=x&255,P=x>>8&255,j=x>>16&255,I=x>>24&255;if(I===0)continue;const[C,R,H]=Pt(k,P,j);if(R<.06||C<c||C>u)continue;const B=d,[N,Y,E]=Ct(B,R,H);s[v]=I<<24|E<<16|Y<<8|N}g<m&&await new Promise(v=>setTimeout(v,0))}return r.putImageData(a,0,0),W.toDataURL("image/png")}const Tt="https://api.stability.ai/v1/generation",jt="https://api.stability.ai/v2beta/stable-image/edit/remove-background",We="stability_api_key";let ae=null;function St(e){ae=e}function Rt(){return ae}function Et(){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 Nt(e,t){const n=e/t;let r=Me[0],a=1/0;for(const i of Me){const s=i.width/i.height,d=Math.abs(n-s);d<a&&(a=d,r=i)}return r}function Lt(e){return new Promise((t,n)=>{const r=new Image;r.onload=()=>{const a=Nt(r.width,r.height),i=document.createElement("canvas");i.width=a.width,i.height=a.height;const s=i.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,h=0,m=r.width,w=r.height;d>c?(m=r.height*c,u=(r.width-m)/2):(w=r.width/c,h=(r.height-w)/2),s.drawImage(r,u,h,m,w,0,0,a.width,a.height),t(i.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,i=new Uint8Array(a);for(let d=0;d<a;d++)i[d]=r.charCodeAt(d);return new Blob([i],{type:n})}function me(){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:me()!==null}async function Ht(e){const t=me();if(!t)throw new Error("No Stability AI API key configured");const{imageDataUrl:n,style:r,strength:a=.35}=e,i=await Lt(n),s=Xe(i),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(`${Tt}/stable-diffusion-xl-1024-v1-0/image-to-image`,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"},body:d});if(!u.ok){const m=await u.text();throw console.error("Stability AI error:",m),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 h=await u.json();if(!h.artifacts||h.artifacts.length===0)throw new Error("No image generated");return`data:image/png;base64,${h.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=me();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(jt,{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 i=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(i)})}function Dt(){const[e,t]=p.useState(!1),[n,r]=p.useState(!1),[a,i]=p.useState(null),[s,d]=p.useState(()=>Pe());p.useEffect(()=>{d(Pe())},[]);const c=p.useCallback(()=>i(null),[]),u=p.useCallback(w=>{$e(w),d(!0),i(null)},[]),h=p.useCallback(async(w,g=.5)=>{t(!0),i(null);try{return await Ye(w,g)}catch(v){const x=v instanceof Error?v.message:"Enhancement failed";throw i(x),v}finally{t(!1)}},[]),m=p.useCallback(async w=>{r(!0),i(null);try{return await Oe(w)}catch(g){const v=g instanceof Error?g.message:"Background removal failed";throw i(v),g}finally{r(!1)}},[]);return{enhance:h,removeBg:m,isEnhancing:e,isRemovingBg:n,error:a,hasKey:s,setApiKey:u,clearError:c}}function Fe({isOpen:e,onClose:t,onSubmit:n}){const r=b(u=>u.voucherConfig.language),[a,i]=p.useState("");if(!e)return null;const s=u=>{u.preventDefault(),a.trim()&&(n(a.trim()),i(""),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 o.jsxs("dialog",{className:"modal modal-open",children:[o.jsxs("div",{className:"modal-box",children:[o.jsx("h3",{className:"font-bold text-lg",children:c.title}),o.jsx("p",{className:"py-4 text-sm opacity-80",children:c.description}),o.jsxs("form",{onSubmit:s,children:[o.jsxs("div",{className:"form-control",children:[o.jsx("input",{type:"password",placeholder:c.placeholder,className:"input input-bordered w-full",value:a,onChange:u=>i(u.target.value),autoFocus:!0}),o.jsx("label",{className:"label",children:o.jsx("span",{className:"label-text-alt",children:c.hint})})]}),o.jsxs("div",{className:"modal-action",children:[o.jsx("button",{type:"button",className:"btn btn-ghost",onClick:t,children:c.cancel}),o.jsx("button",{type:"submit",className:"btn btn-primary",disabled:!a.trim(),children:c.submit})]})]})]}),o.jsx("form",{method:"dialog",className:"modal-backdrop",children:o.jsx("button",{onClick:t,children:"close"})})]})}function Mt(){const e=b(l=>l.voucherConfig.language),t=b(l=>l.portrait),n=b(l=>l.setPortrait),r=b(l=>l.setPortraitZoom),a=b(l=>l.setPortraitPan),i=b(l=>l.setPortraitRawImage),s=b(l=>l.setPortraitBgRemoved),d=b(l=>l.setPortraitBgOpacity),c=b(l=>l.setPortraitBgBlur),u=b(l=>l.setPortraitEngravingIntensity),{enhance:h,removeBg:m,isEnhancing:w,isRemovingBg:g,error:v,hasKey:x,setApiKey:k}=Dt(),P=F(e),j=p.useRef(null),I=p.useRef(null),[C,R]=p.useState(!1),[H,B]=p.useState(!1),[N,Y]=p.useState(!1),E=p.useRef(null),D=p.useRef(null),M=p.useRef(null),S=t.rawImage,_=t.bgRemovedImage,A=t.bgRemoved,X=t.bgOpacity,V=t.bgBlur,se=t.engravingIntensity;p.useEffect(()=>{t.original&&!t.rawImage&&i(t.original)},[t.original,t.rawImage,i]),p.useEffect(()=>()=>{D.current&&clearTimeout(D.current),M.current&&clearTimeout(M.current)},[]);const re=p.useCallback(async l=>{if(!l.type.startsWith("image/"))return;const y=new FileReader;y.onload=async T=>{var ue;const U=(ue=T.target)==null?void 0:ue.result,de=await kt(U);i(de),n(de),s(!1,null),u(0)},y.readAsDataURL(l)},[n,i,s,u]),ge=p.useCallback(l=>{l.preventDefault(),R(!1);const y=l.dataTransfer.files[0];y&&re(y)},[re]),f=p.useCallback(l=>{l.preventDefault(),R(!0)},[]),L=p.useCallback(l=>{l.preventDefault(),R(!1)},[]),$=()=>{var l;(l=j.current)==null||l.click()},Z=l=>{var T;const y=(T=l.target.files)==null?void 0:T[0];y&&re(y)},O=p.useCallback(async(l,y)=>{try{return await h(l,y)}catch(T){return console.error("Enhancement failed:",T),l}},[h]),J=p.useCallback(async l=>{try{const y=await m(l);return s(!0,y),y}catch(y){return console.error("Background removal failed:",y),l}},[m,s]),q=p.useCallback(async()=>{const l=b.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(!S)return;if(!A&&!x){B(!0);return}if(!A){const y=await J(S),T=b.getState().portrait;let U=await ye(y,S,T.bgOpacity,T.bgBlur);T.engravingIntensity>0&&(U=await O(U,T.engravingIntensity)),n(U)}else{s(!1,null);const y=b.getState().portrait.engravingIntensity;if(y>0){const T=await O(S,y);n(T)}else n(S)}},fe=l=>{u(l),D.current&&clearTimeout(D.current),S&&(D.current=setTimeout(q,150))},be=async l=>{if(k(l),!S)return;const y=await J(S),T=b.getState().portrait;let U=await ye(y,S,T.bgOpacity,T.bgBlur);T.engravingIntensity>0&&(U=await O(U,T.engravingIntensity)),n(U)},xe=l=>{d(l),M.current&&clearTimeout(M.current),!(!S||!_)&&(M.current=setTimeout(q,150))},le=l=>{c(l),M.current&&clearTimeout(M.current),!(!S||!_)&&(M.current=setTimeout(q,150))},ce=()=>{n(null),i(null),s(!1,null),d(0),c(0),u(0),It()},Ne=(l,y)=>{t.zoom<=1||(Y(!0),E.current={x:l,y,panX:t.panX,panY:t.panY})},Le=(l,y)=>{if(!N||!E.current||!I.current)return;const T=I.current.getBoundingClientRect(),U=2/Math.max(T.width,T.height),de=(l-E.current.x)*U,ue=(y-E.current.y)*U,ht=Math.max(-1,Math.min(1,E.current.panX+de)),mt=Math.max(-1,Math.min(1,E.current.panY+ue));a(ht,mt)},we=()=>{Y(!1),E.current=null},ot=l=>{l.preventDefault(),Ne(l.clientX,l.clientY)},it=l=>{Le(l.clientX,l.clientY)},st=()=>{we()},lt=()=>{we()},ct=l=>{l.touches.length===1&&Ne(l.touches[0].clientX,l.touches[0].clientY)},dt=l=>{l.touches.length===1&&Le(l.touches[0].clientX,l.touches[0].clientY)},ut=()=>{we()};return o.jsxs("div",{className:"space-y-4",children:[t.original?o.jsxs("div",{className:"flex flex-col items-center space-y-4",children:[o.jsxs("div",{className:"relative",children:[o.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":""} ${N?"cursor-grabbing":""}`,onMouseDown:ot,onMouseMove:it,onMouseUp:st,onMouseLeave:lt,onTouchStart:ct,onTouchMove:dt,onTouchEnd:ut,children:o.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})}),o.jsx("button",{className:"btn btn-circle btn-xs btn-error absolute -top-1 -right-1",onClick:ce,children:o.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:o.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),o.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[o.jsxs("div",{className:"form-control w-full",children:[o.jsxs("label",{className:"label",children:[o.jsx("span",{className:"label-text",children:P.form.portrait.zoom}),o.jsxs("span",{className:"label-text-alt",children:[Math.round(t.zoom*100),"%"]})]}),o.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"})]}),o.jsxs("div",{className:"form-control w-full",children:[o.jsxs("label",{className:"label",children:[o.jsxs("span",{className:"label-text flex items-center gap-2",children:[e==="de"?"Sepia-Effekt":"Sepia effect",w&&o.jsx("span",{className:"loading loading-spinner loading-xs"})]}),o.jsxs("span",{className:"label-text-alt",children:[Math.round(se*100),"%"]})]}),o.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||!S})]})]}),A?o.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4 w-full",children:[o.jsxs("div",{className:"form-control w-full",children:[o.jsxs("label",{className:"label",children:[o.jsx("span",{className:"label-text",children:e==="de"?"Hintergrund":"Background"}),o.jsxs("span",{className:"label-text-alt",children:[Math.round(X*100),"%"]})]}),o.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"})]}),o.jsxs("div",{className:"form-control w-full",children:[o.jsxs("label",{className:"label",children:[o.jsx("span",{className:"label-text",children:e==="de"?"Unschärfe":"Blur"}),o.jsxs("span",{className:"label-text-alt",children:[Math.round(V*100),"%"]})]}),o.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"})]})]}):o.jsx("div",{className:"form-control",children:o.jsxs("label",{className:"label cursor-pointer justify-start gap-3",children:[o.jsx("input",{type:"checkbox",className:`toggle toggle-primary ${g?"opacity-50":""}`,checked:A,onChange:oe,disabled:g||!S}),o.jsxs("span",{className:"label-text flex items-center gap-2",children:[g?o.jsxs(o.Fragment,{children:[o.jsx("span",{className:"loading loading-spinner loading-xs"}),e==="de"?"Hintergrund wird entfernt...":"Removing background..."]}):e==="de"?"Hintergrund entfernen":"Remove background",!x&&o.jsx("span",{className:"badge badge-sm badge-outline",children:"API"})]})]})}),v&&o.jsxs("div",{className:"alert alert-warning text-sm py-2",children:[o.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:o.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"})}),o.jsx("span",{children:v})]})]}):o.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:L,onClick:$,children:[o.jsx("input",{ref:j,type:"file",accept:"image/*",className:"hidden",onChange:Z}),g?o.jsxs("div",{className:"flex flex-col items-center gap-2",children:[o.jsx("span",{className:"loading loading-spinner loading-lg text-primary"}),o.jsx("p",{className:"font-medium",children:e==="de"?"Hintergrund wird entfernt...":"Removing background..."})]}):o.jsxs("div",{className:"flex flex-col items-center gap-2",children:[o.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:o.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"})}),o.jsx("p",{className:"font-medium",children:P.form.portrait.upload}),o.jsx("p",{className:"text-sm text-base-content/60",children:P.form.portrait.dragDrop})]})]}),o.jsx(Fe,{isOpen:H,onClose:()=>B(!1),onSubmit:be})]})}function At(){const e=b(a=>a.voucherConfig.language),t=b(a=>a.voucherConfig.templateHue),n=b(a=>a.setTemplateHue),r=F(e);return o.jsx("div",{className:"space-y-4",children:o.jsxs("div",{className:"form-control",children:[o.jsxs("label",{className:"label",children:[o.jsx("span",{className:"label-text font-medium",children:r.form.billColor.label}),o.jsxs("span",{className:"label-text-alt",children:[t,"°"]})]}),o.jsx("input",{type:"range",min:"0",max:"360",value:t,onChange:a=>n(Number(a.target.value)),className:"w-full h-3 rounded-lg appearance-none cursor-pointer [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-5 [&::-webkit-slider-thumb]:h-5 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-white [&::-webkit-slider-thumb]:shadow-md [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-gray-300 [&::-moz-range-thumb]:w-5 [&::-moz-range-thumb]:h-5 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-white [&::-moz-range-thumb]:shadow-md [&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-gray-300",style:{background:`linear-gradient(to right,
|
|
2
2
|
hsl(0, 70%, 50%),
|
|
3
3
|
hsl(60, 70%, 50%),
|
|
4
4
|
hsl(120, 70%, 50%),
|
|
5
5
|
hsl(180, 70%, 50%),
|
|
6
6
|
hsl(240, 70%, 50%),
|
|
7
7
|
hsl(300, 70%, 50%),
|
|
8
|
-
hsl(360, 70%, 50%))`}}),o.jsxs("div",{className:"flex justify-between text-xs px-1 mt-1 opacity-60",children:[o.jsx("span",{children:"0°"}),o.jsx("span",{children:"90°"}),o.jsx("span",{children:"180°"}),o.jsx("span",{children:"270°"}),o.jsx("span",{children:"360°"})]})]})})}const
|
|
8
|
+
hsl(360, 70%, 50%))`}}),o.jsxs("div",{className:"flex justify-between text-xs px-1 mt-1 opacity-60",children:[o.jsx("span",{children:"0°"}),o.jsx("span",{children:"90°"}),o.jsx("span",{children:"180°"}),o.jsx("span",{children:"270°"}),o.jsx("span",{children:"360°"})]})]})})}const z=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"&&"/"||"/",Se={en:{1:{front:`${z}templates/front_ldpi_en.png`,back:`${z}templates/back_ldpi_en.png`,width:1536,height:1024},5:{front:`${z}templates/front_ldpi_en.png`,back:`${z}templates/back_ldpi_en.png`,width:1536,height:1024},10:{front:`${z}templates/front_ldpi_en.png`,back:`${z}templates/back_ldpi_en.png`,width:1536,height:1024}},de:{1:{front:`${z}templates/front_hdpi_de.webp`,back:`${z}templates/back_hdpi_de.webp`,width:6144,height:3200},5:{front:`${z}templates/front_hdpi_de.webp`,back:`${z}templates/back_hdpi_de.webp`,width:6144,height:3200},10:{front:`${z}templates/front_hdpi_de.webp`,back:`${z}templates/back_hdpi_de.webp`,width:6144,height:3200}}},K={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"}}},G={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 Re(e){return e==="de"?G:K}function qe(e,t){return Se[e][t]}const Ce=.25;function Ut(e){const t=Re(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 zt(e,t){const n=Se[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 Ee(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 i=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(i,0,0,n,r);const c=s.toDataURL("image/png"),u=await _e(c,t);if(Q.size>20){const h=Q.keys().next().value;h&&Q.delete(h)}return Q.set(a,u),te(u)}function Ge(e,t,n,r,a,i,s=1,d=0,c=0){e.save(),e.beginPath(),e.ellipse(n,r,a,i,0,0,Math.PI*2),e.closePath(),e.clip();const u=t.width/t.height,h=a/i,m=a*2,w=i*2;let g,v;u>h?(v=w,g=w*u):(g=m,v=m/u),g*=s,v*=s;const x=Math.max(0,(g-m)/2),k=Math.max(0,(v-w)/2),P=n-g/2+d*x,j=r-v/2+c*k;e.drawImage(t,P,j,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,i=n.lineHeight||n.fontSize*1.4,s=t.split(" "),d=[];let c="";for(const m of s){const w=c?`${c} ${m}`:m;e.measureText(w).width>a&&c?(d.push(c),c=m):c=w}c&&d.push(c);const u=d.length*i;let h=n.y-u/2;for(const m of d)e.fillText(m,n.x,h),h+=i;e.restore()}function Ze(e,t,n,r,a,i="#2a3a2a"){e.save(),e.font=`${a.fontSize}px "Times New Roman", serif`,e.textAlign=a.align||"center",e.textBaseline="middle",e.fillStyle=i;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 h of d)h&&(e.fillText(h,a.x,u),u+=s);e.restore()}async function Je(e,t,n,r,a,i,s,d=1,c=0,u=0,h=0){const m=e.getContext("2d");if(!m)return;e.width=i,e.height=s,m.clearRect(0,0,i,s);const w=await Ke(t,h,i,s);if(Ee(m,w,i,s),n)try{const g=await te(n);Ge(m,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(m,r,a.namePlate)}async function Qe(e,t,n,r,a,i,s,d,c,u=0){const h=e.getContext("2d");if(!h)return;e.width=d,e.height=c,h.clearRect(0,0,d,c);const m=await Ke(t,u,d,c);Ee(h,m,d,c),s.contactInfo&&(n||r||a)&&Ze(h,n,r,a,s.contactInfo),s.description&&i&&Ve(h,i,s.description),n&&Be(h,n,s.namePlate)}function Yt(e,t){const[n,r]=p.useState(e);return p.useEffect(()=>{const a=setTimeout(()=>r(e),t);return()=>clearTimeout(a)},[e,t]),n}function _t(){const e=b(f=>f.voucherConfig.language),t=b(f=>f.voucherConfig.hours),n=b(f=>f.voucherConfig.description),r=b(f=>f.voucherConfig.templateHue),a=b(f=>f.personalInfo),i=b(f=>f.portrait),s=b(f=>f.currentSide),d=b(f=>f.flipSide),c=b(f=>f.setPortraitPan),u=Yt(r,150),h=F(e),m=p.useRef(null),w=p.useRef(null),g=p.useRef(null),[v,x]=p.useState(!1),[k,P]=p.useState(!1),j=p.useRef(null),I=zt(e,t),C=Ut(e),R=i.useEnhanced&&i.enhanced?i.enhanced:i.original,H=Te(e,t,n);p.useEffect(()=>{m.current&&Je(m.current,I.front,R,a.name,C.front,I.width,I.height,i.zoom,i.panX,i.panY,u)},[I,R,a.name,C,i.zoom,i.panX,i.panY,u]),p.useEffect(()=>{w.current&&Qe(w.current,I.back,a.name,a.email,a.phone,H,C.back,I.width,I.height,u)},[I,a,H,C,u]);const B=()=>{x(!0),setTimeout(()=>{d(),x(!1)},150)},N=p.useCallback((f,L)=>{if(!g.current||s!=="front"||!i.original)return!1;const $=g.current.getBoundingClientRect(),Z=$.width/I.width,O=$.height/I.height,J=(f-$.left)/Z,q=(L-$.top)/O,{x:oe,y:fe,radiusX:be,radiusY:xe}=C.front.portrait,le=(J-oe)/be,ce=(q-fe)/xe;return le*le+ce*ce<=1},[s,i.original,I.width,I.height,C.front.portrait]),Y=p.useCallback((f,L)=>{i.zoom<=1||!N(f,L)||(P(!0),j.current={x:f,y:L,panX:i.panX,panY:i.panY})},[i.zoom,i.panX,i.panY,N]),E=p.useCallback((f,L)=>{if(!k||!j.current||!g.current)return;const $=g.current.getBoundingClientRect(),Z=3/Math.max($.width,$.height),O=(f-j.current.x)*Z,J=(L-j.current.y)*Z,q=Math.max(-1,Math.min(1,j.current.panX+O)),oe=Math.max(-1,Math.min(1,j.current.panY+J));c(q,oe)},[k,c]),D=p.useCallback(()=>{P(!1),j.current=null},[]),M=f=>{i.zoom>1&&N(f.clientX,f.clientY)&&(f.preventDefault(),Y(f.clientX,f.clientY))},S=f=>{E(f.clientX,f.clientY)},_=()=>D(),A=()=>D(),X=f=>{if(f.touches.length===1){const L=f.touches[0];i.zoom>1&&N(L.clientX,L.clientY)&&Y(L.clientX,L.clientY)}},V=f=>{f.touches.length===1&&E(f.touches[0].clientX,f.touches[0].clientY)},se=()=>D(),re=s==="front"&&i.original&&i.zoom>1,ge=I.width/I.height;return o.jsxs("div",{className:"space-y-4",children:[o.jsxs("div",{className:"flex justify-between items-center",children:[o.jsxs("div",{className:"tabs tabs-boxed bg-base-200",children:[o.jsx("button",{className:`tab ${s==="front"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>s!=="front"&&B(),children:h.preview.front}),o.jsx("button",{className:`tab ${s==="back"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>s!=="back"&&B(),children:h.preview.back})]}),o.jsxs("button",{className:"btn btn-ghost btn-sm",onClick:B,children:[o.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:o.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"})}),h.preview.flip]})]}),o.jsxs("div",{ref:g,className:`relative w-full overflow-hidden shadow-lg ${re?k?"cursor-grabbing":"cursor-grab":""}`,style:{aspectRatio:ge},onMouseDown:M,onMouseMove:S,onMouseUp:_,onMouseLeave:A,onTouchStart:X,onTouchMove:V,onTouchEnd:se,children:[o.jsx("canvas",{ref:m,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"}`}),o.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=p.useRef(null),t=p.useRef(null);return{frontCanvasRef:e,backCanvasRef:t}}const Xt=`
|
|
9
9
|
// RGB to HSL conversion
|
|
10
10
|
function rgbToHsl(r, g, b) {
|
|
11
11
|
r /= 255;
|
|
@@ -358,4 +358,4 @@ self.onmessage = async (e) => {
|
|
|
358
358
|
});
|
|
359
359
|
}
|
|
360
360
|
};
|
|
361
|
-
`;let Ie=null,Ae=null;function $t(){if(!Ie){const e=new Blob([Xt],{type:"application/javascript"});Ae=URL.createObjectURL(e),Ie=new Worker(Ae,{type:"module"})}return Ie}async function ke(e){const n=await(await fetch(e)).blob();return URL.createObjectURL(n)}function Ue(e,t){const n=new Uint8Array(e);let r="";for(let a=0;a<n.length;a++)r+=String.fromCharCode(n[a]);return`data:${t};base64,${btoa(r)}`}async function et(e){const{frontTemplateSrc:t,backTemplateSrc:n,templateWidth:r,templateHeight:a,layout:i,portrait:s,portraitZoom:d=1,portraitPanX:c=0,portraitPanY:u=0,templateHue:
|
|
361
|
+
`;let Ie=null,Ae=null;function $t(){if(!Ie){const e=new Blob([Xt],{type:"application/javascript"});Ae=URL.createObjectURL(e),Ie=new Worker(Ae,{type:"module"})}return Ie}async function ke(e){const n=await(await fetch(e)).blob();return URL.createObjectURL(n)}function Ue(e,t){const n=new Uint8Array(e);let r="";for(let a=0;a<n.length;a++)r+=String.fromCharCode(n[a]);return`data:${t};base64,${btoa(r)}`}async function et(e){const{frontTemplateSrc:t,backTemplateSrc:n,templateWidth:r,templateHeight:a,layout:i,portrait:s,portraitZoom:d=1,portraitPanX:c=0,portraitPanY:u=0,templateHue:h=160,name:m,email:w,phone:g,description:v}=e,[x,k]=await Promise.all([ke(t),ke(n)]);let P=null;return s&&(P=await ke(s)),new Promise((j,I)=>{const C=$t(),R=B=>{if(C.removeEventListener("message",R),C.removeEventListener("error",H),URL.revokeObjectURL(x),URL.revokeObjectURL(k),P&&URL.revokeObjectURL(P),B.data.type==="success")try{const{frontImageData:N,backImageData:Y,width:E,height:D}=B.data;if(!N||!Y||!E||!D){I(new Error("Invalid response from worker"));return}const M=Ue(N,"image/jpeg"),S=Ue(Y,"image/jpeg"),_=E/96*25.4,A=D/96*25.4,X=new ft.jsPDF({orientation:_>A?"landscape":"portrait",unit:"mm",format:[_,A]});X.addImage(M,"JPEG",0,0,_,A),X.addPage([_,A]),X.addImage(S,"JPEG",0,0,_,A);const V=X.output("blob");j(V)}catch(N){I(N)}else I(new Error(B.data.error))},H=B=>{C.removeEventListener("message",R),C.removeEventListener("error",H),URL.revokeObjectURL(x),URL.revokeObjectURL(k),P&&URL.revokeObjectURL(P),I(new Error(B.message))};C.addEventListener("message",R),C.addEventListener("error",H),C.postMessage({type:"generate",frontTemplateUrl:x,backTemplateUrl:k,portraitUrl:P,templateWidth:r,templateHeight:a,templateHue:h,portraitZoom:d,portraitPanX:c,portraitPanY:u,layout:{front:{portrait:i.front.portrait,namePlate:i.front.namePlate},back:{namePlate:i.back.namePlate,contactInfo:i.back.contactInfo,description:i.back.description}},name:m,email:w,phone:g,description:v})})}function tt(e,t){const n=URL.createObjectURL(e),r=document.createElement("a");r.href=n,r.download=t,document.body.appendChild(r),r.click(),document.body.removeChild(r),URL.revokeObjectURL(n)}async function nt(e){const t=await et(e);tt(t,e.filename)}function Ot(){const e=b(x=>x.voucherConfig.language),t=b(x=>x.voucherConfig.hours),n=b(x=>x.voucherConfig.description),r=b(x=>x.voucherConfig.templateHue),a=b(x=>x.personalInfo),i=b(x=>x.portrait),s=b(x=>x.isExporting),d=b(x=>x.setIsExporting),c=F(e),u=qe(e,t),h=Re(e),m=i.useEnhanced&&i.enhanced?i.enhanced:i.original,w=Te(e,t,n),g=a.name.trim().length>0&&a.email.trim().length>0&&a.phone.trim().length>0&&i.original!==null,v=async()=>{if(!(!g||s)){d(!0);try{const x=`zeitgutschein-${t}h-${a.name.replace(/\s+/g,"-").toLowerCase()}.pdf`;await nt({frontTemplateSrc:u.front,backTemplateSrc:u.back,templateWidth:u.width,templateHeight:u.height,layout:h,portrait:m,portraitZoom:i.zoom,portraitPanX:i.panX,portraitPanY:i.panY,templateHue:r,name:a.name,email:a.email,phone:a.phone,description:w,filename:x})}catch(x){console.error("PDF export failed:",x)}finally{d(!1)}}};return o.jsxs("button",{className:`btn btn-primary flex-1 ${g?"":"btn-disabled"}`,onClick:v,disabled:!g,"aria-busy":s,children:[s?o.jsx("span",{className:"loading loading-spinner loading-sm"}):o.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:o.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"})}),c.export.button]})}function at(){const e=b(r=>r.voucherConfig.language),t=b(r=>r.setLanguage),n=r=>{t(r)};return o.jsxs("div",{className:"join",children:[o.jsx("button",{className:`join-item btn btn-sm ${e==="de"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>n("de"),children:"DE"}),o.jsx("button",{className:`join-item btn btn-sm ${e==="en"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>n("en"),children:"EN"})]})}function Ft(){const e=b(n=>n.voucherConfig.language),t=F(e);return o.jsxs("div",{className:"navbar bg-currency-green text-currency-cream shadow-lg",children:[o.jsx("div",{className:"navbar-start",children:o.jsx("a",{className:"btn btn-ghost text-xl font-currency font-bold",children:t.header.title})}),o.jsx("div",{className:"navbar-center hidden sm:flex",children:o.jsx("span",{className:"text-sm opacity-80",children:t.header.subtitle})}),o.jsx("div",{className:"navbar-end",children:o.jsx(at,{})})]})}const he="/",qt={id:"time-voucher-classic-de",name:"Zeitgutschein Classic",type:"time-voucher",category:"classic",images:{front:`${he}templates/front_hdpi_de.jpg`,back:`${he}templates/back_hdpi_de.jpg`,width:6144,height:4096},fields:[{id:"name",type:"text",label:{de:"Name",en:"Name"},required:!0,validation:{minLength:1,maxLength:50}},{id:"hours",type:"select",label:{de:"Stunden",en:"Hours"},required:!0,options:["1","5","10"]},{id:"portrait",type:"image",label:{de:"Portrait",en:"Portrait"},required:!1},{id:"email",type:"text",label:{de:"E-Mail",en:"Email"},required:!1},{id:"phone",type:"text",label:{de:"Telefon",en:"Phone"},required:!1},{id:"description",type:"textarea",label:{de:"Beschreibung",en:"Description"},required:!1,validation:{maxLength:200}}],layout:{front:{portrait:G.front.portrait,name:G.front.namePlate},back:{name:G.back.namePlate,contactInfo:G.back.contactInfo,description:G.back.description}},languages:["de"]},Kt={id:"time-voucher-classic-en",name:"Time Voucher Classic",type:"time-voucher",category:"classic",images:{front:`${he}templates/front_ldpi_en.png`,back:`${he}templates/back_ldpi_en.png`,width:1536,height:1024},fields:[{id:"name",type:"text",label:{de:"Name",en:"Name"},required:!0,validation:{minLength:1,maxLength:50}},{id:"hours",type:"select",label:{de:"Stunden",en:"Hours"},required:!0,options:["1","5","10"]},{id:"portrait",type:"image",label:{de:"Portrait",en:"Portrait"},required:!1},{id:"email",type:"text",label:{de:"E-Mail",en:"Email"},required:!1},{id:"phone",type:"text",label:{de:"Telefon",en:"Phone"},required:!1},{id:"description",type:"textarea",label:{de:"Beschreibung",en:"Description"},required:!1,validation:{maxLength:200}}],layout:{front:{portrait:K.front.portrait,name:K.front.namePlate},back:{name:K.back.namePlate,contactInfo:K.back.contactInfo,description:K.back.description}},languages:["en"]},ze=[qt,Kt],rt={async listTemplates(e){let t=[...ze];return e!=null&&e.type&&(t=t.filter(n=>n.type===e.type)),e!=null&&e.category&&(t=t.filter(n=>n.category===e.category)),e!=null&&e.language&&(t=t.filter(n=>n.languages.includes(e.language))),t},async getTemplate(e){const t=ze.find(n=>n.id===e);if(!t)throw new Error(`Template not found: ${e}`);return t}};function Gt(e){return e==="de"?"time-voucher-classic-de":"time-voucher-classic-en"}let pe=rt;function Vt(e){pe=e}function Zt(){return pe}async function Jt(e){return pe.listTemplates(e)}async function Qt(e){return pe.getTemplate(e)}exports.ApiKeyModal=Fe;exports.BillPreview=_t;exports.ExportButton=Ot;exports.Header=Ft;exports.LAYOUT_HDPI=G;exports.LAYOUT_LDPI=K;exports.LanguageToggle=at;exports.PersonalInfoForm=yt;exports.PortraitUpload=Mt;exports.TEMPLATES=Se;exports.VoucherConfig=At;exports.applyEngravingEffect=Ye;exports.applyHueShift=_e;exports.downloadBlob=tt;exports.drawContactInfo=Ze;exports.drawMultilineText=Ve;exports.drawOvalPortrait=Ge;exports.drawTemplate=Ee;exports.drawText=Be;exports.enhancePortrait=Ht;exports.exportBillAsPDF=nt;exports.formatDescription=Te;exports.generateBillPDF=et;exports.getApiKey=me;exports.getDefaultTemplateId=Gt;exports.getLayout=Re;exports.getRemoveBackgroundEndpoint=Rt;exports.getTemplate=qe;exports.getTemplateById=Qt;exports.getTemplateProvider=Zt;exports.hasApiKey=Pe;exports.hasCustomEndpoint=Et;exports.listTemplates=Jt;exports.loadImage=te;exports.removeBackground=Oe;exports.renderBackSide=Qe;exports.renderFrontSide=Je;exports.setApiKey=$e;exports.setRemoveBackgroundEndpoint=St;exports.setTemplateProvider=Vt;exports.staticTemplateProvider=rt;exports.t=F;exports.useBillCanvasRefs=Wt;exports.useBillStore=b;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsxs as
|
|
1
|
+
import { jsxs as m, jsx as d, Fragment as tt } from "react/jsx-runtime";
|
|
2
2
|
import { create as nt } from "zustand";
|
|
3
3
|
import { persist as at } from "zustand/middleware";
|
|
4
4
|
import { useState as X, useEffect as re, useCallback as B, useRef as W } from "react";
|
|
@@ -265,7 +265,7 @@ const Be = {
|
|
|
265
265
|
function V(e) {
|
|
266
266
|
return st[e];
|
|
267
267
|
}
|
|
268
|
-
function
|
|
268
|
+
function Ue(e, t, n) {
|
|
269
269
|
if (n && n.trim())
|
|
270
270
|
return n;
|
|
271
271
|
const r = V(e), a = t === 1 ? r.form.voucher.hourLabel : r.form.voucher.hoursLabel;
|
|
@@ -273,8 +273,8 @@ function Ye(e, t, n) {
|
|
|
273
273
|
}
|
|
274
274
|
function Kt() {
|
|
275
275
|
const e = b((a) => a.voucherConfig.language), t = b((a) => a.personalInfo), n = b((a) => a.setPersonalInfo), r = V(e);
|
|
276
|
-
return /* @__PURE__ */
|
|
277
|
-
/* @__PURE__ */
|
|
276
|
+
return /* @__PURE__ */ m("div", { className: "space-y-4", children: [
|
|
277
|
+
/* @__PURE__ */ m("div", { className: "form-control", children: [
|
|
278
278
|
/* @__PURE__ */ d("label", { className: "label", children: /* @__PURE__ */ d("span", { className: "label-text font-medium", children: r.form.personalInfo.name }) }),
|
|
279
279
|
/* @__PURE__ */ d(
|
|
280
280
|
"input",
|
|
@@ -287,7 +287,7 @@ function Kt() {
|
|
|
287
287
|
}
|
|
288
288
|
)
|
|
289
289
|
] }),
|
|
290
|
-
/* @__PURE__ */
|
|
290
|
+
/* @__PURE__ */ m("div", { className: "form-control", children: [
|
|
291
291
|
/* @__PURE__ */ d("label", { className: "label", children: /* @__PURE__ */ d("span", { className: "label-text font-medium", children: r.form.personalInfo.email }) }),
|
|
292
292
|
/* @__PURE__ */ d(
|
|
293
293
|
"input",
|
|
@@ -300,7 +300,7 @@ function Kt() {
|
|
|
300
300
|
}
|
|
301
301
|
)
|
|
302
302
|
] }),
|
|
303
|
-
/* @__PURE__ */
|
|
303
|
+
/* @__PURE__ */ m("div", { className: "form-control", children: [
|
|
304
304
|
/* @__PURE__ */ d("label", { className: "label", children: /* @__PURE__ */ d("span", { className: "label-text font-medium", children: r.form.personalInfo.phone }) }),
|
|
305
305
|
/* @__PURE__ */ d(
|
|
306
306
|
"input",
|
|
@@ -360,13 +360,13 @@ async function ut(e, t = 0.5) {
|
|
|
360
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 h = i[u],
|
|
363
|
+
const h = i[u], p = h & 255, y = h >> 8 & 255, g = h >> 16 & 255, x = h >> 24 & 255;
|
|
364
364
|
if (x === 0) continue;
|
|
365
|
-
let k = (((77 *
|
|
365
|
+
let k = (((77 * p + 150 * y + 29 * g >> 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, S = k * 0.78 + 15, I = k * 0.55 + 5;
|
|
368
368
|
P > 255 && (P = 255), S > 255 && (S = 255), I > 255 && (I = 255);
|
|
369
|
-
const C =
|
|
369
|
+
const C = p * l + P * t | 0, N = y * l + S * t | 0, M = g * l + I * t | 0;
|
|
370
370
|
i[u] = x << 24 | M << 16 | N << 8 | C;
|
|
371
371
|
}
|
|
372
372
|
return r.putImageData(a, 0, 0), j.toDataURL("image/png");
|
|
@@ -391,7 +391,7 @@ function ht(e, t, n) {
|
|
|
391
391
|
}
|
|
392
392
|
return [i, c, o];
|
|
393
393
|
}
|
|
394
|
-
function
|
|
394
|
+
function mt(e, t, n) {
|
|
395
395
|
if (t === 0) {
|
|
396
396
|
const i = Math.round(n * 255);
|
|
397
397
|
return [i, i, i];
|
|
@@ -403,27 +403,27 @@ function pt(e, t, n) {
|
|
|
403
403
|
Math.round(r(o, a, e - 1 / 3) * 255)
|
|
404
404
|
];
|
|
405
405
|
}
|
|
406
|
-
async function
|
|
406
|
+
async function pt(e, t) {
|
|
407
407
|
if (t >= 155 && t <= 165)
|
|
408
408
|
return e;
|
|
409
409
|
const n = await ce(e), r = Se(n.width, n.height);
|
|
410
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,
|
|
412
|
-
for (let y = 0; y <
|
|
413
|
-
const g = Math.min(y + h,
|
|
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 g = Math.min(y + h, p);
|
|
414
414
|
for (let x = y; x < g; x++) {
|
|
415
415
|
const w = i[x], k = w & 255, P = w >> 8 & 255, S = w >> 16 & 255, I = w >> 24 & 255;
|
|
416
416
|
if (I === 0) continue;
|
|
417
417
|
const [C, N, M] = ht(k, P, S);
|
|
418
418
|
if (N < 0.06 || C < l || C > u) continue;
|
|
419
|
-
const L = c, [H, $, R] =
|
|
419
|
+
const L = c, [H, $, R] = mt(L, N, M);
|
|
420
420
|
i[x] = I << 24 | R << 16 | $ << 8 | H;
|
|
421
421
|
}
|
|
422
|
-
g <
|
|
422
|
+
g < p && await new Promise((x) => setTimeout(x, 0));
|
|
423
423
|
}
|
|
424
424
|
return r.putImageData(a, 0, 0), j.toDataURL("image/png");
|
|
425
425
|
}
|
|
426
|
-
const gt = "https://api.stability.ai/v1/generation", ft = "https://api.stability.ai/v2beta/stable-image/edit/remove-background",
|
|
426
|
+
const gt = "https://api.stability.ai/v1/generation", ft = "https://api.stability.ai/v2beta/stable-image/edit/remove-background", Ye = "stability_api_key";
|
|
427
427
|
let oe = null;
|
|
428
428
|
function qt(e) {
|
|
429
429
|
oe = e;
|
|
@@ -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, h = 0,
|
|
474
|
-
c > l ? (
|
|
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
|
}
|
|
@@ -485,10 +485,10 @@ function _e(e) {
|
|
|
485
485
|
function Ee() {
|
|
486
486
|
var t;
|
|
487
487
|
const e = typeof import.meta < "u" && "sk-7mEKklrqaltdtgbX0VoZbkA8E1cl939Spn75jSIYRvp1BW0b" || typeof process < "u" && ((t = process.env) == null ? void 0 : t.NEXT_PUBLIC_STABILITY_API_KEY);
|
|
488
|
-
return e && e !== "your-api-key-here" ? e : typeof localStorage < "u" ? localStorage.getItem(
|
|
488
|
+
return e && e !== "your-api-key-here" ? e : typeof localStorage < "u" ? localStorage.getItem(Ye) : null;
|
|
489
489
|
}
|
|
490
490
|
function vt(e) {
|
|
491
|
-
localStorage.setItem(
|
|
491
|
+
localStorage.setItem(Ye, e);
|
|
492
492
|
}
|
|
493
493
|
function De() {
|
|
494
494
|
return oe ? !0 : Ee() !== null;
|
|
@@ -508,8 +508,8 @@ async function Zt(e) {
|
|
|
508
508
|
body: c
|
|
509
509
|
});
|
|
510
510
|
if (!u.ok) {
|
|
511
|
-
const
|
|
512
|
-
throw console.error("Stability AI error:",
|
|
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
514
|
const h = await u.json();
|
|
515
515
|
if (!h.artifacts || h.artifacts.length === 0)
|
|
@@ -574,7 +574,7 @@ function It() {
|
|
|
574
574
|
}
|
|
575
575
|
},
|
|
576
576
|
[]
|
|
577
|
-
),
|
|
577
|
+
), p = B(
|
|
578
578
|
async (y) => {
|
|
579
579
|
r(!0), o(null);
|
|
580
580
|
try {
|
|
@@ -590,7 +590,7 @@ function It() {
|
|
|
590
590
|
);
|
|
591
591
|
return {
|
|
592
592
|
enhance: h,
|
|
593
|
-
removeBg:
|
|
593
|
+
removeBg: p,
|
|
594
594
|
isEnhancing: e,
|
|
595
595
|
isRemovingBg: n,
|
|
596
596
|
error: a,
|
|
@@ -622,12 +622,12 @@ function kt({ isOpen: e, onClose: t, onSubmit: n }) {
|
|
|
622
622
|
hint: "The key is stored locally in your browser."
|
|
623
623
|
}
|
|
624
624
|
}[r];
|
|
625
|
-
return /* @__PURE__ */
|
|
626
|
-
/* @__PURE__ */
|
|
625
|
+
return /* @__PURE__ */ m("dialog", { className: "modal modal-open", children: [
|
|
626
|
+
/* @__PURE__ */ m("div", { className: "modal-box", children: [
|
|
627
627
|
/* @__PURE__ */ d("h3", { className: "font-bold text-lg", children: l.title }),
|
|
628
628
|
/* @__PURE__ */ d("p", { className: "py-4 text-sm opacity-80", children: l.description }),
|
|
629
|
-
/* @__PURE__ */
|
|
630
|
-
/* @__PURE__ */
|
|
629
|
+
/* @__PURE__ */ m("form", { onSubmit: i, children: [
|
|
630
|
+
/* @__PURE__ */ m("div", { className: "form-control", children: [
|
|
631
631
|
/* @__PURE__ */ d(
|
|
632
632
|
"input",
|
|
633
633
|
{
|
|
@@ -641,7 +641,7 @@ function kt({ isOpen: e, onClose: t, onSubmit: n }) {
|
|
|
641
641
|
),
|
|
642
642
|
/* @__PURE__ */ d("label", { className: "label", children: /* @__PURE__ */ d("span", { className: "label-text-alt", children: l.hint }) })
|
|
643
643
|
] }),
|
|
644
|
-
/* @__PURE__ */
|
|
644
|
+
/* @__PURE__ */ m("div", { className: "modal-action", children: [
|
|
645
645
|
/* @__PURE__ */ d("button", { type: "button", className: "btn btn-ghost", onClick: t, children: l.cancel }),
|
|
646
646
|
/* @__PURE__ */ d("button", { type: "submit", className: "btn btn-primary", disabled: !a.trim(), children: l.submit })
|
|
647
647
|
] })
|
|
@@ -651,11 +651,11 @@ function kt({ isOpen: e, onClose: t, onSubmit: n }) {
|
|
|
651
651
|
] });
|
|
652
652
|
}
|
|
653
653
|
function Jt() {
|
|
654
|
-
const e = b((s) => s.voucherConfig.language), t = b((s) => s.portrait), n = b((s) => s.setPortrait), r = b((s) => s.setPortraitZoom), a = b((s) => s.setPortraitPan), o = b((s) => s.setPortraitRawImage), i = b((s) => s.setPortraitBgRemoved), c = b((s) => s.setPortraitBgOpacity), l = b((s) => s.setPortraitBgBlur), u = b((s) => s.setPortraitEngravingIntensity), { enhance: h, removeBg:
|
|
654
|
+
const e = b((s) => s.voucherConfig.language), t = b((s) => s.portrait), n = b((s) => s.setPortrait), r = b((s) => s.setPortraitZoom), a = b((s) => s.setPortraitPan), o = b((s) => s.setPortraitRawImage), i = b((s) => s.setPortraitBgRemoved), c = b((s) => s.setPortraitBgOpacity), l = b((s) => s.setPortraitBgBlur), u = b((s) => s.setPortraitEngravingIntensity), { enhance: h, removeBg: p, isEnhancing: y, isRemovingBg: g, error: x, hasKey: w, setApiKey: k } = It(), P = V(e), S = W(null), I = W(null), [C, N] = X(!1), [M, L] = X(!1), [H, $] = X(!1), R = W(null), A = W(null), z = W(null), E = t.rawImage, O = t.bgRemovedImage, U = t.bgRemoved, F = t.bgOpacity, Z = t.bgBlur, de = t.engravingIntensity;
|
|
655
655
|
re(() => {
|
|
656
656
|
t.original && !t.rawImage && o(t.original);
|
|
657
657
|
}, [t.original, t.rawImage, o]), re(() => () => {
|
|
658
|
-
A.current && clearTimeout(A.current),
|
|
658
|
+
A.current && clearTimeout(A.current), z.current && clearTimeout(z.current);
|
|
659
659
|
}, []);
|
|
660
660
|
const ie = B(
|
|
661
661
|
async (s) => {
|
|
@@ -663,9 +663,9 @@ function Jt() {
|
|
|
663
663
|
return;
|
|
664
664
|
const v = new FileReader();
|
|
665
665
|
v.onload = async (T) => {
|
|
666
|
-
var
|
|
667
|
-
const
|
|
668
|
-
o(
|
|
666
|
+
var pe;
|
|
667
|
+
const Y = (pe = T.target) == null ? void 0 : pe.result, me = await dt(Y);
|
|
668
|
+
o(me), n(me), i(!1, null), u(0);
|
|
669
669
|
}, v.readAsDataURL(s);
|
|
670
670
|
},
|
|
671
671
|
[n, o, i, u]
|
|
@@ -695,26 +695,26 @@ function Jt() {
|
|
|
695
695
|
}
|
|
696
696
|
}, [h]), Q = B(async (s) => {
|
|
697
697
|
try {
|
|
698
|
-
const v = await
|
|
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
|
-
}, [
|
|
703
|
+
}, [p, i]), G = B(async () => {
|
|
704
704
|
const s = b.getState().portrait;
|
|
705
705
|
if (!s.rawImage) return;
|
|
706
706
|
let v;
|
|
707
707
|
s.bgRemoved && s.bgRemovedImage ? v = await Ie(s.bgRemovedImage, s.rawImage, s.bgOpacity, s.bgBlur) : v = s.rawImage, s.engravingIntensity > 0 && (v = await q(v, s.engravingIntensity)), n(v);
|
|
708
708
|
}, [q, n]), se = async () => {
|
|
709
709
|
if (!E) return;
|
|
710
|
-
if (!
|
|
710
|
+
if (!U && !w) {
|
|
711
711
|
L(!0);
|
|
712
712
|
return;
|
|
713
713
|
}
|
|
714
|
-
if (!
|
|
714
|
+
if (!U) {
|
|
715
715
|
const v = await Q(E), T = b.getState().portrait;
|
|
716
|
-
let
|
|
717
|
-
T.engravingIntensity > 0 && (
|
|
716
|
+
let Y = await Ie(v, E, T.bgOpacity, T.bgBlur);
|
|
717
|
+
T.engravingIntensity > 0 && (Y = await q(Y, T.engravingIntensity)), n(Y);
|
|
718
718
|
} else {
|
|
719
719
|
i(!1, null);
|
|
720
720
|
const v = b.getState().portrait.engravingIntensity;
|
|
@@ -729,12 +729,12 @@ function Jt() {
|
|
|
729
729
|
}, ye = async (s) => {
|
|
730
730
|
if (k(s), !E) return;
|
|
731
731
|
const v = await Q(E), T = b.getState().portrait;
|
|
732
|
-
let
|
|
733
|
-
T.engravingIntensity > 0 && (
|
|
732
|
+
let Y = await Ie(v, E, T.bgOpacity, T.bgBlur);
|
|
733
|
+
T.engravingIntensity > 0 && (Y = await q(Y, T.engravingIntensity)), n(Y);
|
|
734
734
|
}, ve = (s) => {
|
|
735
|
-
c(s),
|
|
735
|
+
c(s), z.current && clearTimeout(z.current), !(!E || !O) && (z.current = setTimeout(G, 150));
|
|
736
736
|
}, ue = (s) => {
|
|
737
|
-
l(s),
|
|
737
|
+
l(s), z.current && clearTimeout(z.current), !(!E || !O) && (z.current = setTimeout(G, 150));
|
|
738
738
|
}, he = () => {
|
|
739
739
|
n(null), o(null), i(!1, null), c(0), l(0), u(0), ct();
|
|
740
740
|
}, Ne = (s, v) => {
|
|
@@ -746,7 +746,7 @@ function Jt() {
|
|
|
746
746
|
});
|
|
747
747
|
}, Re = (s, v) => {
|
|
748
748
|
if (!H || !R.current || !I.current) return;
|
|
749
|
-
const T = I.current.getBoundingClientRect(),
|
|
749
|
+
const T = I.current.getBoundingClientRect(), Y = 2 / Math.max(T.width, T.height), me = (s - R.current.x) * Y, pe = (v - R.current.y) * Y, Qe = Math.max(-1, Math.min(1, R.current.panX + me)), et = Math.max(-1, Math.min(1, R.current.panY + pe));
|
|
750
750
|
a(Qe, et);
|
|
751
751
|
}, xe = () => {
|
|
752
752
|
$(!1), R.current = null;
|
|
@@ -765,9 +765,9 @@ function Jt() {
|
|
|
765
765
|
}, Je = () => {
|
|
766
766
|
xe();
|
|
767
767
|
};
|
|
768
|
-
return /* @__PURE__ */
|
|
769
|
-
t.original ? /* @__PURE__ */
|
|
770
|
-
/* @__PURE__ */
|
|
768
|
+
return /* @__PURE__ */ m("div", { className: "space-y-4", children: [
|
|
769
|
+
t.original ? /* @__PURE__ */ m("div", { className: "flex flex-col items-center space-y-4", children: [
|
|
770
|
+
/* @__PURE__ */ m("div", { className: "relative", children: [
|
|
771
771
|
/* @__PURE__ */ d(
|
|
772
772
|
"div",
|
|
773
773
|
{
|
|
@@ -821,11 +821,11 @@ function Jt() {
|
|
|
821
821
|
}
|
|
822
822
|
)
|
|
823
823
|
] }),
|
|
824
|
-
/* @__PURE__ */
|
|
825
|
-
/* @__PURE__ */
|
|
826
|
-
/* @__PURE__ */
|
|
824
|
+
/* @__PURE__ */ m("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4 w-full", children: [
|
|
825
|
+
/* @__PURE__ */ m("div", { className: "form-control w-full", children: [
|
|
826
|
+
/* @__PURE__ */ m("label", { className: "label", children: [
|
|
827
827
|
/* @__PURE__ */ d("span", { className: "label-text", children: P.form.portrait.zoom }),
|
|
828
|
-
/* @__PURE__ */
|
|
828
|
+
/* @__PURE__ */ m("span", { className: "label-text-alt", children: [
|
|
829
829
|
Math.round(t.zoom * 100),
|
|
830
830
|
"%"
|
|
831
831
|
] })
|
|
@@ -846,13 +846,13 @@ function Jt() {
|
|
|
846
846
|
}
|
|
847
847
|
)
|
|
848
848
|
] }),
|
|
849
|
-
/* @__PURE__ */
|
|
850
|
-
/* @__PURE__ */
|
|
851
|
-
/* @__PURE__ */
|
|
849
|
+
/* @__PURE__ */ m("div", { className: "form-control w-full", children: [
|
|
850
|
+
/* @__PURE__ */ m("label", { className: "label", children: [
|
|
851
|
+
/* @__PURE__ */ m("span", { className: "label-text flex items-center gap-2", children: [
|
|
852
852
|
e === "de" ? "Sepia-Effekt" : "Sepia effect",
|
|
853
853
|
y && /* @__PURE__ */ d("span", { className: "loading loading-spinner loading-xs" })
|
|
854
854
|
] }),
|
|
855
|
-
/* @__PURE__ */
|
|
855
|
+
/* @__PURE__ */ m("span", { className: "label-text-alt", children: [
|
|
856
856
|
Math.round(de * 100),
|
|
857
857
|
"%"
|
|
858
858
|
] })
|
|
@@ -872,13 +872,13 @@ function Jt() {
|
|
|
872
872
|
)
|
|
873
873
|
] })
|
|
874
874
|
] }),
|
|
875
|
-
|
|
875
|
+
U ? (
|
|
876
876
|
// Show opacity and blur sliders when background has been removed
|
|
877
|
-
/* @__PURE__ */
|
|
878
|
-
/* @__PURE__ */
|
|
879
|
-
/* @__PURE__ */
|
|
877
|
+
/* @__PURE__ */ m("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4 w-full", children: [
|
|
878
|
+
/* @__PURE__ */ m("div", { className: "form-control w-full", children: [
|
|
879
|
+
/* @__PURE__ */ m("label", { className: "label", children: [
|
|
880
880
|
/* @__PURE__ */ d("span", { className: "label-text", children: e === "de" ? "Hintergrund" : "Background" }),
|
|
881
|
-
/* @__PURE__ */
|
|
881
|
+
/* @__PURE__ */ m("span", { className: "label-text-alt", children: [
|
|
882
882
|
Math.round(F * 100),
|
|
883
883
|
"%"
|
|
884
884
|
] })
|
|
@@ -896,10 +896,10 @@ function Jt() {
|
|
|
896
896
|
}
|
|
897
897
|
)
|
|
898
898
|
] }),
|
|
899
|
-
/* @__PURE__ */
|
|
900
|
-
/* @__PURE__ */
|
|
899
|
+
/* @__PURE__ */ m("div", { className: "form-control w-full", children: [
|
|
900
|
+
/* @__PURE__ */ m("label", { className: "label", children: [
|
|
901
901
|
/* @__PURE__ */ d("span", { className: "label-text", children: e === "de" ? "Unschärfe" : "Blur" }),
|
|
902
|
-
/* @__PURE__ */
|
|
902
|
+
/* @__PURE__ */ m("span", { className: "label-text-alt", children: [
|
|
903
903
|
Math.round(Z * 100),
|
|
904
904
|
"%"
|
|
905
905
|
] })
|
|
@@ -920,19 +920,19 @@ function Jt() {
|
|
|
920
920
|
] })
|
|
921
921
|
) : (
|
|
922
922
|
// Show toggle when background not yet removed
|
|
923
|
-
/* @__PURE__ */ d("div", { className: "form-control", children: /* @__PURE__ */
|
|
923
|
+
/* @__PURE__ */ d("div", { className: "form-control", children: /* @__PURE__ */ m("label", { className: "label cursor-pointer justify-start gap-3", children: [
|
|
924
924
|
/* @__PURE__ */ d(
|
|
925
925
|
"input",
|
|
926
926
|
{
|
|
927
927
|
type: "checkbox",
|
|
928
928
|
className: `toggle toggle-primary ${g ? "opacity-50" : ""}`,
|
|
929
|
-
checked:
|
|
929
|
+
checked: U,
|
|
930
930
|
onChange: se,
|
|
931
931
|
disabled: g || !E
|
|
932
932
|
}
|
|
933
933
|
),
|
|
934
|
-
/* @__PURE__ */
|
|
935
|
-
g ? /* @__PURE__ */
|
|
934
|
+
/* @__PURE__ */ m("span", { className: "label-text flex items-center gap-2", children: [
|
|
935
|
+
g ? /* @__PURE__ */ m(tt, { children: [
|
|
936
936
|
/* @__PURE__ */ d("span", { className: "loading loading-spinner loading-xs" }),
|
|
937
937
|
e === "de" ? "Hintergrund wird entfernt..." : "Removing background..."
|
|
938
938
|
] }) : e === "de" ? "Hintergrund entfernen" : "Remove background",
|
|
@@ -940,11 +940,11 @@ function Jt() {
|
|
|
940
940
|
] })
|
|
941
941
|
] }) })
|
|
942
942
|
),
|
|
943
|
-
x && /* @__PURE__ */
|
|
943
|
+
x && /* @__PURE__ */ m("div", { className: "alert alert-warning text-sm py-2", children: [
|
|
944
944
|
/* @__PURE__ */ d("svg", { xmlns: "http://www.w3.org/2000/svg", className: "stroke-current shrink-0 h-5 w-5", fill: "none", viewBox: "0 0 24 24", children: /* @__PURE__ */ d("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" }) }),
|
|
945
945
|
/* @__PURE__ */ d("span", { children: x })
|
|
946
946
|
] })
|
|
947
|
-
] }) : /* @__PURE__ */
|
|
947
|
+
] }) : /* @__PURE__ */ m(
|
|
948
948
|
"div",
|
|
949
949
|
{
|
|
950
950
|
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"}`,
|
|
@@ -963,10 +963,10 @@ function Jt() {
|
|
|
963
963
|
onChange: J
|
|
964
964
|
}
|
|
965
965
|
),
|
|
966
|
-
g ? /* @__PURE__ */
|
|
966
|
+
g ? /* @__PURE__ */ m("div", { className: "flex flex-col items-center gap-2", children: [
|
|
967
967
|
/* @__PURE__ */ d("span", { className: "loading loading-spinner loading-lg text-primary" }),
|
|
968
968
|
/* @__PURE__ */ d("p", { className: "font-medium", children: e === "de" ? "Hintergrund wird entfernt..." : "Removing background..." })
|
|
969
|
-
] }) : /* @__PURE__ */
|
|
969
|
+
] }) : /* @__PURE__ */ m("div", { className: "flex flex-col items-center gap-2", children: [
|
|
970
970
|
/* @__PURE__ */ d(
|
|
971
971
|
"svg",
|
|
972
972
|
{
|
|
@@ -1004,10 +1004,10 @@ function Jt() {
|
|
|
1004
1004
|
}
|
|
1005
1005
|
function Qt() {
|
|
1006
1006
|
const e = b((a) => a.voucherConfig.language), t = b((a) => a.voucherConfig.templateHue), n = b((a) => a.setTemplateHue), r = V(e);
|
|
1007
|
-
return /* @__PURE__ */ d("div", { className: "space-y-4", children: /* @__PURE__ */
|
|
1008
|
-
/* @__PURE__ */
|
|
1007
|
+
return /* @__PURE__ */ d("div", { className: "space-y-4", children: /* @__PURE__ */ m("div", { className: "form-control", children: [
|
|
1008
|
+
/* @__PURE__ */ m("label", { className: "label", children: [
|
|
1009
1009
|
/* @__PURE__ */ d("span", { className: "label-text font-medium", children: r.form.billColor.label }),
|
|
1010
|
-
/* @__PURE__ */
|
|
1010
|
+
/* @__PURE__ */ m("span", { className: "label-text-alt", children: [
|
|
1011
1011
|
t,
|
|
1012
1012
|
"°"
|
|
1013
1013
|
] })
|
|
@@ -1020,7 +1020,7 @@ function Qt() {
|
|
|
1020
1020
|
max: "360",
|
|
1021
1021
|
value: t,
|
|
1022
1022
|
onChange: (a) => n(Number(a.target.value)),
|
|
1023
|
-
className: "range range-
|
|
1023
|
+
className: "w-full h-3 rounded-lg appearance-none cursor-pointer [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:w-5 [&::-webkit-slider-thumb]:h-5 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-white [&::-webkit-slider-thumb]:shadow-md [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-gray-300 [&::-moz-range-thumb]:w-5 [&::-moz-range-thumb]:h-5 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-white [&::-moz-range-thumb]:shadow-md [&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-gray-300",
|
|
1024
1024
|
style: {
|
|
1025
1025
|
background: `linear-gradient(to right,
|
|
1026
1026
|
hsl(0, 70%, 50%),
|
|
@@ -1033,7 +1033,7 @@ function Qt() {
|
|
|
1033
1033
|
}
|
|
1034
1034
|
}
|
|
1035
1035
|
),
|
|
1036
|
-
/* @__PURE__ */
|
|
1036
|
+
/* @__PURE__ */ m("div", { className: "flex justify-between text-xs px-1 mt-1 opacity-60", children: [
|
|
1037
1037
|
/* @__PURE__ */ d("span", { children: "0°" }),
|
|
1038
1038
|
/* @__PURE__ */ d("span", { children: "90°" }),
|
|
1039
1039
|
/* @__PURE__ */ d("span", { children: "180°" }),
|
|
@@ -1252,7 +1252,7 @@ async function Oe(e, t, n, r) {
|
|
|
1252
1252
|
const c = i.getContext("2d");
|
|
1253
1253
|
if (!c) throw new Error("Failed to get canvas context");
|
|
1254
1254
|
c.drawImage(o, 0, 0, n, r);
|
|
1255
|
-
const l = i.toDataURL("image/png"), u = await
|
|
1255
|
+
const l = i.toDataURL("image/png"), u = await pt(l, t);
|
|
1256
1256
|
if (ee.size > 20) {
|
|
1257
1257
|
const h = ee.keys().next().value;
|
|
1258
1258
|
h && ee.delete(h);
|
|
@@ -1261,10 +1261,10 @@ async function Oe(e, t, n, r) {
|
|
|
1261
1261
|
}
|
|
1262
1262
|
function St(e, t, n, r, a, o, i = 1, c = 0, l = 0) {
|
|
1263
1263
|
e.save(), e.beginPath(), e.ellipse(n, r, a, o, 0, 0, Math.PI * 2), e.closePath(), e.clip();
|
|
1264
|
-
const u = t.width / t.height, h = a / o,
|
|
1264
|
+
const u = t.width / t.height, h = a / o, p = a * 2, y = o * 2;
|
|
1265
1265
|
let g, x;
|
|
1266
|
-
u > h ? (x = y, g = y * u) : (g =
|
|
1267
|
-
const w = Math.max(0, (g -
|
|
1266
|
+
u > h ? (x = y, g = y * u) : (g = p, x = p / u), g *= i, x *= i;
|
|
1267
|
+
const w = Math.max(0, (g - p) / 2), k = Math.max(0, (x - y) / 2), P = n - g / 2 + c * w, S = r - x / 2 + l * k;
|
|
1268
1268
|
e.drawImage(t, P, S, g, x), e.restore();
|
|
1269
1269
|
}
|
|
1270
1270
|
function je(e, t, n, r = "#2a3a2a") {
|
|
@@ -1274,15 +1274,15 @@ function Et(e, t, n, r = "#2a3a2a") {
|
|
|
1274
1274
|
e.save(), e.font = `${n.fontSize}px "Times New Roman", serif`, e.textAlign = n.align || "center", e.textBaseline = "top", e.fillStyle = r;
|
|
1275
1275
|
const a = n.maxWidth || 400, o = n.lineHeight || n.fontSize * 1.4, i = t.split(" "), c = [];
|
|
1276
1276
|
let l = "";
|
|
1277
|
-
for (const
|
|
1278
|
-
const y = l ? `${l} ${
|
|
1279
|
-
e.measureText(y).width > a && l ? (c.push(l), l =
|
|
1277
|
+
for (const p of i) {
|
|
1278
|
+
const y = l ? `${l} ${p}` : p;
|
|
1279
|
+
e.measureText(y).width > a && l ? (c.push(l), l = p) : l = y;
|
|
1280
1280
|
}
|
|
1281
1281
|
l && c.push(l);
|
|
1282
1282
|
const u = c.length * o;
|
|
1283
1283
|
let h = n.y - u / 2;
|
|
1284
|
-
for (const
|
|
1285
|
-
e.fillText(
|
|
1284
|
+
for (const p of c)
|
|
1285
|
+
e.fillText(p, n.x, h), h += o;
|
|
1286
1286
|
e.restore();
|
|
1287
1287
|
}
|
|
1288
1288
|
function Nt(e, t, n, r, a, o = "#2a3a2a") {
|
|
@@ -1294,15 +1294,15 @@ function Nt(e, t, n, r, a, o = "#2a3a2a") {
|
|
|
1294
1294
|
e.restore();
|
|
1295
1295
|
}
|
|
1296
1296
|
async function Rt(e, t, n, r, a, o, i, c = 1, l = 0, u = 0, h = 0) {
|
|
1297
|
-
const
|
|
1298
|
-
if (!
|
|
1299
|
-
e.width = o, e.height = i,
|
|
1297
|
+
const p = e.getContext("2d");
|
|
1298
|
+
if (!p) return;
|
|
1299
|
+
e.width = o, e.height = i, p.clearRect(0, 0, o, i);
|
|
1300
1300
|
const y = await Oe(t, h, o, i);
|
|
1301
|
-
if ($e(
|
|
1301
|
+
if ($e(p, y, o, i), n)
|
|
1302
1302
|
try {
|
|
1303
1303
|
const g = await le(n);
|
|
1304
1304
|
St(
|
|
1305
|
-
|
|
1305
|
+
p,
|
|
1306
1306
|
g,
|
|
1307
1307
|
a.portrait.x,
|
|
1308
1308
|
a.portrait.y,
|
|
@@ -1315,14 +1315,14 @@ async function Rt(e, t, n, r, a, o, i, c = 1, l = 0, u = 0, h = 0) {
|
|
|
1315
1315
|
} catch (g) {
|
|
1316
1316
|
console.error("Failed to load portrait:", g);
|
|
1317
1317
|
}
|
|
1318
|
-
r && je(
|
|
1318
|
+
r && je(p, r, a.namePlate);
|
|
1319
1319
|
}
|
|
1320
1320
|
async function Bt(e, t, n, r, a, o, i, c, l, u = 0) {
|
|
1321
1321
|
const h = e.getContext("2d");
|
|
1322
1322
|
if (!h) return;
|
|
1323
1323
|
e.width = c, e.height = l, h.clearRect(0, 0, c, l);
|
|
1324
|
-
const
|
|
1325
|
-
$e(h,
|
|
1324
|
+
const p = await Oe(t, u, c, l);
|
|
1325
|
+
$e(h, p, c, l), i.contactInfo && (n || r || a) && Nt(h, n, r, a, i.contactInfo), i.description && o && Et(h, o, i.description), n && je(h, n, i.namePlate);
|
|
1326
1326
|
}
|
|
1327
1327
|
function Lt(e, t) {
|
|
1328
1328
|
const [n, r] = X(e);
|
|
@@ -1332,10 +1332,10 @@ function Lt(e, t) {
|
|
|
1332
1332
|
}, [e, t]), n;
|
|
1333
1333
|
}
|
|
1334
1334
|
function en() {
|
|
1335
|
-
const e = b((f) => f.voucherConfig.language), t = b((f) => f.voucherConfig.hours), n = b((f) => f.voucherConfig.description), r = b((f) => f.voucherConfig.templateHue), a = b((f) => f.personalInfo), o = b((f) => f.portrait), i = b((f) => f.currentSide), c = b((f) => f.flipSide), l = b((f) => f.setPortraitPan), u = Lt(r, 150), h = V(e),
|
|
1335
|
+
const e = b((f) => f.voucherConfig.language), t = b((f) => f.voucherConfig.hours), n = b((f) => f.voucherConfig.description), r = b((f) => f.voucherConfig.templateHue), a = b((f) => f.personalInfo), o = b((f) => f.portrait), i = b((f) => f.currentSide), c = b((f) => f.flipSide), l = b((f) => f.setPortraitPan), u = Lt(r, 150), h = V(e), p = W(null), y = W(null), g = W(null), [x, w] = X(!1), [k, P] = X(!1), S = W(null), I = Tt(e, t), C = Ct(e), N = o.useEnhanced && o.enhanced ? o.enhanced : o.original, M = Ue(e, t, n);
|
|
1336
1336
|
re(() => {
|
|
1337
|
-
|
|
1338
|
-
|
|
1337
|
+
p.current && Rt(
|
|
1338
|
+
p.current,
|
|
1339
1339
|
I.front,
|
|
1340
1340
|
N,
|
|
1341
1341
|
a.name,
|
|
@@ -1382,11 +1382,11 @@ function en() {
|
|
|
1382
1382
|
l(G, se);
|
|
1383
1383
|
}, [k, l]), A = B(() => {
|
|
1384
1384
|
P(!1), S.current = null;
|
|
1385
|
-
}, []),
|
|
1385
|
+
}, []), z = (f) => {
|
|
1386
1386
|
o.zoom > 1 && H(f.clientX, f.clientY) && (f.preventDefault(), $(f.clientX, f.clientY));
|
|
1387
1387
|
}, E = (f) => {
|
|
1388
1388
|
R(f.clientX, f.clientY);
|
|
1389
|
-
}, O = () => A(),
|
|
1389
|
+
}, O = () => A(), U = () => A(), F = (f) => {
|
|
1390
1390
|
if (f.touches.length === 1) {
|
|
1391
1391
|
const D = f.touches[0];
|
|
1392
1392
|
o.zoom > 1 && H(D.clientX, D.clientY) && $(D.clientX, D.clientY);
|
|
@@ -1394,9 +1394,9 @@ function en() {
|
|
|
1394
1394
|
}, Z = (f) => {
|
|
1395
1395
|
f.touches.length === 1 && R(f.touches[0].clientX, f.touches[0].clientY);
|
|
1396
1396
|
}, de = () => A(), ie = i === "front" && o.original && o.zoom > 1, be = I.width / I.height;
|
|
1397
|
-
return /* @__PURE__ */
|
|
1398
|
-
/* @__PURE__ */
|
|
1399
|
-
/* @__PURE__ */
|
|
1397
|
+
return /* @__PURE__ */ m("div", { className: "space-y-4", children: [
|
|
1398
|
+
/* @__PURE__ */ m("div", { className: "flex justify-between items-center", children: [
|
|
1399
|
+
/* @__PURE__ */ m("div", { className: "tabs tabs-boxed bg-base-200", children: [
|
|
1400
1400
|
/* @__PURE__ */ d(
|
|
1401
1401
|
"button",
|
|
1402
1402
|
{
|
|
@@ -1414,7 +1414,7 @@ function en() {
|
|
|
1414
1414
|
}
|
|
1415
1415
|
)
|
|
1416
1416
|
] }),
|
|
1417
|
-
/* @__PURE__ */
|
|
1417
|
+
/* @__PURE__ */ m("button", { className: "btn btn-ghost btn-sm", onClick: L, children: [
|
|
1418
1418
|
/* @__PURE__ */ d(
|
|
1419
1419
|
"svg",
|
|
1420
1420
|
{
|
|
@@ -1437,16 +1437,16 @@ function en() {
|
|
|
1437
1437
|
h.preview.flip
|
|
1438
1438
|
] })
|
|
1439
1439
|
] }),
|
|
1440
|
-
/* @__PURE__ */
|
|
1440
|
+
/* @__PURE__ */ m(
|
|
1441
1441
|
"div",
|
|
1442
1442
|
{
|
|
1443
1443
|
ref: g,
|
|
1444
1444
|
className: `relative w-full overflow-hidden shadow-lg ${ie ? k ? "cursor-grabbing" : "cursor-grab" : ""}`,
|
|
1445
1445
|
style: { aspectRatio: be },
|
|
1446
|
-
onMouseDown:
|
|
1446
|
+
onMouseDown: z,
|
|
1447
1447
|
onMouseMove: E,
|
|
1448
1448
|
onMouseUp: O,
|
|
1449
|
-
onMouseLeave:
|
|
1449
|
+
onMouseLeave: U,
|
|
1450
1450
|
onTouchStart: F,
|
|
1451
1451
|
onTouchMove: Z,
|
|
1452
1452
|
onTouchEnd: de,
|
|
@@ -1454,7 +1454,7 @@ function en() {
|
|
|
1454
1454
|
/* @__PURE__ */ d(
|
|
1455
1455
|
"canvas",
|
|
1456
1456
|
{
|
|
1457
|
-
ref:
|
|
1457
|
+
ref: p,
|
|
1458
1458
|
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"}`
|
|
1459
1459
|
}
|
|
1460
1460
|
),
|
|
@@ -1859,7 +1859,7 @@ async function Mt(e) {
|
|
|
1859
1859
|
portraitPanX: l = 0,
|
|
1860
1860
|
portraitPanY: u = 0,
|
|
1861
1861
|
templateHue: h = 160,
|
|
1862
|
-
name:
|
|
1862
|
+
name: p,
|
|
1863
1863
|
email: y,
|
|
1864
1864
|
phone: g,
|
|
1865
1865
|
description: x
|
|
@@ -1877,12 +1877,12 @@ async function Mt(e) {
|
|
|
1877
1877
|
I(new Error("Invalid response from worker"));
|
|
1878
1878
|
return;
|
|
1879
1879
|
}
|
|
1880
|
-
const
|
|
1881
|
-
orientation: O >
|
|
1880
|
+
const z = Ae(H, "image/jpeg"), E = Ae($, "image/jpeg"), O = R / 96 * 25.4, U = A / 96 * 25.4, F = new rt({
|
|
1881
|
+
orientation: O > U ? "landscape" : "portrait",
|
|
1882
1882
|
unit: "mm",
|
|
1883
|
-
format: [O,
|
|
1883
|
+
format: [O, U]
|
|
1884
1884
|
});
|
|
1885
|
-
F.addImage(
|
|
1885
|
+
F.addImage(z, "JPEG", 0, 0, O, U), F.addPage([O, U]), F.addImage(E, "JPEG", 0, 0, O, U);
|
|
1886
1886
|
const Z = F.output("blob");
|
|
1887
1887
|
S(Z);
|
|
1888
1888
|
} catch (H) {
|
|
@@ -1915,7 +1915,7 @@ async function Mt(e) {
|
|
|
1915
1915
|
description: o.back.description
|
|
1916
1916
|
}
|
|
1917
1917
|
},
|
|
1918
|
-
name:
|
|
1918
|
+
name: p,
|
|
1919
1919
|
email: y,
|
|
1920
1920
|
phone: g,
|
|
1921
1921
|
description: x
|
|
@@ -1926,13 +1926,13 @@ function At(e, t) {
|
|
|
1926
1926
|
const n = URL.createObjectURL(e), r = document.createElement("a");
|
|
1927
1927
|
r.href = n, r.download = t, document.body.appendChild(r), r.click(), document.body.removeChild(r), URL.revokeObjectURL(n);
|
|
1928
1928
|
}
|
|
1929
|
-
async function
|
|
1929
|
+
async function zt(e) {
|
|
1930
1930
|
const t = await Mt(e);
|
|
1931
1931
|
At(t, e.filename);
|
|
1932
1932
|
}
|
|
1933
1933
|
function nn() {
|
|
1934
|
-
const e = b((w) => w.voucherConfig.language), t = b((w) => w.voucherConfig.hours), n = b((w) => w.voucherConfig.description), r = b((w) => w.voucherConfig.templateHue), a = b((w) => w.personalInfo), o = b((w) => w.portrait), i = b((w) => w.isExporting), c = b((w) => w.setIsExporting), l = V(e), u = Pt(e, t), h = Xe(e),
|
|
1935
|
-
return /* @__PURE__ */
|
|
1934
|
+
const e = b((w) => w.voucherConfig.language), t = b((w) => w.voucherConfig.hours), n = b((w) => w.voucherConfig.description), r = b((w) => w.voucherConfig.templateHue), a = b((w) => w.personalInfo), o = b((w) => w.portrait), i = b((w) => w.isExporting), c = b((w) => w.setIsExporting), l = V(e), u = Pt(e, t), h = Xe(e), p = o.useEnhanced && o.enhanced ? o.enhanced : o.original, y = Ue(e, t, n), g = a.name.trim().length > 0 && a.email.trim().length > 0 && a.phone.trim().length > 0 && o.original !== null;
|
|
1935
|
+
return /* @__PURE__ */ m(
|
|
1936
1936
|
"button",
|
|
1937
1937
|
{
|
|
1938
1938
|
className: `btn btn-primary flex-1 ${g ? "" : "btn-disabled"}`,
|
|
@@ -1941,13 +1941,13 @@ function nn() {
|
|
|
1941
1941
|
c(!0);
|
|
1942
1942
|
try {
|
|
1943
1943
|
const w = `zeitgutschein-${t}h-${a.name.replace(/\s+/g, "-").toLowerCase()}.pdf`;
|
|
1944
|
-
await
|
|
1944
|
+
await zt({
|
|
1945
1945
|
frontTemplateSrc: u.front,
|
|
1946
1946
|
backTemplateSrc: u.back,
|
|
1947
1947
|
templateWidth: u.width,
|
|
1948
1948
|
templateHeight: u.height,
|
|
1949
1949
|
layout: h,
|
|
1950
|
-
portrait:
|
|
1950
|
+
portrait: p,
|
|
1951
1951
|
portraitZoom: o.zoom,
|
|
1952
1952
|
portraitPanX: o.panX,
|
|
1953
1953
|
portraitPanY: o.panY,
|
|
@@ -1992,11 +1992,11 @@ function nn() {
|
|
|
1992
1992
|
}
|
|
1993
1993
|
);
|
|
1994
1994
|
}
|
|
1995
|
-
function
|
|
1995
|
+
function Ut() {
|
|
1996
1996
|
const e = b((r) => r.voucherConfig.language), t = b((r) => r.setLanguage), n = (r) => {
|
|
1997
1997
|
t(r);
|
|
1998
1998
|
};
|
|
1999
|
-
return /* @__PURE__ */
|
|
1999
|
+
return /* @__PURE__ */ m("div", { className: "join", children: [
|
|
2000
2000
|
/* @__PURE__ */ d(
|
|
2001
2001
|
"button",
|
|
2002
2002
|
{
|
|
@@ -2017,13 +2017,13 @@ function Yt() {
|
|
|
2017
2017
|
}
|
|
2018
2018
|
function an() {
|
|
2019
2019
|
const e = b((n) => n.voucherConfig.language), t = V(e);
|
|
2020
|
-
return /* @__PURE__ */
|
|
2020
|
+
return /* @__PURE__ */ m("div", { className: "navbar bg-currency-green text-currency-cream shadow-lg", children: [
|
|
2021
2021
|
/* @__PURE__ */ d("div", { className: "navbar-start", children: /* @__PURE__ */ d("a", { className: "btn btn-ghost text-xl font-currency font-bold", children: t.header.title }) }),
|
|
2022
2022
|
/* @__PURE__ */ d("div", { className: "navbar-center hidden sm:flex", children: /* @__PURE__ */ d("span", { className: "text-sm opacity-80", children: t.header.subtitle }) }),
|
|
2023
|
-
/* @__PURE__ */ d("div", { className: "navbar-end", children: /* @__PURE__ */ d(
|
|
2023
|
+
/* @__PURE__ */ d("div", { className: "navbar-end", children: /* @__PURE__ */ d(Ut, {}) })
|
|
2024
2024
|
] });
|
|
2025
2025
|
}
|
|
2026
|
-
const ge = "/",
|
|
2026
|
+
const ge = "/", Yt = {
|
|
2027
2027
|
id: "time-voucher-classic-de",
|
|
2028
2028
|
name: "Zeitgutschein Classic",
|
|
2029
2029
|
type: "time-voucher",
|
|
@@ -2151,16 +2151,16 @@ const ge = "/", zt = {
|
|
|
2151
2151
|
}
|
|
2152
2152
|
},
|
|
2153
2153
|
languages: ["en"]
|
|
2154
|
-
},
|
|
2155
|
-
|
|
2154
|
+
}, ze = [
|
|
2155
|
+
Yt,
|
|
2156
2156
|
_t
|
|
2157
2157
|
], Wt = {
|
|
2158
2158
|
async listTemplates(e) {
|
|
2159
|
-
let t = [...
|
|
2159
|
+
let t = [...ze];
|
|
2160
2160
|
return e != null && e.type && (t = t.filter((n) => n.type === e.type)), e != null && e.category && (t = t.filter((n) => n.category === e.category)), e != null && e.language && (t = t.filter((n) => n.languages.includes(e.language))), t;
|
|
2161
2161
|
},
|
|
2162
2162
|
async getTemplate(e) {
|
|
2163
|
-
const t =
|
|
2163
|
+
const t = ze.find((n) => n.id === e);
|
|
2164
2164
|
if (!t)
|
|
2165
2165
|
throw new Error(`Template not found: ${e}`);
|
|
2166
2166
|
return t;
|
|
@@ -2189,13 +2189,13 @@ export {
|
|
|
2189
2189
|
an as Header,
|
|
2190
2190
|
ae as LAYOUT_HDPI,
|
|
2191
2191
|
ne as LAYOUT_LDPI,
|
|
2192
|
-
|
|
2192
|
+
Ut as LanguageToggle,
|
|
2193
2193
|
Kt as PersonalInfoForm,
|
|
2194
2194
|
Jt as PortraitUpload,
|
|
2195
2195
|
We as TEMPLATES,
|
|
2196
2196
|
Qt as VoucherConfig,
|
|
2197
2197
|
ut as applyEngravingEffect,
|
|
2198
|
-
|
|
2198
|
+
pt as applyHueShift,
|
|
2199
2199
|
At as downloadBlob,
|
|
2200
2200
|
Nt as drawContactInfo,
|
|
2201
2201
|
Et as drawMultilineText,
|
|
@@ -2203,8 +2203,8 @@ export {
|
|
|
2203
2203
|
$e as drawTemplate,
|
|
2204
2204
|
je as drawText,
|
|
2205
2205
|
Zt as enhancePortrait,
|
|
2206
|
-
|
|
2207
|
-
|
|
2206
|
+
zt as exportBillAsPDF,
|
|
2207
|
+
Ue as formatDescription,
|
|
2208
2208
|
Mt as generateBillPDF,
|
|
2209
2209
|
Ee as getApiKey,
|
|
2210
2210
|
rn as getDefaultTemplateId,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antontranelis/money-printer",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.24",
|
|
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",
|