@antontranelis/money-printer 1.0.12 → 1.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),Se=require("zustand"),Ce=require("zustand/middleware"),b=require("react"),Te=require("jspdf");var _=typeof document<"u"?document.currentScript:null;const te={personalInfo:{name:"",email:"",phone:""},voucherConfig:{hours:1,description:"",language:"de"},portrait:{original:null,enhanced:null,useEnhanced:!1,zoom:1,rawImage:null,bgRemovedImage:null,bgRemoved:!1,engravingIntensity:0},currentSide:"front",isEnhancing:!1,isExporting:!1},v=Se.create()(Ce.persist(e=>({...te,setPersonalInfo:t=>e(n=>({personalInfo:{...n.personalInfo,...t}})),setVoucherConfig:t=>e(n=>({voucherConfig:{...n.voucherConfig,...t}})),setPortrait:(t,n=null)=>e(a=>({portrait:{...a.portrait,original:t,enhanced:n,useEnhanced:!1,zoom:a.portrait.original&&t?a.portrait.zoom:1}})),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}})),setPortraitRawImage:t=>e(n=>({portrait:{...n.portrait,rawImage:t}})),setPortraitBgRemoved:(t,n)=>e(a=>({portrait:{...a.portrait,bgRemoved:t,bgRemovedImage:n!==void 0?n:a.portrait.bgRemovedImage}})),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}})),reset:()=>e(te)}),{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,rawImage:null,bgRemovedImage:null,bgRemoved:!1,engravingIntensity:e.portrait.engravingIntensity}})})),Re={header:{title:"Money Generator",subtitle:"Erstelle deinen persönlichen Zeitgutschein"},form:{personalInfo:{title:"Persönliche Daten",name:"Name",namePlaceholder:"Dein Name",email:"E-Mail",emailPlaceholder:"deine@email.de",phone:"Telefon",phonePlaceholder:"+49 123 456789"},portrait:{title:"Portrait",upload:"Bild hochladen",dragDrop:"oder hierher ziehen",enhance:"Mit AI verbessern",enhancing:"Wird verbessert...",useOriginal:"Original verwenden",useEnhanced:"Verbessertes verwenden",zoom:"Zoom"},voucher:{title:"Gutschein",hours:"Stunden",hourLabel:"Stunde",hoursLabel:"Stunden",description:"Beschreibung",descriptionPlaceholder:"Was kann mit diesem Gutschein eingelöst werden?"}},preview:{front:"Vorderseite",back:"Rückseite",flip:"Umdrehen"},export:{button:"Als PDF herunterladen",exporting:"PDF wird erstellt...",success:"Download gestartet!"},bill:{descriptionText:"Für diesen Schein erhältst du {hours} {hourLabel} meiner Zeit oder ein gleichwertiges Dankeschön"}},Ae={header:{title:"Money Generator",subtitle:"Create your personal time voucher"},form:{personalInfo:{title:"Personal Information",name:"Name",namePlaceholder:"Your name",email:"Email",emailPlaceholder:"your@email.com",phone:"Phone",phonePlaceholder:"+1 234 567890"},portrait:{title:"Portrait",upload:"Upload image",dragDrop:"or drag and drop",enhance:"Enhance with AI",enhancing:"Enhancing...",useOriginal:"Use original",useEnhanced:"Use enhanced",zoom:"Zoom"},voucher:{title:"Voucher",hours:"Hours",hourLabel:"hour",hoursLabel:"hours",description:"Description",descriptionPlaceholder:"What can be redeemed with this voucher?"}},preview:{front:"Front",back:"Back",flip:"Flip"},export:{button:"Download as PDF",exporting:"Creating PDF...",success:"Download started!"},bill:{descriptionText:"This voucher entitles you to {hours} {hourLabel} of my time or an equivalent thank you"}},Le={de:Re,en:Ae};function A(e){return Le[e]}function W(e,t,n){if(n&&n.trim())return n;const a=A(e),o=t===1?a.form.voucher.hourLabel:a.form.voucher.hoursLabel;return a.bill.descriptionText.replace("{hours}",t.toString()).replace("{hourLabel}",o)}function _e(){const e=v(o=>o.voucherConfig.language),t=v(o=>o.personalInfo),n=v(o=>o.setPersonalInfo),a=A(e);return r.jsxs("div",{className:"space-y-4",children:[r.jsxs("div",{className:"form-control",children:[r.jsx("label",{className:"label",children:r.jsx("span",{className:"label-text font-medium",children:a.form.personalInfo.name})}),r.jsx("input",{type:"text",placeholder:a.form.personalInfo.namePlaceholder,className:"input input-bordered w-full",value:t.name,onChange:o=>n({name:o.target.value})})]}),r.jsxs("div",{className:"form-control",children:[r.jsx("label",{className:"label",children:r.jsx("span",{className:"label-text font-medium",children:a.form.personalInfo.email})}),r.jsx("input",{type:"email",placeholder:a.form.personalInfo.emailPlaceholder,className:"input input-bordered w-full",value:t.email,onChange:o=>n({email:o.target.value})})]}),r.jsxs("div",{className:"form-control",children:[r.jsx("label",{className:"label",children:r.jsx("span",{className:"label-text font-medium",children:a.form.personalInfo.phone})}),r.jsx("input",{type:"tel",placeholder:a.form.personalInfo.phonePlaceholder,className:"input input-bordered w-full",value:t.phone,onChange:o=>n({phone:o.target.value})})]})]})}async function re(e,t=.5){return new Promise((n,a)=>{const o=new Image;o.onload=()=>{const i=document.createElement("canvas"),c=i.getContext("2d");if(!c){a(new Error("Failed to get canvas context"));return}i.width=o.width,i.height=o.height,c.drawImage(o,0,0);const l=c.getImageData(0,0,i.width,i.height),s=l.data,d=1+t*.8;for(let u=0;u<s.length;u+=4){const g=s[u],p=s[u+1],f=s[u+2];if(s[u+3]===0)continue;let y=(((.299*g+.587*p+.114*f)/255-.5)*d+.5)*255;y=Math.max(0,Math.min(255,y));const I=Math.min(255,y*.9+25),C=Math.min(255,y*.78+15),w=Math.min(255,y*.55+5);s[u]=Math.round(g*(1-t)+I*t),s[u+1]=Math.round(p*(1-t)+C*t),s[u+2]=Math.round(f*(1-t)+w*t)}c.putImageData(l,0,0),n(i.toDataURL("image/png"))},o.onerror=()=>a(new Error("Failed to load image")),o.src=e})}const Be="https://api.stability.ai/v1/generation",De="https://api.stability.ai/v2beta/stable-image/edit/remove-background",oe="stability_api_key";let B=null;function $e(e){B=e}function Ue(){return B}function Me(){return B!==null}const ze={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"},ne=[{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 Fe(e,t){const n=e/t;let a=ne[0],o=1/0;for(const i of ne){const c=i.width/i.height,l=Math.abs(n-c);l<o&&(o=l,a=i)}return a}function He(e){return new Promise((t,n)=>{const a=new Image;a.onload=()=>{const o=Fe(a.width,a.height),i=document.createElement("canvas");i.width=o.width,i.height=o.height;const c=i.getContext("2d");if(!c){n(new Error("Failed to get canvas context"));return}const l=a.width/a.height,s=o.width/o.height;let d=0,u=0,g=a.width,p=a.height;l>s?(g=a.height*s,d=(a.width-g)/2):(p=a.width/s,u=(a.height-p)/2),c.drawImage(a,d,u,g,p,0,0,o.width,o.height),t(i.toDataURL("image/png"))},a.onerror=()=>n(new Error("Failed to load image")),a.src=e})}function ie(e){var c;const t=e.split(","),n=((c=t[0].match(/:(.*?);/))==null?void 0:c[1])||"image/png",a=atob(t[1]),o=a.length,i=new Uint8Array(o);for(let l=0;l<o;l++)i[l]=a.charCodeAt(l);return new Blob([i],{type:n})}function z(){var t;const e=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:_&&_.tagName.toUpperCase()==="SCRIPT"&&_.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(oe):null}function se(e){localStorage.setItem(oe,e)}function O(){return B?!0:z()!==null}async function Ke(e){const t=z();if(!t)throw new Error("No Stability AI API key configured");const{imageDataUrl:n,style:a,strength:o=.35}=e,i=await He(n),c=ie(i),l=new FormData;l.append("init_image",c,"portrait.png"),l.append("init_image_mode","IMAGE_STRENGTH"),l.append("image_strength",String(1-o)),l.append("text_prompts[0][text]",ze[a]),l.append("text_prompts[0][weight]","1"),l.append("cfg_scale","7"),l.append("samples","1"),l.append("steps","30");const d=await fetch(`${Be}/stable-diffusion-xl-1024-v1-0/image-to-image`,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"},body:l});if(!d.ok){const g=await d.text();throw console.error("Stability AI error:",g),d.status===401?new Error("Invalid API key"):d.status===402?new Error("Insufficient credits"):d.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${d.status}`)}const u=await d.json();if(!u.artifacts||u.artifacts.length===0)throw new Error("No image generated");return`data:image/png;base64,${u.artifacts[0].base64}`}async function le(e){if(B){const c=await fetch(B,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({imageDataUrl:e})});if(!c.ok){const s=await c.json().catch(()=>({}));throw new Error(s.error||`API error: ${c.status}`)}return(await c.json()).imageDataUrl}const t=z();if(!t)throw new Error("No Stability AI API key configured");const n=ie(e),a=new FormData;a.append("image",n,"image.png"),a.append("output_format","png");const o=await fetch(De,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"image/*"},body:a});if(!o.ok){const c=await o.text();throw console.error("Stability AI remove background error:",c),o.status===401?new Error("Invalid API key"):o.status===402?new Error("Insufficient credits"):o.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${o.status}`)}const i=await o.blob();return new Promise((c,l)=>{const s=new FileReader;s.onload=()=>c(s.result),s.onerror=()=>l(new Error("Failed to read result")),s.readAsDataURL(i)})}function Oe(){const[e,t]=b.useState(!1),[n,a]=b.useState(!1),[o,i]=b.useState(null),[c,l]=b.useState(()=>O());b.useEffect(()=>{l(O())},[]);const s=b.useCallback(()=>i(null),[]),d=b.useCallback(p=>{se(p),l(!0),i(null)},[]),u=b.useCallback(async(p,f=.5)=>{t(!0),i(null);try{return await re(p,f)}catch(h){const N=h instanceof Error?h.message:"Enhancement failed";throw i(N),h}finally{t(!1)}},[]),g=b.useCallback(async p=>{a(!0),i(null);try{return await le(p)}catch(f){const h=f instanceof Error?f.message:"Background removal failed";throw i(h),f}finally{a(!1)}},[]);return{enhance:u,removeBg:g,isEnhancing:e,isRemovingBg:n,error:o,hasKey:c,setApiKey:d,clearError:s}}function ce({isOpen:e,onClose:t,onSubmit:n}){const a=v(d=>d.voucherConfig.language),[o,i]=b.useState("");if(!e)return null;const c=d=>{d.preventDefault(),o.trim()&&(n(o.trim()),i(""),t())},s={de:{title:"Stability AI API Key",description:"Um die AI-Bildverbesserung zu nutzen, benötigst du einen Stability AI API Key. Du kannst ihn auf platform.stability.ai erhalten.",placeholder:"sk-...",submit:"Speichern",cancel:"Abbrechen",hint:"Der Key wird lokal in deinem Browser gespeichert."},en:{title:"Stability AI API Key",description:"To use AI image enhancement, you need a Stability AI API key. You can get one at platform.stability.ai.",placeholder:"sk-...",submit:"Save",cancel:"Cancel",hint:"The key is stored locally in your browser."}}[a];return r.jsxs("dialog",{className:"modal modal-open",children:[r.jsxs("div",{className:"modal-box",children:[r.jsx("h3",{className:"font-bold text-lg",children:s.title}),r.jsx("p",{className:"py-4 text-sm opacity-80",children:s.description}),r.jsxs("form",{onSubmit:c,children:[r.jsxs("div",{className:"form-control",children:[r.jsx("input",{type:"password",placeholder:s.placeholder,className:"input input-bordered w-full",value:o,onChange:d=>i(d.target.value),autoFocus:!0}),r.jsx("label",{className:"label",children:r.jsx("span",{className:"label-text-alt",children:s.hint})})]}),r.jsxs("div",{className:"modal-action",children:[r.jsx("button",{type:"button",className:"btn btn-ghost",onClick:t,children:s.cancel}),r.jsx("button",{type:"submit",className:"btn btn-primary",disabled:!o.trim(),children:s.submit})]})]})]}),r.jsx("form",{method:"dialog",className:"modal-backdrop",children:r.jsx("button",{onClick:t,children:"close"})})]})}function We(){const e=v(m=>m.voucherConfig.language),t=v(m=>m.portrait),n=v(m=>m.setPortrait),a=v(m=>m.setPortraitZoom),o=v(m=>m.setPortraitRawImage),i=v(m=>m.setPortraitBgRemoved),c=v(m=>m.setPortraitEngravingIntensity),{enhance:l,removeBg:s,isEnhancing:d,isRemovingBg:u,error:g,hasKey:p,setApiKey:f}=Oe(),h=A(e),N=b.useRef(null),[y,I]=b.useState(!1),[C,w]=b.useState(!1),P=b.useRef(null),k=t.rawImage,D=t.bgRemovedImage,L=t.bgRemoved,S=t.engravingIntensity;b.useEffect(()=>{t.original&&!t.rawImage&&o(t.original)},[t.original,t.rawImage,o]),b.useEffect(()=>()=>{P.current&&clearTimeout(P.current)},[]);const H=b.useCallback(async m=>{if(!m.type.startsWith("image/"))return;const x=new FileReader;x.onload=async j=>{var ee;const Q=(ee=j.target)==null?void 0:ee.result;o(Q),n(Q),i(!1,null),c(0)},x.readAsDataURL(m)},[n,o,i,c]),xe=b.useCallback(m=>{m.preventDefault(),I(!1);const x=m.dataTransfer.files[0];x&&H(x)},[H]),we=b.useCallback(m=>{m.preventDefault(),I(!0)},[]),ye=b.useCallback(m=>{m.preventDefault(),I(!1)},[]),Ie=()=>{var m;(m=N.current)==null||m.click()},ke=m=>{var j;const x=(j=m.target.files)==null?void 0:j[0];x&&H(x)},$=b.useCallback(async(m,x)=>{try{return await l(m,x)}catch(j){return console.error("Enhancement failed:",j),m}},[l]),J=b.useCallback(async m=>{try{const x=await s(m);return i(!0,x),x}catch(x){return console.error("Background removal failed:",x),m}},[s,i]),Pe=async()=>{if(!k)return;if(!L&&!p){w(!0);return}if(!L){const x=await J(k);if(S>0){const j=await $(x,S);n(j)}else n(x)}else if(i(!1,null),S>0){const x=await $(k,S);n(x)}else n(k)},je=m=>{c(m),P.current&&clearTimeout(P.current),k&&(P.current=setTimeout(async()=>{const x=L&&D?D:k;if(m===0)n(x);else{const j=await $(x,m);n(j)}},150))},Ee=async m=>{if(f(m),!k)return;const x=await J(k);if(S>0){const j=await $(x,S);n(j)}else n(x)},Ne=()=>{n(null),o(null),i(!1,null),c(0)};return r.jsxs("div",{className:"space-y-4",children:[t.original?r.jsxs("div",{className:"flex flex-col items-center space-y-4",children:[r.jsxs("div",{className:"relative",children:[r.jsx("div",{className:"w-32 h-32 rounded-full overflow-hidden border-4 border-currency-gold shadow-lg",children:r.jsx("img",{src:t.original||"",alt:"Portrait",className:"w-full h-full object-cover",style:{transform:`scale(${t.zoom})`}})}),r.jsx("button",{className:"btn btn-circle btn-xs btn-error absolute -top-1 -right-1",onClick:Ne,children:r.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:r.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),r.jsxs("div",{className:"form-control w-full max-w-xs",children:[r.jsxs("label",{className:"label",children:[r.jsx("span",{className:"label-text",children:h.form.portrait.zoom}),r.jsxs("span",{className:"label-text-alt",children:[Math.round(t.zoom*100),"%"]})]}),r.jsx("input",{type:"range",min:"0.5",max:"2",step:"0.05",value:t.zoom,onChange:m=>a(parseFloat(m.target.value)),className:"range range-primary range-sm"})]}),r.jsxs("div",{className:"form-control w-full max-w-xs",children:[r.jsxs("label",{className:"label",children:[r.jsxs("span",{className:"label-text flex items-center gap-2",children:[e==="de"?"Gravur-Effekt":"Engraving effect",d&&r.jsx("span",{className:"loading loading-spinner loading-xs"})]}),r.jsxs("span",{className:"label-text-alt",children:[Math.round(S*100),"%"]})]}),r.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",value:S,onChange:m=>je(parseFloat(m.target.value)),className:"range range-secondary range-sm",disabled:d||!k})]}),r.jsx("div",{className:"form-control",children:r.jsxs("label",{className:"label cursor-pointer justify-start gap-3",children:[r.jsx("input",{type:"checkbox",className:`toggle toggle-primary ${u?"opacity-50":""}`,checked:L,onChange:Pe,disabled:u||!k}),r.jsxs("span",{className:"label-text flex items-center gap-2",children:[u?r.jsxs(r.Fragment,{children:[r.jsx("span",{className:"loading loading-spinner loading-xs"}),e==="de"?"Hintergrund wird entfernt...":"Removing background..."]}):e==="de"?"Hintergrund entfernen":"Remove background",!p&&r.jsx("span",{className:"badge badge-sm badge-outline",children:"API"})]})]})}),g&&r.jsxs("div",{className:"alert alert-warning text-sm py-2",children:[r.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:r.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"})}),r.jsx("span",{children:g})]})]}):r.jsxs("div",{className:`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${u?"border-primary bg-primary/10 pointer-events-none":y?"border-primary bg-primary/10":"border-base-300 hover:border-primary hover:bg-base-200"}`,onDrop:xe,onDragOver:we,onDragLeave:ye,onClick:Ie,children:[r.jsx("input",{ref:N,type:"file",accept:"image/*",className:"hidden",onChange:ke}),u?r.jsxs("div",{className:"flex flex-col items-center gap-2",children:[r.jsx("span",{className:"loading loading-spinner loading-lg text-primary"}),r.jsx("p",{className:"font-medium",children:e==="de"?"Hintergrund wird entfernt...":"Removing background..."})]}):r.jsxs("div",{className:"flex flex-col items-center gap-2",children:[r.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:r.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"})}),r.jsx("p",{className:"font-medium",children:h.form.portrait.upload}),r.jsx("p",{className:"text-sm text-base-content/60",children:h.form.portrait.dragDrop})]})]}),r.jsx(ce,{isOpen:C,onClose:()=>w(!1),onSubmit:Ee})]})}function qe(){return null}const E=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:_&&_.tagName.toUpperCase()==="SCRIPT"&&_.src||new URL("index.cjs",document.baseURI).href}<"u"&&"/"||"/",de={en:{1:{front:`${E}templates/front_ldpi_en.png`,back:`${E}templates/back_ldpi_en.png`,width:1536,height:1024},5:{front:`${E}templates/front_ldpi_en.png`,back:`${E}templates/back_ldpi_en.png`,width:1536,height:1024},10:{front:`${E}templates/front_ldpi_en.png`,back:`${E}templates/back_ldpi_en.png`,width:1536,height:1024}},de:{1:{front:`${E}templates/front_hdpi_de.webp`,back:`${E}templates/back_hdpi_de.webp`,width:6144,height:3200},5:{front:`${E}templates/front_hdpi_de.webp`,back:`${E}templates/back_hdpi_de.webp`,width:6144,height:3200},10:{front:`${E}templates/front_hdpi_de.webp`,back:`${E}templates/back_hdpi_de.webp`,width:6144,height:3200}}},T={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"}}},R={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 q(e){return e==="de"?R:T}function Y(e,t){return de[e][t]}const K=new Map;async function U(e){return K.has(e)?K.get(e):new Promise((t,n)=>{const a=new Image;a.crossOrigin="anonymous",a.onload=()=>{K.set(e,a),t(a)},a.onerror=n,a.src=e})}function V(e,t,n,a){e.drawImage(t,0,0,n,a)}function ue(e,t,n,a,o,i,c=1){e.save(),e.beginPath(),e.ellipse(n,a,o,i,0,0,Math.PI*2),e.closePath(),e.clip();const l=t.width/t.height,s=o/i,d=o*2,u=i*2;let g,p;l>s?(p=u,g=u*l):(g=d,p=d/l),g*=c,p*=c;const f=n-g/2,h=a-p/2;e.drawImage(t,f,h,g,p),e.restore()}function G(e,t,n,a="#2a3a2a"){e.save(),e.font=`${n.fontSize}px "Times New Roman", serif`,e.textAlign=n.align||"center",e.textBaseline="middle",e.fillStyle=a,n.maxWidth?e.fillText(t,n.x,n.y,n.maxWidth):e.fillText(t,n.x,n.y),e.restore()}function me(e,t,n,a="#2a3a2a"){e.save(),e.font=`${n.fontSize}px "Times New Roman", serif`,e.textAlign=n.align||"center",e.textBaseline="top",e.fillStyle=a;const o=n.maxWidth||400,i=n.lineHeight||n.fontSize*1.4,c=t.split(" "),l=[];let s="";for(const g of c){const p=s?`${s} ${g}`:g;e.measureText(p).width>o&&s?(l.push(s),s=g):s=p}s&&l.push(s);const d=l.length*i;let u=n.y-d/2;for(const g of l)e.fillText(g,n.x,u),u+=i;e.restore()}function he(e,t,n,a,o,i="#2a3a2a"){e.save(),e.font=`${o.fontSize}px "Times New Roman", serif`,e.textAlign=o.align||"center",e.textBaseline="middle",e.fillStyle=i;const c=o.lineHeight||o.fontSize*1.8,l=[t,n,a].filter(Boolean),s=(l.length-1)*c;let d=o.y-s/2;for(const u of l)u&&(e.fillText(u,o.x,d),d+=c);e.restore()}async function Z(e,t,n,a,o,i,c,l=1){const s=e.getContext("2d");if(!s)return;e.width=i,e.height=c,s.clearRect(0,0,i,c);const d=await U(t);if(V(s,d,i,c),n)try{const u=await U(n);ue(s,u,o.portrait.x,o.portrait.y,o.portrait.radiusX,o.portrait.radiusY,l)}catch(u){console.error("Failed to load portrait:",u)}a&&G(s,a,o.namePlate)}async function X(e,t,n,a,o,i,c,l,s){const d=e.getContext("2d");if(!d)return;e.width=l,e.height=s,d.clearRect(0,0,l,s);const u=await U(t);V(d,u,l,s),c.contactInfo&&(n||a||o)&&he(d,n,a,o,c.contactInfo),c.description&&i&&me(d,i,c.description),n&&G(d,n,c.namePlate)}function Ye(){const e=v(w=>w.voucherConfig.language),t=v(w=>w.voucherConfig.hours),n=v(w=>w.voucherConfig.description),a=v(w=>w.personalInfo),o=v(w=>w.portrait),i=v(w=>w.currentSide),c=v(w=>w.flipSide),l=A(e),s=b.useRef(null),d=b.useRef(null),u=b.useRef(null),[g,p]=b.useState(!1),f=Y(e,t),h=q(e),N=o.useEnhanced&&o.enhanced?o.enhanced:o.original,y=W(e,t,n);b.useEffect(()=>{s.current&&Z(s.current,f.front,N,a.name,h.front,f.width,f.height,o.zoom)},[f,N,a.name,h,o.zoom]),b.useEffect(()=>{d.current&&X(d.current,f.back,a.name,a.email,a.phone,y,h.back,f.width,f.height)},[f,a,y,h]);const I=()=>{p(!0),setTimeout(()=>{c(),p(!1)},150)},C=f.width/f.height;return r.jsxs("div",{className:"space-y-4",children:[r.jsxs("div",{className:"flex justify-between items-center",children:[r.jsxs("div",{className:"tabs tabs-boxed bg-base-200",children:[r.jsx("button",{className:`tab ${i==="front"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>i!=="front"&&I(),children:l.preview.front}),r.jsx("button",{className:`tab ${i==="back"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>i!=="back"&&I(),children:l.preview.back})]}),r.jsxs("button",{className:"btn btn-ghost btn-sm",onClick:I,children:[r.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:r.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"})}),l.preview.flip]})]}),r.jsxs("div",{ref:u,className:"relative w-full overflow-hidden shadow-lg",style:{aspectRatio:C},children:[r.jsx("canvas",{ref:s,className:`absolute inset-0 w-full h-full transition-all duration-300 ${i==="front"?g?"opacity-0 scale-95":"opacity-100 scale-100":"opacity-0 scale-95 pointer-events-none"}`}),r.jsx("canvas",{ref:d,className:`absolute inset-0 w-full h-full transition-all duration-300 ${i==="back"?g?"opacity-0 scale-95":"opacity-100 scale-100":"opacity-0 scale-95 pointer-events-none"}`})]})]})}function Ve(){const e=b.useRef(null),t=b.useRef(null);return{frontCanvasRef:e,backCanvasRef:t}}async function pe(e){const{frontTemplateSrc:t,backTemplateSrc:n,templateWidth:a,templateHeight:o,layout:i,portrait:c,portraitZoom:l=1,name:s,email:d,phone:u,description:g}=e,p=document.createElement("canvas"),f=document.createElement("canvas");await Promise.all([Z(p,t,c,s,i.front,a,o,l),X(f,n,s,d,u,g,i.back,a,o)]);const h=new Te({orientation:"landscape",unit:"mm",format:"a4"}),N=297,y=210,I=10,C=a/o;let w=N-I*2,P=w/C;P>y-I*2&&(P=y-I*2,w=P*C);const k=(N-w)/2,D=(y-P)/2,L=p.toDataURL("image/jpeg",.95);h.addImage(L,"JPEG",k,D,w,P),h.addPage();const S=f.toDataURL("image/jpeg",.95);return h.addImage(S,"JPEG",k,D,w,P),h.output("blob")}function ge(e,t){const n=URL.createObjectURL(e),a=document.createElement("a");a.href=n,a.download=t,document.body.appendChild(a),a.click(),document.body.removeChild(a),URL.revokeObjectURL(n)}async function fe(e){const t=await pe(e);ge(t,e.filename)}function Ge(){const e=v(h=>h.voucherConfig.language),t=v(h=>h.voucherConfig.hours),n=v(h=>h.voucherConfig.description),a=v(h=>h.personalInfo),o=v(h=>h.portrait),i=v(h=>h.isExporting),c=v(h=>h.setIsExporting),l=A(e),s=Y(e,t),d=q(e),u=o.useEnhanced&&o.enhanced?o.enhanced:o.original,g=W(e,t,n),p=a.name.trim().length>0&&a.email.trim().length>0&&a.phone.trim().length>0&&o.original!==null,f=async()=>{if(!(!p||i)){c(!0);try{const h=`zeitgutschein-${t}h-${a.name.replace(/\s+/g,"-").toLowerCase()}.pdf`;await fe({frontTemplateSrc:s.front,backTemplateSrc:s.back,templateWidth:s.width,templateHeight:s.height,layout:d,portrait:u,portraitZoom:o.zoom,name:a.name,email:a.email,phone:a.phone,description:g,filename:h})}catch(h){console.error("PDF export failed:",h)}finally{c(!1)}}};return r.jsx("button",{className:`btn btn-primary flex-1 ${i?"loading":""}`,onClick:f,disabled:!p||i,children:i?r.jsxs(r.Fragment,{children:[r.jsx("span",{className:"loading loading-spinner loading-sm"}),l.export.exporting]}):r.jsxs(r.Fragment,{children:[r.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:r.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"})}),l.export.button]})})}function be(){const e=v(a=>a.voucherConfig.language),t=v(a=>a.setLanguage),n=a=>{t(a)};return r.jsxs("div",{className:"join",children:[r.jsx("button",{className:`join-item btn btn-sm ${e==="de"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>n("de"),children:"DE"}),r.jsx("button",{className:`join-item btn btn-sm ${e==="en"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>n("en"),children:"EN"})]})}function Ze(){const e=v(n=>n.voucherConfig.language),t=A(e);return r.jsxs("div",{className:"navbar bg-currency-green text-currency-cream shadow-lg",children:[r.jsx("div",{className:"navbar-start",children:r.jsx("a",{className:"btn btn-ghost text-xl font-currency font-bold",children:t.header.title})}),r.jsx("div",{className:"navbar-center hidden sm:flex",children:r.jsx("span",{className:"text-sm opacity-80",children:t.header.subtitle})}),r.jsx("div",{className:"navbar-end",children:r.jsx(be,{})})]})}const M="/",Xe={id:"time-voucher-classic-de",name:"Zeitgutschein Classic",type:"time-voucher",category:"classic",images:{front:`${M}templates/front_hdpi_de.jpg`,back:`${M}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:R.front.portrait,name:R.front.namePlate},back:{name:R.back.namePlate,contactInfo:R.back.contactInfo,description:R.back.description}},languages:["de"]},Je={id:"time-voucher-classic-en",name:"Time Voucher Classic",type:"time-voucher",category:"classic",images:{front:`${M}templates/front_ldpi_en.png`,back:`${M}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:T.front.portrait,name:T.front.namePlate},back:{name:T.back.namePlate,contactInfo:T.back.contactInfo,description:T.back.description}},languages:["en"]},ae=[Xe,Je],ve={async listTemplates(e){let t=[...ae];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=ae.find(n=>n.id===e);if(!t)throw new Error(`Template not found: ${e}`);return t}};function Qe(e){return e==="de"?"time-voucher-classic-de":"time-voucher-classic-en"}let F=ve;function et(e){F=e}function tt(){return F}async function nt(e){return F.listTemplates(e)}async function at(e){return F.getTemplate(e)}exports.ApiKeyModal=ce;exports.BillPreview=Ye;exports.ExportButton=Ge;exports.Header=Ze;exports.LAYOUT_HDPI=R;exports.LAYOUT_LDPI=T;exports.LanguageToggle=be;exports.PersonalInfoForm=_e;exports.PortraitUpload=We;exports.TEMPLATES=de;exports.VoucherConfig=qe;exports.applyEngravingEffect=re;exports.downloadBlob=ge;exports.drawContactInfo=he;exports.drawMultilineText=me;exports.drawOvalPortrait=ue;exports.drawTemplate=V;exports.drawText=G;exports.enhancePortrait=Ke;exports.exportBillAsPDF=fe;exports.formatDescription=W;exports.generateBillPDF=pe;exports.getApiKey=z;exports.getDefaultTemplateId=Qe;exports.getLayout=q;exports.getRemoveBackgroundEndpoint=Ue;exports.getTemplate=Y;exports.getTemplateById=at;exports.getTemplateProvider=tt;exports.hasApiKey=O;exports.hasCustomEndpoint=Me;exports.listTemplates=nt;exports.loadImage=U;exports.removeBackground=le;exports.renderBackSide=X;exports.renderFrontSide=Z;exports.setApiKey=se;exports.setRemoveBackgroundEndpoint=$e;exports.setTemplateProvider=et;exports.staticTemplateProvider=ve;exports.t=A;exports.useBillCanvasRefs=Ve;exports.useBillStore=v;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),Ce=require("zustand"),Te=require("zustand/middleware"),w=require("react"),Re=require("jspdf");var _=typeof document<"u"?document.currentScript:null;const te={personalInfo:{name:"",email:"",phone:""},voucherConfig:{hours:1,description:"",language:"de"},portrait:{original:null,enhanced:null,useEnhanced:!1,zoom:1,rawImage:null,bgRemovedImage:null,bgRemoved:!1,engravingIntensity:0},currentSide:"front",isEnhancing:!1,isExporting:!1},f=Ce.create()(Te.persist(e=>({...te,setPersonalInfo:t=>e(n=>({personalInfo:{...n.personalInfo,...t}})),setVoucherConfig:t=>e(n=>({voucherConfig:{...n.voucherConfig,...t}})),setPortrait:(t,n=null)=>e(a=>({portrait:{...a.portrait,original:t,enhanced:n,useEnhanced:!1,zoom:a.portrait.original&&t?a.portrait.zoom:1}})),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}})),setPortraitRawImage:t=>e(n=>({portrait:{...n.portrait,rawImage:t}})),setPortraitBgRemoved:(t,n)=>e(a=>({portrait:{...a.portrait,bgRemoved:t,bgRemovedImage:n!==void 0?n:a.portrait.bgRemovedImage}})),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}})),reset:()=>e(te)}),{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,rawImage:null,bgRemovedImage:null,bgRemoved:!1,engravingIntensity:e.portrait.engravingIntensity}})})),Ae={header:{title:"Money Generator",subtitle:"Erstelle deinen persönlichen Zeitgutschein"},form:{personalInfo:{title:"Persönliche Daten",name:"Name",namePlaceholder:"Dein Name",email:"E-Mail",emailPlaceholder:"deine@email.de",phone:"Telefon",phonePlaceholder:"+49 123 456789"},portrait:{title:"Portrait",upload:"Bild hochladen",dragDrop:"oder hierher ziehen",enhance:"Mit AI verbessern",enhancing:"Wird verbessert...",useOriginal:"Original verwenden",useEnhanced:"Verbessertes verwenden",zoom:"Zoom"},voucher:{title:"Gutschein",hours:"Stunden",hourLabel:"Stunde",hoursLabel:"Stunden",description:"Beschreibung",descriptionPlaceholder:"Was kann mit diesem Gutschein eingelöst werden?"}},preview:{front:"Vorderseite",back:"Rückseite",flip:"Umdrehen"},export:{button:"Als PDF herunterladen",exporting:"PDF wird erstellt...",success:"Download gestartet!"},bill:{descriptionText:"Für diesen Schein erhältst du {hours} {hourLabel} meiner Zeit oder ein gleichwertiges Dankeschön"}},Le={header:{title:"Money Generator",subtitle:"Create your personal time voucher"},form:{personalInfo:{title:"Personal Information",name:"Name",namePlaceholder:"Your name",email:"Email",emailPlaceholder:"your@email.com",phone:"Phone",phonePlaceholder:"+1 234 567890"},portrait:{title:"Portrait",upload:"Upload image",dragDrop:"or drag and drop",enhance:"Enhance with AI",enhancing:"Enhancing...",useOriginal:"Use original",useEnhanced:"Use enhanced",zoom:"Zoom"},voucher:{title:"Voucher",hours:"Hours",hourLabel:"hour",hoursLabel:"hours",description:"Description",descriptionPlaceholder:"What can be redeemed with this voucher?"}},preview:{front:"Front",back:"Back",flip:"Flip"},export:{button:"Download as PDF",exporting:"Creating PDF...",success:"Download started!"},bill:{descriptionText:"This voucher entitles you to {hours} {hourLabel} of my time or an equivalent thank you"}},_e={de:Ae,en:Le};function R(e){return _e[e]}function q(e,t,n){if(n&&n.trim())return n;const a=R(e),o=t===1?a.form.voucher.hourLabel:a.form.voucher.hoursLabel;return a.bill.descriptionText.replace("{hours}",t.toString()).replace("{hourLabel}",o)}function De(){const e=f(o=>o.voucherConfig.language),t=f(o=>o.personalInfo),n=f(o=>o.setPersonalInfo),a=R(e);return r.jsxs("div",{className:"space-y-4",children:[r.jsxs("div",{className:"form-control",children:[r.jsx("label",{className:"label",children:r.jsx("span",{className:"label-text font-medium",children:a.form.personalInfo.name})}),r.jsx("input",{type:"text",placeholder:a.form.personalInfo.namePlaceholder,className:"input input-bordered w-full",value:t.name,onChange:o=>n({name:o.target.value})})]}),r.jsxs("div",{className:"form-control",children:[r.jsx("label",{className:"label",children:r.jsx("span",{className:"label-text font-medium",children:a.form.personalInfo.email})}),r.jsx("input",{type:"email",placeholder:a.form.personalInfo.emailPlaceholder,className:"input input-bordered w-full",value:t.email,onChange:o=>n({email:o.target.value})})]}),r.jsxs("div",{className:"form-control",children:[r.jsx("label",{className:"label",children:r.jsx("span",{className:"label-text font-medium",children:a.form.personalInfo.phone})}),r.jsx("input",{type:"tel",placeholder:a.form.personalInfo.phonePlaceholder,className:"input input-bordered w-full",value:t.phone,onChange:o=>n({phone:o.target.value})})]})]})}const ne=1600;function Be(e,t,n){const a=Math.max(e.width,e.height);if(a<=ne){n.width=e.width,n.height=e.height,t.drawImage(e,0,0);return}const o=ne/a;n.width=Math.round(e.width*o),n.height=Math.round(e.height*o),t.drawImage(e,0,0,n.width,n.height)}async function oe(e,t=.5){return new Promise((n,a)=>{const o=new Image;o.onload=()=>{const i=document.createElement("canvas"),c=i.getContext("2d");if(!c){a(new Error("Failed to get canvas context"));return}Be(o,c,i);const l=c.getImageData(0,0,i.width,i.height),s=l.data,d=1+t*.8;for(let u=0;u<s.length;u+=4){const g=s[u],m=s[u+1],b=s[u+2];if(s[u+3]===0)continue;let I=(((.299*g+.587*m+.114*b)/255-.5)*d+.5)*255;I=Math.max(0,Math.min(255,I));const k=Math.min(255,I*.9+25),N=Math.min(255,I*.78+15),x=Math.min(255,I*.55+5);s[u]=Math.round(g*(1-t)+k*t),s[u+1]=Math.round(m*(1-t)+N*t),s[u+2]=Math.round(b*(1-t)+x*t)}c.putImageData(l,0,0),n(i.toDataURL("image/png"))},o.onerror=()=>a(new Error("Failed to load image")),o.src=e})}const Me="https://api.stability.ai/v1/generation",$e="https://api.stability.ai/v2beta/stable-image/edit/remove-background",ie="stability_api_key";let D=null;function Ue(e){D=e}function ze(){return D}function Fe(){return D!==null}const He={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"},ae=[{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 Ke(e,t){const n=e/t;let a=ae[0],o=1/0;for(const i of ae){const c=i.width/i.height,l=Math.abs(n-c);l<o&&(o=l,a=i)}return a}function Oe(e){return new Promise((t,n)=>{const a=new Image;a.onload=()=>{const o=Ke(a.width,a.height),i=document.createElement("canvas");i.width=o.width,i.height=o.height;const c=i.getContext("2d");if(!c){n(new Error("Failed to get canvas context"));return}const l=a.width/a.height,s=o.width/o.height;let d=0,u=0,g=a.width,m=a.height;l>s?(g=a.height*s,d=(a.width-g)/2):(m=a.width/s,u=(a.height-m)/2),c.drawImage(a,d,u,g,m,0,0,o.width,o.height),t(i.toDataURL("image/png"))},a.onerror=()=>n(new Error("Failed to load image")),a.src=e})}function se(e){var c;const t=e.split(","),n=((c=t[0].match(/:(.*?);/))==null?void 0:c[1])||"image/png",a=atob(t[1]),o=a.length,i=new Uint8Array(o);for(let l=0;l<o;l++)i[l]=a.charCodeAt(l);return new Blob([i],{type:n})}function F(){var t;const e=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:_&&_.tagName.toUpperCase()==="SCRIPT"&&_.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(ie):null}function le(e){localStorage.setItem(ie,e)}function W(){return D?!0:F()!==null}async function We(e){const t=F();if(!t)throw new Error("No Stability AI API key configured");const{imageDataUrl:n,style:a,strength:o=.35}=e,i=await Oe(n),c=se(i),l=new FormData;l.append("init_image",c,"portrait.png"),l.append("init_image_mode","IMAGE_STRENGTH"),l.append("image_strength",String(1-o)),l.append("text_prompts[0][text]",He[a]),l.append("text_prompts[0][weight]","1"),l.append("cfg_scale","7"),l.append("samples","1"),l.append("steps","30");const d=await fetch(`${Me}/stable-diffusion-xl-1024-v1-0/image-to-image`,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"application/json"},body:l});if(!d.ok){const g=await d.text();throw console.error("Stability AI error:",g),d.status===401?new Error("Invalid API key"):d.status===402?new Error("Insufficient credits"):d.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${d.status}`)}const u=await d.json();if(!u.artifacts||u.artifacts.length===0)throw new Error("No image generated");return`data:image/png;base64,${u.artifacts[0].base64}`}async function ce(e){if(D){const c=await fetch(D,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({imageDataUrl:e})});if(!c.ok){const s=await c.json().catch(()=>({}));throw new Error(s.error||`API error: ${c.status}`)}return(await c.json()).imageDataUrl}const t=F();if(!t)throw new Error("No Stability AI API key configured");const n=se(e),a=new FormData;a.append("image",n,"image.png"),a.append("output_format","png");const o=await fetch($e,{method:"POST",headers:{Authorization:`Bearer ${t}`,Accept:"image/*"},body:a});if(!o.ok){const c=await o.text();throw console.error("Stability AI remove background error:",c),o.status===401?new Error("Invalid API key"):o.status===402?new Error("Insufficient credits"):o.status===429?new Error("Rate limit exceeded. Please try again later."):new Error(`API error: ${o.status}`)}const i=await o.blob();return new Promise((c,l)=>{const s=new FileReader;s.onload=()=>c(s.result),s.onerror=()=>l(new Error("Failed to read result")),s.readAsDataURL(i)})}function qe(){const[e,t]=w.useState(!1),[n,a]=w.useState(!1),[o,i]=w.useState(null),[c,l]=w.useState(()=>W());w.useEffect(()=>{l(W())},[]);const s=w.useCallback(()=>i(null),[]),d=w.useCallback(m=>{le(m),l(!0),i(null)},[]),u=w.useCallback(async(m,b=.5)=>{t(!0),i(null);try{return await oe(m,b)}catch(p){const S=p instanceof Error?p.message:"Enhancement failed";throw i(S),p}finally{t(!1)}},[]),g=w.useCallback(async m=>{a(!0),i(null);try{return await ce(m)}catch(b){const p=b instanceof Error?b.message:"Background removal failed";throw i(p),b}finally{a(!1)}},[]);return{enhance:u,removeBg:g,isEnhancing:e,isRemovingBg:n,error:o,hasKey:c,setApiKey:d,clearError:s}}function de({isOpen:e,onClose:t,onSubmit:n}){const a=f(d=>d.voucherConfig.language),[o,i]=w.useState("");if(!e)return null;const c=d=>{d.preventDefault(),o.trim()&&(n(o.trim()),i(""),t())},s={de:{title:"Stability AI API Key",description:"Um die AI-Bildverbesserung zu nutzen, benötigst du einen Stability AI API Key. Du kannst ihn auf platform.stability.ai erhalten.",placeholder:"sk-...",submit:"Speichern",cancel:"Abbrechen",hint:"Der Key wird lokal in deinem Browser gespeichert."},en:{title:"Stability AI API Key",description:"To use AI image enhancement, you need a Stability AI API key. You can get one at platform.stability.ai.",placeholder:"sk-...",submit:"Save",cancel:"Cancel",hint:"The key is stored locally in your browser."}}[a];return r.jsxs("dialog",{className:"modal modal-open",children:[r.jsxs("div",{className:"modal-box",children:[r.jsx("h3",{className:"font-bold text-lg",children:s.title}),r.jsx("p",{className:"py-4 text-sm opacity-80",children:s.description}),r.jsxs("form",{onSubmit:c,children:[r.jsxs("div",{className:"form-control",children:[r.jsx("input",{type:"password",placeholder:s.placeholder,className:"input input-bordered w-full",value:o,onChange:d=>i(d.target.value),autoFocus:!0}),r.jsx("label",{className:"label",children:r.jsx("span",{className:"label-text-alt",children:s.hint})})]}),r.jsxs("div",{className:"modal-action",children:[r.jsx("button",{type:"button",className:"btn btn-ghost",onClick:t,children:s.cancel}),r.jsx("button",{type:"submit",className:"btn btn-primary",disabled:!o.trim(),children:s.submit})]})]})]}),r.jsx("form",{method:"dialog",className:"modal-backdrop",children:r.jsx("button",{onClick:t,children:"close"})})]})}function Ye(){const e=f(h=>h.voucherConfig.language),t=f(h=>h.portrait),n=f(h=>h.setPortrait),a=f(h=>h.setPortraitZoom),o=f(h=>h.setPortraitRawImage),i=f(h=>h.setPortraitBgRemoved),c=f(h=>h.setPortraitEngravingIntensity),{enhance:l,removeBg:s,isEnhancing:d,isRemovingBg:u,error:g,hasKey:m,setApiKey:b}=qe(),p=R(e),S=w.useRef(null),[I,k]=w.useState(!1),[N,x]=w.useState(!1),j=w.useRef(null),P=t.rawImage,B=t.bgRemovedImage,A=t.bgRemoved,L=t.engravingIntensity;w.useEffect(()=>{t.original&&!t.rawImage&&o(t.original)},[t.original,t.rawImage,o]),w.useEffect(()=>()=>{j.current&&clearTimeout(j.current)},[]);const K=w.useCallback(async h=>{if(!h.type.startsWith("image/"))return;const v=new FileReader;v.onload=async y=>{var ee;const $=(ee=y.target)==null?void 0:ee.result;o($),n($),i(!1,null),c(0)},v.readAsDataURL(h)},[n,o,i,c]),xe=w.useCallback(h=>{h.preventDefault(),k(!1);const v=h.dataTransfer.files[0];v&&K(v)},[K]),ye=w.useCallback(h=>{h.preventDefault(),k(!0)},[]),Ie=w.useCallback(h=>{h.preventDefault(),k(!1)},[]),ke=()=>{var h;(h=S.current)==null||h.click()},Pe=h=>{var y;const v=(y=h.target.files)==null?void 0:y[0];v&&K(v)},M=w.useCallback(async(h,v)=>{try{return await l(h,v)}catch(y){return console.error("Enhancement failed:",y),h}},[l]),Q=w.useCallback(async h=>{try{const v=await s(h);return i(!0,v),v}catch(v){return console.error("Background removal failed:",v),h}},[s,i]),je=async()=>{if(!P)return;if(!A&&!m){x(!0);return}if(!A){const v=await Q(P),y=f.getState().portrait.engravingIntensity;if(y>0){const $=await M(v,y);n($)}else n(v)}else{i(!1,null);const v=f.getState().portrait.engravingIntensity;if(v>0){const y=await M(P,v);n(y)}else n(P)}},Ee=h=>{c(h),j.current&&clearTimeout(j.current),P&&(j.current=setTimeout(async()=>{const v=A&&B?B:P;if(h===0)n(v);else{const y=await M(v,h);n(y)}},150))},Se=async h=>{if(b(h),!P)return;const v=await Q(P);if(L>0){const y=await M(v,L);n(y)}else n(v)},Ne=()=>{n(null),o(null),i(!1,null),c(0)};return r.jsxs("div",{className:"space-y-4",children:[t.original?r.jsxs("div",{className:"flex flex-col items-center space-y-4",children:[r.jsxs("div",{className:"relative",children:[r.jsx("div",{className:"w-32 h-32 rounded-full overflow-hidden border-4 border-currency-gold shadow-lg",children:r.jsx("img",{src:t.original||"",alt:"Portrait",className:"w-full h-full object-cover",style:{transform:`scale(${t.zoom})`}})}),r.jsx("button",{className:"btn btn-circle btn-xs btn-error absolute -top-1 -right-1",onClick:Ne,children:r.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:r.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"})})})]}),r.jsxs("div",{className:"form-control w-full max-w-xs",children:[r.jsxs("label",{className:"label",children:[r.jsx("span",{className:"label-text",children:p.form.portrait.zoom}),r.jsxs("span",{className:"label-text-alt",children:[Math.round(t.zoom*100),"%"]})]}),r.jsx("input",{type:"range",min:"0.5",max:"2",step:"0.05",value:t.zoom,onChange:h=>a(parseFloat(h.target.value)),className:"range range-primary range-sm"})]}),r.jsxs("div",{className:"form-control w-full max-w-xs",children:[r.jsxs("label",{className:"label",children:[r.jsxs("span",{className:"label-text flex items-center gap-2",children:[e==="de"?"Sepia-Effekt":"Sepia effect",d&&r.jsx("span",{className:"loading loading-spinner loading-xs"})]}),r.jsxs("span",{className:"label-text-alt",children:[Math.round(L*100),"%"]})]}),r.jsx("input",{type:"range",min:"0",max:"1",step:"0.05",value:L,onChange:h=>Ee(parseFloat(h.target.value)),className:"range range-secondary range-sm",disabled:d||!P})]}),r.jsx("div",{className:"form-control",children:r.jsxs("label",{className:"label cursor-pointer justify-start gap-3",children:[r.jsx("input",{type:"checkbox",className:`toggle toggle-primary ${u?"opacity-50":""}`,checked:A,onChange:je,disabled:u||!P}),r.jsxs("span",{className:"label-text flex items-center gap-2",children:[u?r.jsxs(r.Fragment,{children:[r.jsx("span",{className:"loading loading-spinner loading-xs"}),e==="de"?"Hintergrund wird entfernt...":"Removing background..."]}):e==="de"?"Hintergrund entfernen":"Remove background",!m&&r.jsx("span",{className:"badge badge-sm badge-outline",children:"API"})]})]})}),g&&r.jsxs("div",{className:"alert alert-warning text-sm py-2",children:[r.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:r.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"})}),r.jsx("span",{children:g})]})]}):r.jsxs("div",{className:`border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${u?"border-primary bg-primary/10 pointer-events-none":I?"border-primary bg-primary/10":"border-base-300 hover:border-primary hover:bg-base-200"}`,onDrop:xe,onDragOver:ye,onDragLeave:Ie,onClick:ke,children:[r.jsx("input",{ref:S,type:"file",accept:"image/*",className:"hidden",onChange:Pe}),u?r.jsxs("div",{className:"flex flex-col items-center gap-2",children:[r.jsx("span",{className:"loading loading-spinner loading-lg text-primary"}),r.jsx("p",{className:"font-medium",children:e==="de"?"Hintergrund wird entfernt...":"Removing background..."})]}):r.jsxs("div",{className:"flex flex-col items-center gap-2",children:[r.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:r.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"})}),r.jsx("p",{className:"font-medium",children:p.form.portrait.upload}),r.jsx("p",{className:"text-sm text-base-content/60",children:p.form.portrait.dragDrop})]})]}),r.jsx(de,{isOpen:N,onClose:()=>x(!1),onSubmit:Se})]})}function Ve(){return null}const E=typeof{url:typeof document>"u"?require("url").pathToFileURL(__filename).href:_&&_.tagName.toUpperCase()==="SCRIPT"&&_.src||new URL("index.cjs",document.baseURI).href}<"u"&&"/"||"/",ue={en:{1:{front:`${E}templates/front_ldpi_en.png`,back:`${E}templates/back_ldpi_en.png`,width:1536,height:1024},5:{front:`${E}templates/front_ldpi_en.png`,back:`${E}templates/back_ldpi_en.png`,width:1536,height:1024},10:{front:`${E}templates/front_ldpi_en.png`,back:`${E}templates/back_ldpi_en.png`,width:1536,height:1024}},de:{1:{front:`${E}templates/front_hdpi_de.webp`,back:`${E}templates/back_hdpi_de.webp`,width:6144,height:3200},5:{front:`${E}templates/front_hdpi_de.webp`,back:`${E}templates/back_hdpi_de.webp`,width:6144,height:3200},10:{front:`${E}templates/front_hdpi_de.webp`,back:`${E}templates/back_hdpi_de.webp`,width:6144,height:3200}}},C={front:{portrait:{x:768,y:490,radiusX:236,radiusY:258},namePlate:{x:768,y:848,fontSize:36,maxWidth:380,align:"center"}},back:{portrait:{x:0,y:0,radiusX:0,radiusY:0},namePlate:{x:768,y:832,fontSize:36,maxWidth:380,align:"center"},contactInfo:{x:380,y:500,fontSize:38,lineHeight:55,align:"center"},description:{x:1150,y:500,fontSize:38,maxWidth:480,lineHeight:42,align:"center"}}},T={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 Y(e){return e==="de"?T:C}function V(e,t){return ue[e][t]}const O=new Map;async function U(e){return O.has(e)?O.get(e):new Promise((t,n)=>{const a=new Image;a.crossOrigin="anonymous",a.onload=()=>{O.set(e,a),t(a)},a.onerror=n,a.src=e})}function G(e,t,n,a){e.drawImage(t,0,0,n,a)}function he(e,t,n,a,o,i,c=1){e.save(),e.beginPath(),e.ellipse(n,a,o,i,0,0,Math.PI*2),e.closePath(),e.clip();const l=t.width/t.height,s=o/i,d=o*2,u=i*2;let g,m;l>s?(m=u,g=u*l):(g=d,m=d/l),g*=c,m*=c;const b=n-g/2,p=a-m/2;e.drawImage(t,b,p,g,m),e.restore()}function Z(e,t,n,a="#2a3a2a"){e.save(),e.font=`${n.fontSize}px "Times New Roman", serif`,e.textAlign=n.align||"center",e.textBaseline="middle",e.fillStyle=a,n.maxWidth?e.fillText(t,n.x,n.y,n.maxWidth):e.fillText(t,n.x,n.y),e.restore()}function pe(e,t,n,a="#2a3a2a"){e.save(),e.font=`${n.fontSize}px "Times New Roman", serif`,e.textAlign=n.align||"center",e.textBaseline="top",e.fillStyle=a;const o=n.maxWidth||400,i=n.lineHeight||n.fontSize*1.4,c=t.split(" "),l=[];let s="";for(const g of c){const m=s?`${s} ${g}`:g;e.measureText(m).width>o&&s?(l.push(s),s=g):s=m}s&&l.push(s);const d=l.length*i;let u=n.y-d/2;for(const g of l)e.fillText(g,n.x,u),u+=i;e.restore()}function me(e,t,n,a,o,i="#2a3a2a"){e.save(),e.font=`${o.fontSize}px "Times New Roman", serif`,e.textAlign=o.align||"center",e.textBaseline="middle",e.fillStyle=i;const c=o.lineHeight||o.fontSize*1.8,l=[t,n,a].filter(Boolean),s=(l.length-1)*c;let d=o.y-s/2;for(const u of l)u&&(e.fillText(u,o.x,d),d+=c);e.restore()}async function X(e,t,n,a,o,i,c,l=1){const s=e.getContext("2d");if(!s)return;e.width=i,e.height=c,s.clearRect(0,0,i,c);const d=await U(t);if(G(s,d,i,c),n)try{const u=await U(n);he(s,u,o.portrait.x,o.portrait.y,o.portrait.radiusX,o.portrait.radiusY,l)}catch(u){console.error("Failed to load portrait:",u)}a&&Z(s,a,o.namePlate)}async function J(e,t,n,a,o,i,c,l,s){const d=e.getContext("2d");if(!d)return;e.width=l,e.height=s,d.clearRect(0,0,l,s);const u=await U(t);G(d,u,l,s),c.contactInfo&&(n||a||o)&&me(d,n,a,o,c.contactInfo),c.description&&i&&pe(d,i,c.description),n&&Z(d,n,c.namePlate)}function Ge(){const e=f(x=>x.voucherConfig.language),t=f(x=>x.voucherConfig.hours),n=f(x=>x.voucherConfig.description),a=f(x=>x.personalInfo),o=f(x=>x.portrait),i=f(x=>x.currentSide),c=f(x=>x.flipSide),l=R(e),s=w.useRef(null),d=w.useRef(null),u=w.useRef(null),[g,m]=w.useState(!1),b=V(e,t),p=Y(e),S=o.useEnhanced&&o.enhanced?o.enhanced:o.original,I=q(e,t,n);w.useEffect(()=>{s.current&&X(s.current,b.front,S,a.name,p.front,b.width,b.height,o.zoom)},[b,S,a.name,p,o.zoom]),w.useEffect(()=>{d.current&&J(d.current,b.back,a.name,a.email,a.phone,I,p.back,b.width,b.height)},[b,a,I,p]);const k=()=>{m(!0),setTimeout(()=>{c(),m(!1)},150)},N=b.width/b.height;return r.jsxs("div",{className:"space-y-4",children:[r.jsxs("div",{className:"flex justify-between items-center",children:[r.jsxs("div",{className:"tabs tabs-boxed bg-base-200",children:[r.jsx("button",{className:`tab ${i==="front"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>i!=="front"&&k(),children:l.preview.front}),r.jsx("button",{className:`tab ${i==="back"?"tab-active bg-primary text-primary-content font-semibold":""}`,onClick:()=>i!=="back"&&k(),children:l.preview.back})]}),r.jsxs("button",{className:"btn btn-ghost btn-sm",onClick:k,children:[r.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:r.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"})}),l.preview.flip]})]}),r.jsxs("div",{ref:u,className:"relative w-full overflow-hidden shadow-lg",style:{aspectRatio:N},children:[r.jsx("canvas",{ref:s,className:`absolute inset-0 w-full h-full transition-all duration-300 ${i==="front"?g?"opacity-0 scale-95":"opacity-100 scale-100":"opacity-0 scale-95 pointer-events-none"}`}),r.jsx("canvas",{ref:d,className:`absolute inset-0 w-full h-full transition-all duration-300 ${i==="back"?g?"opacity-0 scale-95":"opacity-100 scale-100":"opacity-0 scale-95 pointer-events-none"}`})]})]})}function Ze(){const e=w.useRef(null),t=w.useRef(null);return{frontCanvasRef:e,backCanvasRef:t}}async function ge(e){const{frontTemplateSrc:t,backTemplateSrc:n,templateWidth:a,templateHeight:o,layout:i,portrait:c,portraitZoom:l=1,name:s,email:d,phone:u,description:g}=e,m=document.createElement("canvas"),b=document.createElement("canvas");await Promise.all([X(m,t,c,s,i.front,a,o,l),J(b,n,s,d,u,g,i.back,a,o)]);const p=new Re({orientation:"landscape",unit:"mm",format:"a4"}),S=297,I=210,k=10,N=a/o;let x=S-k*2,j=x/N;j>I-k*2&&(j=I-k*2,x=j*N);const P=(S-x)/2,B=(I-j)/2,A=m.toDataURL("image/jpeg",.95);p.addImage(A,"JPEG",P,B,x,j),p.addPage();const L=b.toDataURL("image/jpeg",.95);return p.addImage(L,"JPEG",P,B,x,j),p.output("blob")}function fe(e,t){const n=URL.createObjectURL(e),a=document.createElement("a");a.href=n,a.download=t,document.body.appendChild(a),a.click(),document.body.removeChild(a),URL.revokeObjectURL(n)}async function be(e){const t=await ge(e);fe(t,e.filename)}function Xe(){const e=f(p=>p.voucherConfig.language),t=f(p=>p.voucherConfig.hours),n=f(p=>p.voucherConfig.description),a=f(p=>p.personalInfo),o=f(p=>p.portrait),i=f(p=>p.isExporting),c=f(p=>p.setIsExporting),l=R(e),s=V(e,t),d=Y(e),u=o.useEnhanced&&o.enhanced?o.enhanced:o.original,g=q(e,t,n),m=a.name.trim().length>0&&a.email.trim().length>0&&a.phone.trim().length>0&&o.original!==null,b=async()=>{if(!(!m||i)){c(!0);try{const p=`zeitgutschein-${t}h-${a.name.replace(/\s+/g,"-").toLowerCase()}.pdf`;await be({frontTemplateSrc:s.front,backTemplateSrc:s.back,templateWidth:s.width,templateHeight:s.height,layout:d,portrait:u,portraitZoom:o.zoom,name:a.name,email:a.email,phone:a.phone,description:g,filename:p})}catch(p){console.error("PDF export failed:",p)}finally{c(!1)}}};return r.jsx("button",{className:`btn btn-primary flex-1 ${i?"loading":""}`,onClick:b,disabled:!m||i,children:i?r.jsxs(r.Fragment,{children:[r.jsx("span",{className:"loading loading-spinner loading-sm"}),l.export.exporting]}):r.jsxs(r.Fragment,{children:[r.jsx("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:r.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"})}),l.export.button]})})}function we(){const e=f(a=>a.voucherConfig.language),t=f(a=>a.setLanguage),n=a=>{t(a)};return r.jsxs("div",{className:"join",children:[r.jsx("button",{className:`join-item btn btn-sm ${e==="de"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>n("de"),children:"DE"}),r.jsx("button",{className:`join-item btn btn-sm ${e==="en"?"btn-active btn-primary":"btn-ghost"}`,onClick:()=>n("en"),children:"EN"})]})}function Je(){const e=f(n=>n.voucherConfig.language),t=R(e);return r.jsxs("div",{className:"navbar bg-currency-green text-currency-cream shadow-lg",children:[r.jsx("div",{className:"navbar-start",children:r.jsx("a",{className:"btn btn-ghost text-xl font-currency font-bold",children:t.header.title})}),r.jsx("div",{className:"navbar-center hidden sm:flex",children:r.jsx("span",{className:"text-sm opacity-80",children:t.header.subtitle})}),r.jsx("div",{className:"navbar-end",children:r.jsx(we,{})})]})}const z="/",Qe={id:"time-voucher-classic-de",name:"Zeitgutschein Classic",type:"time-voucher",category:"classic",images:{front:`${z}templates/front_hdpi_de.jpg`,back:`${z}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:T.front.portrait,name:T.front.namePlate},back:{name:T.back.namePlate,contactInfo:T.back.contactInfo,description:T.back.description}},languages:["de"]},et={id:"time-voucher-classic-en",name:"Time Voucher Classic",type:"time-voucher",category:"classic",images:{front:`${z}templates/front_ldpi_en.png`,back:`${z}templates/back_ldpi_en.png`,width:1536,height:1024},fields:[{id:"name",type:"text",label:{de:"Name",en:"Name"},required:!0,validation:{minLength:1,maxLength:50}},{id:"hours",type:"select",label:{de:"Stunden",en:"Hours"},required:!0,options:["1","5","10"]},{id:"portrait",type:"image",label:{de:"Portrait",en:"Portrait"},required:!1},{id:"email",type:"text",label:{de:"E-Mail",en:"Email"},required:!1},{id:"phone",type:"text",label:{de:"Telefon",en:"Phone"},required:!1},{id:"description",type:"textarea",label:{de:"Beschreibung",en:"Description"},required:!1,validation:{maxLength:200}}],layout:{front:{portrait:C.front.portrait,name:C.front.namePlate},back:{name:C.back.namePlate,contactInfo:C.back.contactInfo,description:C.back.description}},languages:["en"]},re=[Qe,et],ve={async listTemplates(e){let t=[...re];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=re.find(n=>n.id===e);if(!t)throw new Error(`Template not found: ${e}`);return t}};function tt(e){return e==="de"?"time-voucher-classic-de":"time-voucher-classic-en"}let H=ve;function nt(e){H=e}function at(){return H}async function rt(e){return H.listTemplates(e)}async function ot(e){return H.getTemplate(e)}exports.ApiKeyModal=de;exports.BillPreview=Ge;exports.ExportButton=Xe;exports.Header=Je;exports.LAYOUT_HDPI=T;exports.LAYOUT_LDPI=C;exports.LanguageToggle=we;exports.PersonalInfoForm=De;exports.PortraitUpload=Ye;exports.TEMPLATES=ue;exports.VoucherConfig=Ve;exports.applyEngravingEffect=oe;exports.downloadBlob=fe;exports.drawContactInfo=me;exports.drawMultilineText=pe;exports.drawOvalPortrait=he;exports.drawTemplate=G;exports.drawText=Z;exports.enhancePortrait=We;exports.exportBillAsPDF=be;exports.formatDescription=q;exports.generateBillPDF=ge;exports.getApiKey=F;exports.getDefaultTemplateId=tt;exports.getLayout=Y;exports.getRemoveBackgroundEndpoint=ze;exports.getTemplate=V;exports.getTemplateById=ot;exports.getTemplateProvider=at;exports.hasApiKey=W;exports.hasCustomEndpoint=Fe;exports.listTemplates=rt;exports.loadImage=U;exports.removeBackground=ce;exports.renderBackSide=J;exports.renderFrontSide=X;exports.setApiKey=le;exports.setRemoveBackgroundEndpoint=Ue;exports.setTemplateProvider=nt;exports.staticTemplateProvider=ve;exports.t=R;exports.useBillCanvasRefs=Ze;exports.useBillStore=f;
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { jsxs as u, jsx as s, Fragment as O } from "react/jsx-runtime";
2
- import { create as we } from "zustand";
3
- import { persist as ye } from "zustand/middleware";
4
- import { useState as A, useEffect as H, useCallback as T, useRef as L } from "react";
1
+ import { jsxs as u, jsx as s, Fragment as Y } from "react/jsx-runtime";
2
+ import { create as ye } from "zustand";
3
+ import { persist as Ie } from "zustand/middleware";
4
+ import { useState as T, useEffect as H, useCallback as C, useRef as A } from "react";
5
5
  import xe from "jspdf";
6
6
  const X = {
7
7
  personalInfo: {
@@ -27,8 +27,8 @@ const X = {
27
27
  currentSide: "front",
28
28
  isEnhancing: !1,
29
29
  isExporting: !1
30
- }, v = we()(
31
- ye(
30
+ }, b = ye()(
31
+ Ie(
32
32
  (e) => ({
33
33
  ...X,
34
34
  setPersonalInfo: (t) => e((n) => ({
@@ -123,7 +123,7 @@ const X = {
123
123
  })
124
124
  }
125
125
  )
126
- ), Ie = {
126
+ ), ke = {
127
127
  header: {
128
128
  title: "Money Generator",
129
129
  subtitle: "Erstelle deinen persönlichen Zeitgutschein"
@@ -170,7 +170,7 @@ const X = {
170
170
  bill: {
171
171
  descriptionText: "Für diesen Schein erhältst du {hours} {hourLabel} meiner Zeit oder ein gleichwertiges Dankeschön"
172
172
  }
173
- }, ke = {
173
+ }, Ee = {
174
174
  header: {
175
175
  title: "Money Generator",
176
176
  subtitle: "Create your personal time voucher"
@@ -217,18 +217,18 @@ const X = {
217
217
  bill: {
218
218
  descriptionText: "This voucher entitles you to {hours} {hourLabel} of my time or an equivalent thank you"
219
219
  }
220
- }, Ee = { de: Ie, en: ke };
221
- function z(e) {
222
- return Ee[e];
220
+ }, Pe = { de: ke, en: Ee };
221
+ function M(e) {
222
+ return Pe[e];
223
223
  }
224
- function te(e, t, n) {
224
+ function ne(e, t, n) {
225
225
  if (n && n.trim())
226
226
  return n;
227
- const a = z(e), r = t === 1 ? a.form.voucher.hourLabel : a.form.voucher.hoursLabel;
227
+ const a = M(e), r = t === 1 ? a.form.voucher.hourLabel : a.form.voucher.hoursLabel;
228
228
  return a.bill.descriptionText.replace("{hours}", t.toString()).replace("{hourLabel}", r);
229
229
  }
230
- function Xe() {
231
- const e = v((r) => r.voucherConfig.language), t = v((r) => r.personalInfo), n = v((r) => r.setPersonalInfo), a = z(e);
230
+ function Qe() {
231
+ const e = b((r) => r.voucherConfig.language), t = b((r) => r.personalInfo), n = b((r) => r.setPersonalInfo), a = M(e);
232
232
  return /* @__PURE__ */ u("div", { className: "space-y-4", children: [
233
233
  /* @__PURE__ */ u("div", { className: "form-control", children: [
234
234
  /* @__PURE__ */ s("label", { className: "label", children: /* @__PURE__ */ s("span", { className: "label-text font-medium", children: a.form.personalInfo.name }) }),
@@ -271,7 +271,17 @@ function Xe() {
271
271
  ] })
272
272
  ] });
273
273
  }
274
- async function Pe(e, t = 0.5) {
274
+ const J = 1600;
275
+ function Ne(e, t, n) {
276
+ const a = Math.max(e.width, e.height);
277
+ if (a <= J) {
278
+ n.width = e.width, n.height = e.height, t.drawImage(e, 0, 0);
279
+ return;
280
+ }
281
+ const r = J / a;
282
+ n.width = Math.round(e.width * r), n.height = Math.round(e.height * r), t.drawImage(e, 0, 0, n.width, n.height);
283
+ }
284
+ async function Se(e, t = 0.5) {
275
285
  return new Promise((n, a) => {
276
286
  const r = new Image();
277
287
  r.onload = () => {
@@ -280,36 +290,36 @@ async function Pe(e, t = 0.5) {
280
290
  a(new Error("Failed to get canvas context"));
281
291
  return;
282
292
  }
283
- o.width = r.width, o.height = r.height, c.drawImage(r, 0, 0);
293
+ Ne(r, c, o);
284
294
  const l = c.getImageData(0, 0, o.width, o.height), i = l.data, d = 1 + t * 0.8;
285
295
  for (let h = 0; h < i.length; h += 4) {
286
- const f = i[h], g = i[h + 1], b = i[h + 2];
296
+ const f = i[h], g = i[h + 1], w = i[h + 2];
287
297
  if (i[h + 3] === 0) continue;
288
- let x = (((0.299 * f + 0.587 * g + 0.114 * b) / 255 - 0.5) * d + 0.5) * 255;
298
+ let x = (((0.299 * f + 0.587 * g + 0.114 * w) / 255 - 0.5) * d + 0.5) * 255;
289
299
  x = Math.max(0, Math.min(255, x));
290
- const I = Math.min(255, x * 0.9 + 25), R = Math.min(255, x * 0.78 + 15), y = Math.min(255, x * 0.55 + 5);
291
- i[h] = Math.round(f * (1 - t) + I * t), i[h + 1] = Math.round(g * (1 - t) + R * t), i[h + 2] = Math.round(b * (1 - t) + y * t);
300
+ const k = Math.min(255, x * 0.9 + 25), R = Math.min(255, x * 0.78 + 15), y = Math.min(255, x * 0.55 + 5);
301
+ i[h] = Math.round(f * (1 - t) + k * t), i[h + 1] = Math.round(g * (1 - t) + R * t), i[h + 2] = Math.round(w * (1 - t) + y * t);
292
302
  }
293
303
  c.putImageData(l, 0, 0), n(o.toDataURL("image/png"));
294
304
  }, r.onerror = () => a(new Error("Failed to load image")), r.src = e;
295
305
  });
296
306
  }
297
- const Ne = "https://api.stability.ai/v1/generation", Se = "https://api.stability.ai/v2beta/stable-image/edit/remove-background", ne = "stability_api_key";
307
+ const Ce = "https://api.stability.ai/v1/generation", Re = "https://api.stability.ai/v2beta/stable-image/edit/remove-background", ae = "stability_api_key";
298
308
  let $ = null;
299
- function Je(e) {
309
+ function et(e) {
300
310
  $ = e;
301
311
  }
302
- function Qe() {
312
+ function tt() {
303
313
  return $;
304
314
  }
305
- function et() {
315
+ function nt() {
306
316
  return $ !== null;
307
317
  }
308
- const Ce = {
318
+ const Te = {
309
319
  vintage: "portrait in the style of vintage currency engraving, fine line work, crosshatching, sepia tones, detailed stippling, classic bank note portrait style",
310
320
  engraved: "portrait as detailed intaglio engraving, currency bill style, fine parallel lines, high contrast, official government portrait",
311
321
  currency: "portrait rendered as US dollar bill engraving, official currency portrait style, green tint, fine line engraving technique"
312
- }, J = [
322
+ }, Q = [
313
323
  { width: 1024, height: 1024 },
314
324
  { width: 1152, height: 896 },
315
325
  { width: 1216, height: 832 },
@@ -320,20 +330,20 @@ const Ce = {
320
330
  { width: 832, height: 1216 },
321
331
  { width: 896, height: 1152 }
322
332
  ];
323
- function Te(e, t) {
333
+ function Ae(e, t) {
324
334
  const n = e / t;
325
- let a = J[0], r = 1 / 0;
326
- for (const o of J) {
335
+ let a = Q[0], r = 1 / 0;
336
+ for (const o of Q) {
327
337
  const c = o.width / o.height, l = Math.abs(n - c);
328
338
  l < r && (r = l, a = o);
329
339
  }
330
340
  return a;
331
341
  }
332
- function Re(e) {
342
+ function Le(e) {
333
343
  return new Promise((t, n) => {
334
344
  const a = new Image();
335
345
  a.onload = () => {
336
- const r = Te(a.width, a.height), o = document.createElement("canvas");
346
+ const r = Ae(a.width, a.height), o = document.createElement("canvas");
337
347
  o.width = r.width, o.height = r.height;
338
348
  const c = o.getContext("2d");
339
349
  if (!c) {
@@ -346,31 +356,31 @@ function Re(e) {
346
356
  }, a.onerror = () => n(new Error("Failed to load image")), a.src = e;
347
357
  });
348
358
  }
349
- function ae(e) {
359
+ function re(e) {
350
360
  var c;
351
361
  const t = e.split(","), n = ((c = t[0].match(/:(.*?);/)) == null ? void 0 : c[1]) || "image/png", a = atob(t[1]), r = a.length, o = new Uint8Array(r);
352
362
  for (let l = 0; l < r; l++)
353
363
  o[l] = a.charCodeAt(l);
354
364
  return new Blob([o], { type: n });
355
365
  }
356
- function q() {
366
+ function V() {
357
367
  var t;
358
368
  const e = typeof import.meta < "u" && "sk-7mEKklrqaltdtgbX0VoZbkA8E1cl939Spn75jSIYRvp1BW0b" || typeof process < "u" && ((t = process.env) == null ? void 0 : t.NEXT_PUBLIC_STABILITY_API_KEY);
359
- return e && e !== "your-api-key-here" ? e : typeof localStorage < "u" ? localStorage.getItem(ne) : null;
369
+ return e && e !== "your-api-key-here" ? e : typeof localStorage < "u" ? localStorage.getItem(ae) : null;
360
370
  }
361
- function Ae(e) {
362
- localStorage.setItem(ne, e);
371
+ function _e(e) {
372
+ localStorage.setItem(ae, e);
363
373
  }
364
- function Q() {
365
- return $ ? !0 : q() !== null;
374
+ function ee() {
375
+ return $ ? !0 : V() !== null;
366
376
  }
367
- async function tt(e) {
368
- const t = q();
377
+ async function at(e) {
378
+ const t = V();
369
379
  if (!t)
370
380
  throw new Error("No Stability AI API key configured");
371
- const { imageDataUrl: n, style: a, strength: r = 0.35 } = e, o = await Re(n), c = ae(o), l = new FormData();
372
- l.append("init_image", c, "portrait.png"), l.append("init_image_mode", "IMAGE_STRENGTH"), l.append("image_strength", String(1 - r)), l.append("text_prompts[0][text]", Ce[a]), l.append("text_prompts[0][weight]", "1"), l.append("cfg_scale", "7"), l.append("samples", "1"), l.append("steps", "30");
373
- const d = await fetch(`${Ne}/stable-diffusion-xl-1024-v1-0/image-to-image`, {
381
+ const { imageDataUrl: n, style: a, strength: r = 0.35 } = e, o = await Le(n), c = re(o), l = new FormData();
382
+ l.append("init_image", c, "portrait.png"), l.append("init_image_mode", "IMAGE_STRENGTH"), l.append("image_strength", String(1 - r)), l.append("text_prompts[0][text]", Te[a]), l.append("text_prompts[0][weight]", "1"), l.append("cfg_scale", "7"), l.append("samples", "1"), l.append("steps", "30");
383
+ const d = await fetch(`${Ce}/stable-diffusion-xl-1024-v1-0/image-to-image`, {
374
384
  method: "POST",
375
385
  headers: {
376
386
  Authorization: `Bearer ${t}`,
@@ -387,7 +397,7 @@ async function tt(e) {
387
397
  throw new Error("No image generated");
388
398
  return `data:image/png;base64,${h.artifacts[0].base64}`;
389
399
  }
390
- async function Le(e) {
400
+ async function De(e) {
391
401
  if ($) {
392
402
  const c = await fetch($, {
393
403
  method: "POST",
@@ -402,12 +412,12 @@ async function Le(e) {
402
412
  }
403
413
  return (await c.json()).imageDataUrl;
404
414
  }
405
- const t = q();
415
+ const t = V();
406
416
  if (!t)
407
417
  throw new Error("No Stability AI API key configured");
408
- const n = ae(e), a = new FormData();
418
+ const n = re(e), a = new FormData();
409
419
  a.append("image", n, "image.png"), a.append("output_format", "png");
410
- const r = await fetch(Se, {
420
+ const r = await fetch(Re, {
411
421
  method: "POST",
412
422
  headers: {
413
423
  Authorization: `Bearer ${t}`,
@@ -425,18 +435,18 @@ async function Le(e) {
425
435
  i.onload = () => c(i.result), i.onerror = () => l(new Error("Failed to read result")), i.readAsDataURL(o);
426
436
  });
427
437
  }
428
- function De() {
429
- const [e, t] = A(!1), [n, a] = A(!1), [r, o] = A(null), [c, l] = A(() => Q());
438
+ function Be() {
439
+ const [e, t] = T(!1), [n, a] = T(!1), [r, o] = T(null), [c, l] = T(() => ee());
430
440
  H(() => {
431
- l(Q());
441
+ l(ee());
432
442
  }, []);
433
- const i = T(() => o(null), []), d = T((g) => {
434
- Ae(g), l(!0), o(null);
435
- }, []), h = T(
436
- async (g, b = 0.5) => {
443
+ const i = C(() => o(null), []), d = C((g) => {
444
+ _e(g), l(!0), o(null);
445
+ }, []), h = C(
446
+ async (g, w = 0.5) => {
437
447
  t(!0), o(null);
438
448
  try {
439
- return await Pe(g, b);
449
+ return await Se(g, w);
440
450
  } catch (p) {
441
451
  const S = p instanceof Error ? p.message : "Enhancement failed";
442
452
  throw o(S), p;
@@ -445,14 +455,14 @@ function De() {
445
455
  }
446
456
  },
447
457
  []
448
- ), f = T(
458
+ ), f = C(
449
459
  async (g) => {
450
460
  a(!0), o(null);
451
461
  try {
452
- return await Le(g);
453
- } catch (b) {
454
- const p = b instanceof Error ? b.message : "Background removal failed";
455
- throw o(p), b;
462
+ return await De(g);
463
+ } catch (w) {
464
+ const p = w instanceof Error ? w.message : "Background removal failed";
465
+ throw o(p), w;
456
466
  } finally {
457
467
  a(!1);
458
468
  }
@@ -470,8 +480,8 @@ function De() {
470
480
  clearError: i
471
481
  };
472
482
  }
473
- function _e({ isOpen: e, onClose: t, onSubmit: n }) {
474
- const a = v((d) => d.voucherConfig.language), [r, o] = A("");
483
+ function $e({ isOpen: e, onClose: t, onSubmit: n }) {
484
+ const a = b((d) => d.voucherConfig.language), [r, o] = T("");
475
485
  if (!e) return null;
476
486
  const c = (d) => {
477
487
  d.preventDefault(), r.trim() && (n(r.trim()), o(""), t());
@@ -521,92 +531,96 @@ function _e({ isOpen: e, onClose: t, onSubmit: n }) {
521
531
  /* @__PURE__ */ s("form", { method: "dialog", className: "modal-backdrop", children: /* @__PURE__ */ s("button", { onClick: t, children: "close" }) })
522
532
  ] });
523
533
  }
524
- function nt() {
525
- const e = v((m) => m.voucherConfig.language), t = v((m) => m.portrait), n = v((m) => m.setPortrait), a = v((m) => m.setPortraitZoom), r = v((m) => m.setPortraitRawImage), o = v((m) => m.setPortraitBgRemoved), c = v((m) => m.setPortraitEngravingIntensity), { enhance: l, removeBg: i, isEnhancing: d, isRemovingBg: h, error: f, hasKey: g, setApiKey: b } = De(), p = z(e), S = L(null), [x, I] = A(!1), [R, y] = A(!1), E = L(null), k = t.rawImage, M = t.bgRemovedImage, D = t.bgRemoved, C = t.engravingIntensity;
534
+ function rt() {
535
+ const e = b((m) => m.voucherConfig.language), t = b((m) => m.portrait), n = b((m) => m.setPortrait), a = b((m) => m.setPortraitZoom), r = b((m) => m.setPortraitRawImage), o = b((m) => m.setPortraitBgRemoved), c = b((m) => m.setPortraitEngravingIntensity), { enhance: l, removeBg: i, isEnhancing: d, isRemovingBg: h, error: f, hasKey: g, setApiKey: w } = Be(), p = M(e), S = A(null), [x, k] = T(!1), [R, y] = T(!1), P = A(null), E = t.rawImage, z = t.bgRemovedImage, L = t.bgRemoved, _ = t.engravingIntensity;
526
536
  H(() => {
527
537
  t.original && !t.rawImage && r(t.original);
528
538
  }, [t.original, t.rawImage, r]), H(() => () => {
529
- E.current && clearTimeout(E.current);
539
+ P.current && clearTimeout(P.current);
530
540
  }, []);
531
- const j = T(
541
+ const K = C(
532
542
  async (m) => {
533
543
  if (!m.type.startsWith("image/"))
534
544
  return;
535
- const w = new FileReader();
536
- w.onload = async (P) => {
545
+ const v = new FileReader();
546
+ v.onload = async (I) => {
537
547
  var Z;
538
- const G = (Z = P.target) == null ? void 0 : Z.result;
539
- r(G), n(G), o(!1, null), c(0);
540
- }, w.readAsDataURL(m);
548
+ const F = (Z = I.target) == null ? void 0 : Z.result;
549
+ r(F), n(F), o(!1, null), c(0);
550
+ }, v.readAsDataURL(m);
541
551
  },
542
552
  [n, r, o, c]
543
- ), de = T(
553
+ ), he = C(
544
554
  (m) => {
545
- m.preventDefault(), I(!1);
546
- const w = m.dataTransfer.files[0];
547
- w && j(w);
555
+ m.preventDefault(), k(!1);
556
+ const v = m.dataTransfer.files[0];
557
+ v && K(v);
548
558
  },
549
- [j]
550
- ), he = T((m) => {
551
- m.preventDefault(), I(!0);
552
- }, []), me = T((m) => {
553
- m.preventDefault(), I(!1);
554
- }, []), pe = () => {
559
+ [K]
560
+ ), me = C((m) => {
561
+ m.preventDefault(), k(!0);
562
+ }, []), pe = C((m) => {
563
+ m.preventDefault(), k(!1);
564
+ }, []), ue = () => {
555
565
  var m;
556
566
  (m = S.current) == null || m.click();
557
- }, ue = (m) => {
558
- var P;
559
- const w = (P = m.target.files) == null ? void 0 : P[0];
560
- w && j(w);
561
- }, U = T(async (m, w) => {
567
+ }, ge = (m) => {
568
+ var I;
569
+ const v = (I = m.target.files) == null ? void 0 : I[0];
570
+ v && K(v);
571
+ }, U = C(async (m, v) => {
562
572
  try {
563
- return await l(m, w);
564
- } catch (P) {
565
- return console.error("Enhancement failed:", P), m;
573
+ return await l(m, v);
574
+ } catch (I) {
575
+ return console.error("Enhancement failed:", I), m;
566
576
  }
567
- }, [l]), V = T(async (m) => {
577
+ }, [l]), G = C(async (m) => {
568
578
  try {
569
- const w = await i(m);
570
- return o(!0, w), w;
571
- } catch (w) {
572
- return console.error("Background removal failed:", w), m;
579
+ const v = await i(m);
580
+ return o(!0, v), v;
581
+ } catch (v) {
582
+ return console.error("Background removal failed:", v), m;
573
583
  }
574
- }, [i, o]), ge = async () => {
575
- if (!k) return;
576
- if (!D && !g) {
584
+ }, [i, o]), fe = async () => {
585
+ if (!E) return;
586
+ if (!L && !g) {
577
587
  y(!0);
578
588
  return;
579
589
  }
580
- if (!D) {
581
- const w = await V(k);
582
- if (C > 0) {
583
- const P = await U(w, C);
584
- n(P);
590
+ if (!L) {
591
+ const v = await G(E), I = b.getState().portrait.engravingIntensity;
592
+ if (I > 0) {
593
+ const F = await U(v, I);
594
+ n(F);
585
595
  } else
586
- n(w);
587
- } else if (o(!1, null), C > 0) {
588
- const w = await U(k, C);
589
- n(w);
590
- } else
591
- n(k);
592
- }, fe = (m) => {
593
- c(m), E.current && clearTimeout(E.current), k && (E.current = setTimeout(async () => {
594
- const w = D && M ? M : k;
596
+ n(v);
597
+ } else {
598
+ o(!1, null);
599
+ const v = b.getState().portrait.engravingIntensity;
600
+ if (v > 0) {
601
+ const I = await U(E, v);
602
+ n(I);
603
+ } else
604
+ n(E);
605
+ }
606
+ }, be = (m) => {
607
+ c(m), P.current && clearTimeout(P.current), E && (P.current = setTimeout(async () => {
608
+ const v = L && z ? z : E;
595
609
  if (m === 0)
596
- n(w);
610
+ n(v);
597
611
  else {
598
- const P = await U(w, m);
599
- n(P);
612
+ const I = await U(v, m);
613
+ n(I);
600
614
  }
601
615
  }, 150));
602
- }, be = async (m) => {
603
- if (b(m), !k) return;
604
- const w = await V(k);
605
- if (C > 0) {
606
- const P = await U(w, C);
607
- n(P);
616
+ }, we = async (m) => {
617
+ if (w(m), !E) return;
618
+ const v = await G(E);
619
+ if (_ > 0) {
620
+ const I = await U(v, _);
621
+ n(I);
608
622
  } else
609
- n(w);
623
+ n(v);
610
624
  }, ve = () => {
611
625
  n(null), r(null), o(!1, null), c(0);
612
626
  };
@@ -673,11 +687,11 @@ function nt() {
673
687
  /* @__PURE__ */ u("div", { className: "form-control w-full max-w-xs", children: [
674
688
  /* @__PURE__ */ u("label", { className: "label", children: [
675
689
  /* @__PURE__ */ u("span", { className: "label-text flex items-center gap-2", children: [
676
- e === "de" ? "Gravur-Effekt" : "Engraving effect",
690
+ e === "de" ? "Sepia-Effekt" : "Sepia effect",
677
691
  d && /* @__PURE__ */ s("span", { className: "loading loading-spinner loading-xs" })
678
692
  ] }),
679
693
  /* @__PURE__ */ u("span", { className: "label-text-alt", children: [
680
- Math.round(C * 100),
694
+ Math.round(_ * 100),
681
695
  "%"
682
696
  ] })
683
697
  ] }),
@@ -688,10 +702,10 @@ function nt() {
688
702
  min: "0",
689
703
  max: "1",
690
704
  step: "0.05",
691
- value: C,
692
- onChange: (m) => fe(parseFloat(m.target.value)),
705
+ value: _,
706
+ onChange: (m) => be(parseFloat(m.target.value)),
693
707
  className: "range range-secondary range-sm",
694
- disabled: d || !k
708
+ disabled: d || !E
695
709
  }
696
710
  )
697
711
  ] }),
@@ -701,13 +715,13 @@ function nt() {
701
715
  {
702
716
  type: "checkbox",
703
717
  className: `toggle toggle-primary ${h ? "opacity-50" : ""}`,
704
- checked: D,
705
- onChange: ge,
706
- disabled: h || !k
718
+ checked: L,
719
+ onChange: fe,
720
+ disabled: h || !E
707
721
  }
708
722
  ),
709
723
  /* @__PURE__ */ u("span", { className: "label-text flex items-center gap-2", children: [
710
- h ? /* @__PURE__ */ u(O, { children: [
724
+ h ? /* @__PURE__ */ u(Y, { children: [
711
725
  /* @__PURE__ */ s("span", { className: "loading loading-spinner loading-xs" }),
712
726
  e === "de" ? "Hintergrund wird entfernt..." : "Removing background..."
713
727
  ] }) : e === "de" ? "Hintergrund entfernen" : "Remove background",
@@ -722,10 +736,10 @@ function nt() {
722
736
  "div",
723
737
  {
724
738
  className: `border-2 border-dashed rounded-lg p-8 text-center cursor-pointer transition-colors ${h ? "border-primary bg-primary/10 pointer-events-none" : x ? "border-primary bg-primary/10" : "border-base-300 hover:border-primary hover:bg-base-200"}`,
725
- onDrop: de,
726
- onDragOver: he,
727
- onDragLeave: me,
728
- onClick: pe,
739
+ onDrop: he,
740
+ onDragOver: me,
741
+ onDragLeave: pe,
742
+ onClick: ue,
729
743
  children: [
730
744
  /* @__PURE__ */ s(
731
745
  "input",
@@ -734,7 +748,7 @@ function nt() {
734
748
  type: "file",
735
749
  accept: "image/*",
736
750
  className: "hidden",
737
- onChange: ue
751
+ onChange: ge
738
752
  }
739
753
  ),
740
754
  h ? /* @__PURE__ */ u("div", { className: "flex flex-col items-center gap-2", children: [
@@ -767,19 +781,19 @@ function nt() {
767
781
  }
768
782
  ),
769
783
  /* @__PURE__ */ s(
770
- _e,
784
+ $e,
771
785
  {
772
786
  isOpen: R,
773
787
  onClose: () => y(!1),
774
- onSubmit: be
788
+ onSubmit: we
775
789
  }
776
790
  )
777
791
  ] });
778
792
  }
779
- function at() {
793
+ function ot() {
780
794
  return null;
781
795
  }
782
- const N = typeof import.meta < "u" && "/" || "/", Be = {
796
+ const N = typeof import.meta < "u" && "/" || "/", Me = {
783
797
  en: {
784
798
  1: {
785
799
  front: `${N}templates/front_ldpi_en.png`,
@@ -820,7 +834,7 @@ const N = typeof import.meta < "u" && "/" || "/", Be = {
820
834
  height: 3200
821
835
  }
822
836
  }
823
- }, _ = {
837
+ }, D = {
824
838
  front: {
825
839
  portrait: {
826
840
  x: 768,
@@ -913,36 +927,36 @@ const N = typeof import.meta < "u" && "/" || "/", Be = {
913
927
  }
914
928
  }
915
929
  };
916
- function re(e) {
917
- return e === "de" ? B : _;
930
+ function oe(e) {
931
+ return e === "de" ? B : D;
918
932
  }
919
- function oe(e, t) {
920
- return Be[e][t];
933
+ function ie(e, t) {
934
+ return Me[e][t];
921
935
  }
922
- const K = /* @__PURE__ */ new Map();
923
- async function Y(e) {
924
- return K.has(e) ? K.get(e) : new Promise((t, n) => {
936
+ const O = /* @__PURE__ */ new Map();
937
+ async function q(e) {
938
+ return O.has(e) ? O.get(e) : new Promise((t, n) => {
925
939
  const a = new Image();
926
940
  a.crossOrigin = "anonymous", a.onload = () => {
927
- K.set(e, a), t(a);
941
+ O.set(e, a), t(a);
928
942
  }, a.onerror = n, a.src = e;
929
943
  });
930
944
  }
931
- function ie(e, t, n, a) {
945
+ function se(e, t, n, a) {
932
946
  e.drawImage(t, 0, 0, n, a);
933
947
  }
934
- function $e(e, t, n, a, r, o, c = 1) {
948
+ function ze(e, t, n, a, r, o, c = 1) {
935
949
  e.save(), e.beginPath(), e.ellipse(n, a, r, o, 0, 0, Math.PI * 2), e.closePath(), e.clip();
936
950
  const l = t.width / t.height, i = r / o, d = r * 2, h = o * 2;
937
951
  let f, g;
938
952
  l > i ? (g = h, f = h * l) : (f = d, g = d / l), f *= c, g *= c;
939
- const b = n - f / 2, p = a - g / 2;
940
- e.drawImage(t, b, p, f, g), e.restore();
953
+ const w = n - f / 2, p = a - g / 2;
954
+ e.drawImage(t, w, p, f, g), e.restore();
941
955
  }
942
- function se(e, t, n, a = "#2a3a2a") {
956
+ function le(e, t, n, a = "#2a3a2a") {
943
957
  e.save(), e.font = `${n.fontSize}px "Times New Roman", serif`, e.textAlign = n.align || "center", e.textBaseline = "middle", e.fillStyle = a, n.maxWidth ? e.fillText(t, n.x, n.y, n.maxWidth) : e.fillText(t, n.x, n.y), e.restore();
944
958
  }
945
- function ze(e, t, n, a = "#2a3a2a") {
959
+ function He(e, t, n, a = "#2a3a2a") {
946
960
  e.save(), e.font = `${n.fontSize}px "Times New Roman", serif`, e.textAlign = n.align || "center", e.textBaseline = "top", e.fillStyle = a;
947
961
  const r = n.maxWidth || 400, o = n.lineHeight || n.fontSize * 1.4, c = t.split(" "), l = [];
948
962
  let i = "";
@@ -957,7 +971,7 @@ function ze(e, t, n, a = "#2a3a2a") {
957
971
  e.fillText(f, n.x, h), h += o;
958
972
  e.restore();
959
973
  }
960
- function Me(e, t, n, a, r, o = "#2a3a2a") {
974
+ function Ue(e, t, n, a, r, o = "#2a3a2a") {
961
975
  e.save(), e.font = `${r.fontSize}px "Times New Roman", serif`, e.textAlign = r.align || "center", e.textBaseline = "middle", e.fillStyle = o;
962
976
  const c = r.lineHeight || r.fontSize * 1.8, l = [t, n, a].filter(Boolean), i = (l.length - 1) * c;
963
977
  let d = r.y - i / 2;
@@ -965,15 +979,15 @@ function Me(e, t, n, a, r, o = "#2a3a2a") {
965
979
  h && (e.fillText(h, r.x, d), d += c);
966
980
  e.restore();
967
981
  }
968
- async function le(e, t, n, a, r, o, c, l = 1) {
982
+ async function ce(e, t, n, a, r, o, c, l = 1) {
969
983
  const i = e.getContext("2d");
970
984
  if (!i) return;
971
985
  e.width = o, e.height = c, i.clearRect(0, 0, o, c);
972
- const d = await Y(t);
973
- if (ie(i, d, o, c), n)
986
+ const d = await q(t);
987
+ if (se(i, d, o, c), n)
974
988
  try {
975
- const h = await Y(n);
976
- $e(
989
+ const h = await q(n);
990
+ ze(
977
991
  i,
978
992
  h,
979
993
  r.portrait.x,
@@ -985,46 +999,46 @@ async function le(e, t, n, a, r, o, c, l = 1) {
985
999
  } catch (h) {
986
1000
  console.error("Failed to load portrait:", h);
987
1001
  }
988
- a && se(i, a, r.namePlate);
1002
+ a && le(i, a, r.namePlate);
989
1003
  }
990
- async function ce(e, t, n, a, r, o, c, l, i) {
1004
+ async function de(e, t, n, a, r, o, c, l, i) {
991
1005
  const d = e.getContext("2d");
992
1006
  if (!d) return;
993
1007
  e.width = l, e.height = i, d.clearRect(0, 0, l, i);
994
- const h = await Y(t);
995
- ie(d, h, l, i), c.contactInfo && (n || a || r) && Me(d, n, a, r, c.contactInfo), c.description && o && ze(d, o, c.description), n && se(d, n, c.namePlate);
1008
+ const h = await q(t);
1009
+ se(d, h, l, i), c.contactInfo && (n || a || r) && Ue(d, n, a, r, c.contactInfo), c.description && o && He(d, o, c.description), n && le(d, n, c.namePlate);
996
1010
  }
997
- function rt() {
998
- const e = v((y) => y.voucherConfig.language), t = v((y) => y.voucherConfig.hours), n = v((y) => y.voucherConfig.description), a = v((y) => y.personalInfo), r = v((y) => y.portrait), o = v((y) => y.currentSide), c = v((y) => y.flipSide), l = z(e), i = L(null), d = L(null), h = L(null), [f, g] = A(!1), b = oe(e, t), p = re(e), S = r.useEnhanced && r.enhanced ? r.enhanced : r.original, x = te(e, t, n);
1011
+ function it() {
1012
+ const e = b((y) => y.voucherConfig.language), t = b((y) => y.voucherConfig.hours), n = b((y) => y.voucherConfig.description), a = b((y) => y.personalInfo), r = b((y) => y.portrait), o = b((y) => y.currentSide), c = b((y) => y.flipSide), l = M(e), i = A(null), d = A(null), h = A(null), [f, g] = T(!1), w = ie(e, t), p = oe(e), S = r.useEnhanced && r.enhanced ? r.enhanced : r.original, x = ne(e, t, n);
999
1013
  H(() => {
1000
- i.current && le(
1014
+ i.current && ce(
1001
1015
  i.current,
1002
- b.front,
1016
+ w.front,
1003
1017
  S,
1004
1018
  a.name,
1005
1019
  p.front,
1006
- b.width,
1007
- b.height,
1020
+ w.width,
1021
+ w.height,
1008
1022
  r.zoom
1009
1023
  );
1010
- }, [b, S, a.name, p, r.zoom]), H(() => {
1011
- d.current && ce(
1024
+ }, [w, S, a.name, p, r.zoom]), H(() => {
1025
+ d.current && de(
1012
1026
  d.current,
1013
- b.back,
1027
+ w.back,
1014
1028
  a.name,
1015
1029
  a.email,
1016
1030
  a.phone,
1017
1031
  x,
1018
1032
  p.back,
1019
- b.width,
1020
- b.height
1033
+ w.width,
1034
+ w.height
1021
1035
  );
1022
- }, [b, a, x, p]);
1023
- const I = () => {
1036
+ }, [w, a, x, p]);
1037
+ const k = () => {
1024
1038
  g(!0), setTimeout(() => {
1025
1039
  c(), g(!1);
1026
1040
  }, 150);
1027
- }, R = b.width / b.height;
1041
+ }, R = w.width / w.height;
1028
1042
  return /* @__PURE__ */ u("div", { className: "space-y-4", children: [
1029
1043
  /* @__PURE__ */ u("div", { className: "flex justify-between items-center", children: [
1030
1044
  /* @__PURE__ */ u("div", { className: "tabs tabs-boxed bg-base-200", children: [
@@ -1032,7 +1046,7 @@ function rt() {
1032
1046
  "button",
1033
1047
  {
1034
1048
  className: `tab ${o === "front" ? "tab-active bg-primary text-primary-content font-semibold" : ""}`,
1035
- onClick: () => o !== "front" && I(),
1049
+ onClick: () => o !== "front" && k(),
1036
1050
  children: l.preview.front
1037
1051
  }
1038
1052
  ),
@@ -1040,12 +1054,12 @@ function rt() {
1040
1054
  "button",
1041
1055
  {
1042
1056
  className: `tab ${o === "back" ? "tab-active bg-primary text-primary-content font-semibold" : ""}`,
1043
- onClick: () => o !== "back" && I(),
1057
+ onClick: () => o !== "back" && k(),
1044
1058
  children: l.preview.back
1045
1059
  }
1046
1060
  )
1047
1061
  ] }),
1048
- /* @__PURE__ */ u("button", { className: "btn btn-ghost btn-sm", onClick: I, children: [
1062
+ /* @__PURE__ */ u("button", { className: "btn btn-ghost btn-sm", onClick: k, children: [
1049
1063
  /* @__PURE__ */ s(
1050
1064
  "svg",
1051
1065
  {
@@ -1094,11 +1108,11 @@ function rt() {
1094
1108
  )
1095
1109
  ] });
1096
1110
  }
1097
- function ot() {
1098
- const e = L(null), t = L(null);
1111
+ function st() {
1112
+ const e = A(null), t = A(null);
1099
1113
  return { frontCanvasRef: e, backCanvasRef: t };
1100
1114
  }
1101
- async function He(e) {
1115
+ async function Fe(e) {
1102
1116
  const {
1103
1117
  frontTemplateSrc: t,
1104
1118
  backTemplateSrc: n,
@@ -1111,33 +1125,33 @@ async function He(e) {
1111
1125
  email: d,
1112
1126
  phone: h,
1113
1127
  description: f
1114
- } = e, g = document.createElement("canvas"), b = document.createElement("canvas");
1128
+ } = e, g = document.createElement("canvas"), w = document.createElement("canvas");
1115
1129
  await Promise.all([
1116
- le(g, t, c, i, o.front, a, r, l),
1117
- ce(b, n, i, d, h, f, o.back, a, r)
1130
+ ce(g, t, c, i, o.front, a, r, l),
1131
+ de(w, n, i, d, h, f, o.back, a, r)
1118
1132
  ]);
1119
1133
  const p = new xe({
1120
1134
  orientation: "landscape",
1121
1135
  unit: "mm",
1122
1136
  format: "a4"
1123
- }), S = 297, x = 210, I = 10, R = a / r;
1124
- let y = S - I * 2, E = y / R;
1125
- E > x - I * 2 && (E = x - I * 2, y = E * R);
1126
- const k = (S - y) / 2, M = (x - E) / 2, D = g.toDataURL("image/jpeg", 0.95);
1127
- p.addImage(D, "JPEG", k, M, y, E), p.addPage();
1128
- const C = b.toDataURL("image/jpeg", 0.95);
1129
- return p.addImage(C, "JPEG", k, M, y, E), p.output("blob");
1137
+ }), S = 297, x = 210, k = 10, R = a / r;
1138
+ let y = S - k * 2, P = y / R;
1139
+ P > x - k * 2 && (P = x - k * 2, y = P * R);
1140
+ const E = (S - y) / 2, z = (x - P) / 2, L = g.toDataURL("image/jpeg", 0.95);
1141
+ p.addImage(L, "JPEG", E, z, y, P), p.addPage();
1142
+ const _ = w.toDataURL("image/jpeg", 0.95);
1143
+ return p.addImage(_, "JPEG", E, z, y, P), p.output("blob");
1130
1144
  }
1131
- function Ue(e, t) {
1145
+ function We(e, t) {
1132
1146
  const n = URL.createObjectURL(e), a = document.createElement("a");
1133
1147
  a.href = n, a.download = t, document.body.appendChild(a), a.click(), document.body.removeChild(a), URL.revokeObjectURL(n);
1134
1148
  }
1135
- async function Fe(e) {
1136
- const t = await He(e);
1137
- Ue(t, e.filename);
1149
+ async function je(e) {
1150
+ const t = await Fe(e);
1151
+ We(t, e.filename);
1138
1152
  }
1139
- function it() {
1140
- const e = v((p) => p.voucherConfig.language), t = v((p) => p.voucherConfig.hours), n = v((p) => p.voucherConfig.description), a = v((p) => p.personalInfo), r = v((p) => p.portrait), o = v((p) => p.isExporting), c = v((p) => p.setIsExporting), l = z(e), i = oe(e, t), d = re(e), h = r.useEnhanced && r.enhanced ? r.enhanced : r.original, f = te(e, t, n), g = a.name.trim().length > 0 && a.email.trim().length > 0 && a.phone.trim().length > 0 && r.original !== null;
1153
+ function lt() {
1154
+ const e = b((p) => p.voucherConfig.language), t = b((p) => p.voucherConfig.hours), n = b((p) => p.voucherConfig.description), a = b((p) => p.personalInfo), r = b((p) => p.portrait), o = b((p) => p.isExporting), c = b((p) => p.setIsExporting), l = M(e), i = ie(e, t), d = oe(e), h = r.useEnhanced && r.enhanced ? r.enhanced : r.original, f = ne(e, t, n), g = a.name.trim().length > 0 && a.email.trim().length > 0 && a.phone.trim().length > 0 && r.original !== null;
1141
1155
  return /* @__PURE__ */ s(
1142
1156
  "button",
1143
1157
  {
@@ -1147,7 +1161,7 @@ function it() {
1147
1161
  c(!0);
1148
1162
  try {
1149
1163
  const p = `zeitgutschein-${t}h-${a.name.replace(/\s+/g, "-").toLowerCase()}.pdf`;
1150
- await Fe({
1164
+ await je({
1151
1165
  frontTemplateSrc: i.front,
1152
1166
  backTemplateSrc: i.back,
1153
1167
  templateWidth: i.width,
@@ -1169,10 +1183,10 @@ function it() {
1169
1183
  }
1170
1184
  },
1171
1185
  disabled: !g || o,
1172
- children: o ? /* @__PURE__ */ u(O, { children: [
1186
+ children: o ? /* @__PURE__ */ u(Y, { children: [
1173
1187
  /* @__PURE__ */ s("span", { className: "loading loading-spinner loading-sm" }),
1174
1188
  l.export.exporting
1175
- ] }) : /* @__PURE__ */ u(O, { children: [
1189
+ ] }) : /* @__PURE__ */ u(Y, { children: [
1176
1190
  /* @__PURE__ */ s(
1177
1191
  "svg",
1178
1192
  {
@@ -1197,8 +1211,8 @@ function it() {
1197
1211
  }
1198
1212
  );
1199
1213
  }
1200
- function We() {
1201
- const e = v((a) => a.voucherConfig.language), t = v((a) => a.setLanguage), n = (a) => {
1214
+ function Ke() {
1215
+ const e = b((a) => a.voucherConfig.language), t = b((a) => a.setLanguage), n = (a) => {
1202
1216
  t(a);
1203
1217
  };
1204
1218
  return /* @__PURE__ */ u("div", { className: "join", children: [
@@ -1220,22 +1234,22 @@ function We() {
1220
1234
  )
1221
1235
  ] });
1222
1236
  }
1223
- function st() {
1224
- const e = v((n) => n.voucherConfig.language), t = z(e);
1237
+ function ct() {
1238
+ const e = b((n) => n.voucherConfig.language), t = M(e);
1225
1239
  return /* @__PURE__ */ u("div", { className: "navbar bg-currency-green text-currency-cream shadow-lg", children: [
1226
1240
  /* @__PURE__ */ s("div", { className: "navbar-start", children: /* @__PURE__ */ s("a", { className: "btn btn-ghost text-xl font-currency font-bold", children: t.header.title }) }),
1227
1241
  /* @__PURE__ */ s("div", { className: "navbar-center hidden sm:flex", children: /* @__PURE__ */ s("span", { className: "text-sm opacity-80", children: t.header.subtitle }) }),
1228
- /* @__PURE__ */ s("div", { className: "navbar-end", children: /* @__PURE__ */ s(We, {}) })
1242
+ /* @__PURE__ */ s("div", { className: "navbar-end", children: /* @__PURE__ */ s(Ke, {}) })
1229
1243
  ] });
1230
1244
  }
1231
- const F = "/", je = {
1245
+ const W = "/", Oe = {
1232
1246
  id: "time-voucher-classic-de",
1233
1247
  name: "Zeitgutschein Classic",
1234
1248
  type: "time-voucher",
1235
1249
  category: "classic",
1236
1250
  images: {
1237
- front: `${F}templates/front_hdpi_de.jpg`,
1238
- back: `${F}templates/back_hdpi_de.jpg`,
1251
+ front: `${W}templates/front_hdpi_de.jpg`,
1252
+ back: `${W}templates/back_hdpi_de.jpg`,
1239
1253
  width: 6144,
1240
1254
  height: 4096
1241
1255
  },
@@ -1292,14 +1306,14 @@ const F = "/", je = {
1292
1306
  }
1293
1307
  },
1294
1308
  languages: ["de"]
1295
- }, Ke = {
1309
+ }, Ye = {
1296
1310
  id: "time-voucher-classic-en",
1297
1311
  name: "Time Voucher Classic",
1298
1312
  type: "time-voucher",
1299
1313
  category: "classic",
1300
1314
  images: {
1301
- front: `${F}templates/front_ldpi_en.png`,
1302
- back: `${F}templates/back_ldpi_en.png`,
1315
+ front: `${W}templates/front_ldpi_en.png`,
1316
+ back: `${W}templates/back_ldpi_en.png`,
1303
1317
  width: 1536,
1304
1318
  height: 1024
1305
1319
  },
@@ -1346,89 +1360,89 @@ const F = "/", je = {
1346
1360
  ],
1347
1361
  layout: {
1348
1362
  front: {
1349
- portrait: _.front.portrait,
1350
- name: _.front.namePlate
1363
+ portrait: D.front.portrait,
1364
+ name: D.front.namePlate
1351
1365
  },
1352
1366
  back: {
1353
- name: _.back.namePlate,
1354
- contactInfo: _.back.contactInfo,
1355
- description: _.back.description
1367
+ name: D.back.namePlate,
1368
+ contactInfo: D.back.contactInfo,
1369
+ description: D.back.description
1356
1370
  }
1357
1371
  },
1358
1372
  languages: ["en"]
1359
- }, ee = [
1360
- je,
1361
- Ke
1362
- ], Oe = {
1373
+ }, te = [
1374
+ Oe,
1375
+ Ye
1376
+ ], qe = {
1363
1377
  async listTemplates(e) {
1364
- let t = [...ee];
1378
+ let t = [...te];
1365
1379
  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;
1366
1380
  },
1367
1381
  async getTemplate(e) {
1368
- const t = ee.find((n) => n.id === e);
1382
+ const t = te.find((n) => n.id === e);
1369
1383
  if (!t)
1370
1384
  throw new Error(`Template not found: ${e}`);
1371
1385
  return t;
1372
1386
  }
1373
1387
  };
1374
- function lt(e) {
1388
+ function dt(e) {
1375
1389
  return e === "de" ? "time-voucher-classic-de" : "time-voucher-classic-en";
1376
1390
  }
1377
- let W = Oe;
1378
- function ct(e) {
1379
- W = e;
1391
+ let j = qe;
1392
+ function ht(e) {
1393
+ j = e;
1380
1394
  }
1381
- function dt() {
1382
- return W;
1395
+ function mt() {
1396
+ return j;
1383
1397
  }
1384
- async function ht(e) {
1385
- return W.listTemplates(e);
1398
+ async function pt(e) {
1399
+ return j.listTemplates(e);
1386
1400
  }
1387
- async function mt(e) {
1388
- return W.getTemplate(e);
1401
+ async function ut(e) {
1402
+ return j.getTemplate(e);
1389
1403
  }
1390
1404
  export {
1391
- _e as ApiKeyModal,
1392
- rt as BillPreview,
1393
- it as ExportButton,
1394
- st as Header,
1405
+ $e as ApiKeyModal,
1406
+ it as BillPreview,
1407
+ lt as ExportButton,
1408
+ ct as Header,
1395
1409
  B as LAYOUT_HDPI,
1396
- _ as LAYOUT_LDPI,
1397
- We as LanguageToggle,
1398
- Xe as PersonalInfoForm,
1399
- nt as PortraitUpload,
1400
- Be as TEMPLATES,
1401
- at as VoucherConfig,
1402
- Pe as applyEngravingEffect,
1403
- Ue as downloadBlob,
1404
- Me as drawContactInfo,
1405
- ze as drawMultilineText,
1406
- $e as drawOvalPortrait,
1407
- ie as drawTemplate,
1408
- se as drawText,
1409
- tt as enhancePortrait,
1410
- Fe as exportBillAsPDF,
1411
- te as formatDescription,
1412
- He as generateBillPDF,
1413
- q as getApiKey,
1414
- lt as getDefaultTemplateId,
1415
- re as getLayout,
1416
- Qe as getRemoveBackgroundEndpoint,
1417
- oe as getTemplate,
1418
- mt as getTemplateById,
1419
- dt as getTemplateProvider,
1420
- Q as hasApiKey,
1421
- et as hasCustomEndpoint,
1422
- ht as listTemplates,
1423
- Y as loadImage,
1424
- Le as removeBackground,
1425
- ce as renderBackSide,
1426
- le as renderFrontSide,
1427
- Ae as setApiKey,
1428
- Je as setRemoveBackgroundEndpoint,
1429
- ct as setTemplateProvider,
1430
- Oe as staticTemplateProvider,
1431
- z as t,
1432
- ot as useBillCanvasRefs,
1433
- v as useBillStore
1410
+ D as LAYOUT_LDPI,
1411
+ Ke as LanguageToggle,
1412
+ Qe as PersonalInfoForm,
1413
+ rt as PortraitUpload,
1414
+ Me as TEMPLATES,
1415
+ ot as VoucherConfig,
1416
+ Se as applyEngravingEffect,
1417
+ We as downloadBlob,
1418
+ Ue as drawContactInfo,
1419
+ He as drawMultilineText,
1420
+ ze as drawOvalPortrait,
1421
+ se as drawTemplate,
1422
+ le as drawText,
1423
+ at as enhancePortrait,
1424
+ je as exportBillAsPDF,
1425
+ ne as formatDescription,
1426
+ Fe as generateBillPDF,
1427
+ V as getApiKey,
1428
+ dt as getDefaultTemplateId,
1429
+ oe as getLayout,
1430
+ tt as getRemoveBackgroundEndpoint,
1431
+ ie as getTemplate,
1432
+ ut as getTemplateById,
1433
+ mt as getTemplateProvider,
1434
+ ee as hasApiKey,
1435
+ nt as hasCustomEndpoint,
1436
+ pt as listTemplates,
1437
+ q as loadImage,
1438
+ De as removeBackground,
1439
+ de as renderBackSide,
1440
+ ce as renderFrontSide,
1441
+ _e as setApiKey,
1442
+ et as setRemoveBackgroundEndpoint,
1443
+ ht as setTemplateProvider,
1444
+ qe as staticTemplateProvider,
1445
+ M as t,
1446
+ st as useBillCanvasRefs,
1447
+ b as useBillStore
1434
1448
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antontranelis/money-printer",
3
- "version": "1.0.12",
3
+ "version": "1.0.14",
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",