@overtone-art/canvas-editor-core 0.3.0 → 0.3.1

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.d.mts CHANGED
@@ -47,6 +47,18 @@ declare class LayerManager {
47
47
  setLocked(id: string, locked: boolean): void;
48
48
  setOpacity(id: string, opacity: number): void;
49
49
  setName(id: string, name: string): void;
50
+ /**
51
+ * Patch a layer's host metadata. A key whose value is `undefined` is removed.
52
+ *
53
+ * `meta` is part of `LayerData` and is serialized, so a host that assigns
54
+ * `layer.meta.x` directly gets neither of the two things every other setter
55
+ * here provides: `layers:changed` (so `useLayers()` keeps returning the old
56
+ * meta) and the history checkpoint (so an undo silently reverts the write —
57
+ * the state IS versioned, it was just never committed at the moment it
58
+ * changed). Going through this method is what makes metadata behave like
59
+ * every other layer property.
60
+ */
61
+ setMeta(id: string, patch: LayerMeta): void;
50
62
  clear(): void;
51
63
  count(): number;
52
64
  private emitChanged;
package/dist/index.d.ts CHANGED
@@ -47,6 +47,18 @@ declare class LayerManager {
47
47
  setLocked(id: string, locked: boolean): void;
48
48
  setOpacity(id: string, opacity: number): void;
49
49
  setName(id: string, name: string): void;
50
+ /**
51
+ * Patch a layer's host metadata. A key whose value is `undefined` is removed.
52
+ *
53
+ * `meta` is part of `LayerData` and is serialized, so a host that assigns
54
+ * `layer.meta.x` directly gets neither of the two things every other setter
55
+ * here provides: `layers:changed` (so `useLayers()` keeps returning the old
56
+ * meta) and the history checkpoint (so an undo silently reverts the write —
57
+ * the state IS versioned, it was just never committed at the moment it
58
+ * changed). Going through this method is what makes metadata behave like
59
+ * every other layer property.
60
+ */
61
+ setMeta(id: string, patch: LayerMeta): void;
50
62
  clear(): void;
51
63
  count(): number;
52
64
  private emitChanged;
@@ -501,6 +501,6 @@ void main() {
501
501
  color.b += max != color.b ? (max - color.b) * amt : 0.00;
502
502
  gl_FragColor = color;
503
503
  }
504
- `}applyTo2d({imageData:{data:r}}){let t=-this.vibrance;for(let e=0;e<r.length;e+=4){let i=r[e],s=r[e+1],n=r[e+2],a=Math.max(i,s,n),o=(i+s+n)/3,l=2*Math.abs(a-o)/255*t;r[e]+=a===i?0:(a-i)*l,r[e+1]+=a===s?0:(a-s)*l,r[e+2]+=a===n?0:(a-n)*l}}sendUniformData(r,t){r.uniform1f(t.uVibrance,-this.vibrance)}isNeutralState(){return this.vibrance===0}};m(Cr,"type","Vibrance"),m(Cr,"defaults",{vibrance:0}),m(Cr,"uniformLocations",["uVibrance"]),_.setClass(Cr);var Lr=Ar({BaseFilter:()=>W,BlackWhite:()=>cu,BlendColor:()=>lr,BlendImage:()=>hr,Blur:()=>cr,Brightness:()=>ur,Brownie:()=>su,ColorMatrix:()=>le,Composed:()=>Xs,Contrast:()=>dr,Convolute:()=>gr,Gamma:()=>pr,Grayscale:()=>fr,HueRotation:()=>oi,Invert:()=>mr,Kodachrome:()=>au,Noise:()=>vr,Pixelate:()=>yr,Polaroid:()=>lu,RemoveColor:()=>br,Resize:()=>xr,Saturation:()=>wr,Sepia:()=>hu,Technicolor:()=>ou,Vibrance:()=>Cr,Vintage:()=>nu});var Le=class{listeners=new Map;on(t,e){this.listeners.has(t)||this.listeners.set(t,new Set),this.listeners.get(t).add(e)}off(t,e){this.listeners.get(t)?.delete(e)}once(t,e){let i=s=>{this.off(t,i),e(s)};this.on(t,i)}emit(t,e){let i=this.listeners.get(t);if(i)for(let s of i)s(e)}removeAllListeners(t){t?this.listeners.delete(t):this.listeners.clear()}};var vn=Ml("crypto");var hl="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";var pu=128,Qt,Re;function fu(r){if(r<0)throw new RangeError("Wrong ID size");try{!Qt||Qt.length<r?(Qt=Buffer.allocUnsafe(r*pu),vn.webcrypto.getRandomValues(Qt),Re=0):Re+r>Qt.length&&(vn.webcrypto.getRandomValues(Qt),Re=0)}catch(t){throw Qt=void 0,t}Re+=r}function cl(r=21){fu(r|=0);let t="";for(let e=Re-r;e<Re;e++)t+=hl[Qt[e]&63];return t}var te=()=>cl(12);var Rr=class{id;type;name;visible;locked;opacity;meta;fabricObject;constructor(t,e,i,s){this.id=s??te(),this.type=t,this.name=i??`${t}-${this.id.slice(0,4)}`,this.visible=!0,this.locked=!1,this.opacity=1,this.meta={},this.fabricObject=e,this.fabricObject._layerId=this.id}hasMeta(){return Object.keys(this.meta).length>0}toData(){return{id:this.id,type:this.type,name:this.name,visible:this.visible,locked:this.locked,opacity:this.opacity,...this.hasMeta()?{meta:this.meta}:{}}}serialize(){return{...this.toData(),fabricObject:this.fabricObject.toObject()}}},Be=class{constructor(t,e){this.canvas=t;this.events=e}canvas;events;layers=[];onPropertyChanged;setHistoryCallback(t){this.onPropertyChanged=t}add(t,e,i,s){let n=new Rr(t,e,i,s);return this.layers.push(n),this.canvas.add(e),this.events.emit("layer:added",{layer:n.toData()}),this.emitChanged(),n}remove(t){let e=this.layers.findIndex(s=>s.id===t);if(e===-1)return!1;let i=this.layers[e];return this.canvas.remove(i.fabricObject),this.layers.splice(e,1),this.events.emit("layer:removed",{layerId:t}),this.emitChanged(),this.onPropertyChanged?.(),!0}replaceObject(t,e){let i=this.get(t);if(!i||i.fabricObject===e)return!1;let s=i.fabricObject,n=this.canvas.getObjects().indexOf(s),a=this.canvas.getActiveObject()===s;return this.canvas.remove(s),i.fabricObject=e,e._layerId=t,e.set({visible:i.visible,opacity:i.opacity,selectable:!i.locked,evented:!i.locked}),this.canvas.insertAt(Math.max(0,n),e),a&&this.canvas.setActiveObject(e),this.canvas.requestRenderAll(),this.events.emit("layer:modified",{layerId:t}),this.emitChanged(),this.onPropertyChanged?.(),!0}reorder(t,e){let i=this.layers.findIndex(a=>a.id===t);if(i===-1||!Number.isFinite(e))return!1;let s=Math.max(0,Math.min(this.layers.length-1,Math.round(e)));if(i===s)return!1;let[n]=this.layers.splice(i,1);return this.layers.splice(s,0,n),this.layers.forEach((a,o)=>{this.canvas.moveObjectTo(a.fabricObject,o)}),this.events.emit("layer:reordered",{layerIds:this.layers.map(a=>a.id)}),this.emitChanged(),this.onPropertyChanged?.(),!0}select(t){if(t===null)this.canvas.discardActiveObject();else{let i=this.get(t);i&&this.canvas.setActiveObject(i.fabricObject)}this.canvas.requestRenderAll(),this.events.emit("layer:selected",{layerId:t});let e=t&&this.get(t)?[t]:[];this.events.emit("selection:changed",{selected:e})}get(t){return this.layers.find(e=>e.id===t)}getAll(){return[...this.layers]}findByObject(t){let e=t._layerId;return e?this.get(e):this.layers.find(i=>i.fabricObject===t)}setVisibility(t,e){let i=this.get(t);i&&i.visible!==e&&(i.visible=e,i.fabricObject.visible=e,this.canvas.requestRenderAll(),this.emitChanged(),this.onPropertyChanged?.())}setLocked(t,e){let i=this.get(t);i&&i.locked!==e&&(i.locked=e,i.fabricObject.selectable=!e,i.fabricObject.evented=!e,this.canvas.requestRenderAll(),this.emitChanged(),this.onPropertyChanged?.())}setOpacity(t,e){let i=this.get(t);if(!i||!Number.isFinite(e))return;let s=Math.max(0,Math.min(1,e));i.opacity!==s&&(i.opacity=s,i.fabricObject.opacity=s,this.canvas.requestRenderAll(),this.emitChanged(),this.onPropertyChanged?.())}setName(t,e){let i=this.get(t);i&&i.name!==e&&(i.name=e,this.emitChanged(),this.onPropertyChanged?.())}clear(){for(let t of this.layers)this.canvas.remove(t.fabricObject);this.layers=[],this.emitChanged()}count(){return this.layers.length}emitChanged(){this.events.emit("layers:changed",{layers:this.layers.map(t=>t.toData())})}};var Xe=class r{static ASSET_KEY="__canvasEditorHistoryAsset";undoStack=[];redoStack=[];assets=new Map;assetIds=new Map;nextAssetId=1;maxSize;maxBytes;paused=!1;debounceTimer=null;debounceMs;getState;restoreState;events;transactionDepth=0;transactionDirty=!1;constructor(t){this.getState=t.getState,this.restoreState=t.restoreState,this.events=t.events,this.maxSize=t.maxSize??50,this.maxBytes=t.maxBytes??50*1024*1024,this.debounceMs=t.debounceMs??300}save(){if(!this.paused){if(this.transactionDepth>0){this.transactionDirty=!0;return}this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(()=>{this.saveImmediate()},this.debounceMs),this.emitChanged()}}saveImmediate(){if(this.paused){this.cancelPending();return}if(this.transactionDepth>0){this.transactionDirty=!0;return}this.cancelPending();let t=this.getState(),e=this.compactState(t);if(this.undoStack.at(-1)===e){this.emitChanged();return}for(this.undoStack.push(e);this.undoStack.length>this.maxSize;)this.undoStack.shift();this.redoStack=[],this.trimToBudget(),this.events.emit("history:snapshot",{bytes:t.length*2,totalBytes:this.snapshotBytes(),entries:this.undoStack.length}),this.emitChanged()}beginTransaction(){this.transactionDepth===0&&this.debounceTimer&&this.saveImmediate(),this.transactionDepth+=1}endTransaction(){this.transactionDepth!==0&&(this.transactionDepth-=1,this.transactionDepth===0&&this.transactionDirty&&(this.transactionDirty=!1,this.saveImmediate()))}async transaction(t){this.beginTransaction();try{return await t()}finally{this.endTransaction()}}async undo(){this.cancelPending();let t=this.undoStack.at(-1);if(!t)return;let e=this.compactState(this.getState()),i=e===t;if(i&&this.undoStack.length<2)return;let s=i?this.undoStack[this.undoStack.length-2]:t;this.paused=!0;try{await this.restoreState(this.expandState(s)),i&&this.undoStack.pop(),this.redoStack.push(e),this.trimToBudget()}catch(n){throw this.events.emit("error",{message:"Failed to undo the last change",error:n}),n}finally{this.paused=!1,this.emitChanged()}}async redo(){this.cancelPending();let t=this.redoStack.at(-1);if(t){this.paused=!0;try{await this.restoreState(this.expandState(t)),this.redoStack.pop(),this.undoStack.at(-1)!==t&&this.undoStack.push(t),this.trimToBudget()}catch(e){throw this.events.emit("error",{message:"Failed to redo the last change",error:e}),e}finally{this.paused=!1,this.emitChanged()}}}isRestoring(){return this.paused}pause(){this.paused=!0}resume(){this.paused=!1}canUndo(){return this.undoStack.length>1||this.debounceTimer!==null}canRedo(){return this.redoStack.length>0}clear(){this.cancelPending(),this.undoStack=[],this.redoStack=[],this.assets.clear(),this.assetIds.clear(),this.emitChanged()}getSnapshotBytes(){return this.snapshotBytes()}cancelPending(){this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null)}dispose(){this.cancelPending(),this.transactionDepth=0,this.transactionDirty=!1,this.undoStack=[],this.redoStack=[],this.assets.clear(),this.assetIds.clear()}emitChanged(){this.events.emit("history:changed",{canUndo:this.canUndo(),canRedo:this.canRedo()})}snapshotBytes(){let t=[...this.undoStack,...this.redoStack].reduce((i,s)=>i+s.length*2,0),e=[...this.assets.values()].reduce((i,s)=>i+s.length*2,0);return t+e}trimToBudget(){for(this.pruneAssets();this.undoStack.length>1&&this.snapshotBytes()>this.maxBytes;)this.undoStack.shift(),this.pruneAssets();for(;this.redoStack.length>1&&this.snapshotBytes()>this.maxBytes;)this.redoStack.shift(),this.pruneAssets()}compactState(t){let e;try{e=JSON.parse(t)}catch{return t}let i=s=>{if(typeof s=="string"&&/^data:image\/(?:png|jpeg|webp);base64,/i.test(s)){let n=this.assetIds.get(s);return n||(n=`a${this.nextAssetId++}`,this.assetIds.set(s,n),this.assets.set(n,s)),{[r.ASSET_KEY]:n}}return Array.isArray(s)?s.map(i):!s||typeof s!="object"?s:Object.fromEntries(Object.entries(s).map(([n,a])=>[n,i(a)]))};return JSON.stringify(i(e))}expandState(t){let e;try{e=JSON.parse(t)}catch{return t}let i=s=>{if(Array.isArray(s))return s.map(i);if(!s||typeof s!="object")return s;let n=s,a=n[r.ASSET_KEY];if(typeof a=="string"&&Object.keys(n).length===1){let o=this.assets.get(a);if(!o)throw new Error(`Missing history raster asset: ${a}`);return o}return Object.fromEntries(Object.entries(n).map(([o,l])=>[o,i(l)]))};return JSON.stringify(i(e))}pruneAssets(){if(this.assets.size===0)return;let t=[...this.undoStack,...this.redoStack];for(let[e,i]of this.assets){let s=`"${r.ASSET_KEY}":"${e}"`;t.some(n=>n.includes(s))||(this.assets.delete(e),this.assetIds.delete(i))}}};var mu="#22c55e",$e=class{constructor(t,e){this.canvas=t;this.events=e;this.onMoving=i=>this.handleMoving(i.target),this.onAfterRender=()=>this.drawGuides(),this.onModified=()=>this.clearGuides(),this.canvas.on("object:moving",this.onMoving),this.canvas.on("after:render",this.onAfterRender),this.canvas.on("mouse:up",this.onModified),this.canvas.on("selection:cleared",this.onModified)}canvas;events;enabled=!1;threshold=8;guides=[];onMoving;onAfterRender;onModified;setEnabled(t){this.enabled!==t&&(this.enabled=t,t||this.clearGuides(),this.events.emit("snap:changed",{enabled:t}))}isEnabled(){return this.enabled}setThreshold(t){this.threshold=Math.max(0,t)}dispose(){this.canvas.off("object:moving",this.onMoving),this.canvas.off("after:render",this.onAfterRender),this.canvas.off("mouse:up",this.onModified),this.canvas.off("selection:cleared",this.onModified),this.guides=[]}handleMoving(t){if(!this.enabled||!t)return;t.setCoords();let e=t.getBoundingRect(),i=this.canvas.getWidth(),s=this.canvas.getHeight(),{xs:n,ys:a}=vu(this.canvas,t,i,s);this.guides=[];let o=ul([e.left,e.left+e.width/2,e.left+e.width],n,this.threshold);o!==null&&(t.set("left",(t.left??0)+o.delta),this.guides.push({x:o.line}));let l=ul([e.top,e.top+e.height/2,e.top+e.height],a,this.threshold);l!==null&&(t.set("top",(t.top??0)+l.delta),this.guides.push({y:l.line})),t.setCoords()}drawGuides(){if(!this.enabled||this.guides.length===0)return;let t=this.canvas.contextTop;if(!t)return;let e=this.canvas.getRetinaScaling(),i=this.canvas.getWidth(),s=this.canvas.getHeight();t.save(),t.setTransform(e,0,0,e,0,0),t.lineWidth=1,t.strokeStyle=mu,t.setLineDash([4,4]),t.beginPath();for(let n of this.guides)n.x!==void 0&&(t.moveTo(n.x,0),t.lineTo(n.x,s)),n.y!==void 0&&(t.moveTo(0,n.y),t.lineTo(i,n.y));t.stroke(),t.restore()}clearGuides(){this.guides.length!==0&&(this.guides=[],this.canvas.clearContext(this.canvas.contextTop))}};function vu(r,t,e,i){let s=[0,e/2,e],n=[0,i/2,i];for(let a of r.getObjects()){if(a===t||!a.visible)continue;a.setCoords();let o=a.getBoundingRect();s.push(o.left,o.left+o.width/2,o.left+o.width),n.push(o.top,o.top+o.height/2,o.top+o.height)}return{xs:s,ys:n}}function ul(r,t,e){let i=null;for(let s of r)for(let n of t){let a=Math.abs(s-n);a<=e&&(i===null||a<i.dist)&&(i={delta:n-s,line:n,dist:a})}return i?{delta:i.delta,line:i.line}:null}function N(r,t,e){return Math.min(e,Math.max(t,r))}function J(r){return Math.round(r*100)/100}var Ye=class{constructor(t,e,i){this.canvas=t;this.history=e;this.events=i;this.onSelectionCleared=()=>{this.session&&this.cancel()},this.canvas.on("selection:cleared",this.onSelectionCleared)}canvas;history;events;session=null;onSelectionCleared;isActive(){return this.session!==null}activeLayerId(){return this.session?.layerId??null}start(t){if(t.type!=="image")return;this.session&&this.cancel();let e=t.fabricObject,i=e.angle??0;i&&e.rotate(0),e.setCoords();let s=e.getBoundingRect(),n=new jt({left:s.left,top:s.top,width:s.width,height:s.height,originX:"left",originY:"top",fill:"rgba(34,197,94,0.12)",stroke:dl,strokeWidth:1,strokeDashArray:[4,4],strokeUniform:!0,lockRotation:!0,cornerColor:dl,transparentCorners:!1});n.setControlsVisibility({mtr:!1});let a=e.selectable??!0,o=e.evented??!0;e.selectable=!1,e.evented=!1,this.canvas.add(n),this.canvas.setActiveObject(n),this.canvas.requestRenderAll(),this.session={layerId:t.id,image:e,rect:n,prevSelectable:a,prevEvented:o,prevAngle:i},this.events.emit("crop:changed",{active:!0,layerId:t.id})}apply(){let t=this.session;if(!t)return;let{image:e,rect:i}=t;i.setCoords(),e.setCoords();let s=e.scaleX??1,n=e.scaleY??1,a=e.left??0,o=e.top??0,l=e.getElement(),h=l.naturalWidth||e.width||0,c=l.naturalHeight||e.height||0,u=(e.cropX??0)+(i.left-a)/s,d=(e.cropY??0)+(i.top-o)/n,g=i.getScaledWidth()/s,p=i.getScaledHeight()/n;u=N(u,0,Math.max(0,h-1)),d=N(d,0,Math.max(0,c-1)),g=N(g,1,h-u),p=N(p,1,c-d),e.set({cropX:u,cropY:d,width:g,height:p,left:a+(u-(e.cropX??0))*s,top:o+(d-(e.cropY??0))*n}),e.setCoords(),t.prevAngle&&(e.rotate(t.prevAngle),e.setCoords()),this.finish(),this.history.save()}cancel(){let t=this.session;t&&(t.prevAngle&&(t.image.rotate(t.prevAngle),t.image.setCoords()),this.finish())}dispose(){this.cancel(),this.canvas.off("selection:cleared",this.onSelectionCleared)}finish(){let t=this.session;t&&(this.session=null,this.canvas.remove(t.rect),t.image.selectable=t.prevSelectable,t.image.evented=t.prevEvented,this.canvas.setActiveObject(t.image),this.canvas.requestRenderAll(),this.events.emit("crop:changed",{active:!1,layerId:null}))}},dl="#22c55e";var ml=200,We=class{constructor(t,e,i,s,n){this.canvas=t;this.layers=e;this.history=i;this.events=s;this.sourceResolver=n}canvas;layers;history;events;sourceResolver;chains=new Map;isPattern(t){return!!this.layers.get(t)?.meta.pattern}getConfig(t){return this.layers.get(t)?.meta.pattern?.config??null}apply(t,e){return this.enqueue(t,async()=>{let i=this.layers.get(t);if(!i||i.type!=="image")return;let s=i.fabricObject,n=!i.meta.pattern;if(i.meta.pattern)i.meta.pattern.config=e;else{let a=s.clipPath;i.meta.pattern={config:e,originalSrc:yu(s)??s.getSrc(),originalClip:a?a.toObject():null,originalLocks:yn(s),original:{left:s.left??0,top:s.top??0,scaleX:s.scaleX??1,scaleY:s.scaleY??1,width:s.width??0,height:s.height??0,angle:s.angle??0,cropX:s.cropX??0,cropY:s.cropY??0}}}try{await this.renderLayer(i)}catch(a){throw n&&delete i.meta.pattern,a}this.history.save()}).catch(i=>{throw this.events.emit("error",{message:"Failed to apply image pattern",error:i}),i})}repinAll(){let t=this.canvas.getWidth(),e=this.canvas.getHeight(),i=!1;for(let s of this.layers.getAll()){if(!s.meta.pattern||s.type!=="image")continue;let n=s.fabricObject;n.set({left:0,top:0,angle:0,scaleX:t/(n.width||t),scaleY:e/(n.height||e)}),ji(n),n.setCoords(),i=!0}i&&this.canvas.requestRenderAll()}disable(t){return this.enqueue(t,async()=>{let e=this.layers.get(t),i=e?.meta.pattern;if(!e||!i)return;let s=e.fabricObject;await s.setSrc(i.originalSrc),s.set({left:i.original.left,top:i.original.top,scaleX:i.original.scaleX,scaleY:i.original.scaleY,width:i.original.width,height:i.original.height,cropX:i.original.cropX,cropY:i.original.cropY,angle:i.original.angle}),s.clipPath=i.originalClip?(await Zt.enlivenObjects([i.originalClip]))[0]:void 0,bn(s,i.originalLocks),s.setCoords(),delete e.meta.pattern,this.canvas.requestRenderAll(),this.history.save()}).catch(e=>{throw this.events.emit("error",{message:"Failed to clear image pattern",error:e}),e})}enqueue(t,e){let s=(this.chains.get(t)??Promise.resolve()).then(e,e);return this.chains.set(t,s.catch(()=>{})),s}async renderLayer(t){let e=t.meta.pattern;if(!e)return;let i=t.fabricObject,s=this.canvas.getWidth(),n=this.canvas.getHeight(),a=Math.max(1,e.config.scale??100)/100,o=Math.sqrt(s*s+n*n),l=Math.max(2,o/ml),h=Math.max(l,e.original.width*e.original.scaleX*a),c=Math.max(l,e.original.height*e.original.scaleY*a),u=await wn(e.originalSrc,e.config,s,n,h,c,this.sourceResolver);await i.setSrc(u),i.set({left:0,top:0,scaleX:1,scaleY:1,width:s,height:n,cropX:0,cropY:0,angle:0}),i.clipPath=void 0,ji(i),i.setCoords(),this.canvas.requestRenderAll()}};function yn(r){return{lockMovementX:r.lockMovementX??!1,lockMovementY:r.lockMovementY??!1,lockScalingX:r.lockScalingX??!1,lockScalingY:r.lockScalingY??!1,lockRotation:r.lockRotation??!1,hasControls:r.hasControls??!0}}function ji(r){r.set({lockMovementX:!0,lockMovementY:!0,lockScalingX:!0,lockScalingY:!0,lockRotation:!0,hasControls:!1})}function bn(r,t){r.set(t??{lockMovementX:!1,lockMovementY:!1,lockScalingX:!1,lockScalingY:!1,lockRotation:!1,hasControls:!0})}function yu(r){try{let t=r.getElement(),e=t.naturalWidth||t.width,i=t.naturalHeight||t.height;if(!e||!i)return null;let s=document.createElement("canvas");s.width=e,s.height=i;let n=s.getContext("2d");return n?(n.drawImage(t,0,0),s.toDataURL("image/png")):null}catch{return null}}var bu=16,Mt=new Map;function xn(r,t){let e=Mt.get(r);if(e)return Mt.delete(r),Mt.set(r,e),e;let i=gl(r).catch(async s=>{if(!t)throw s;let n=await t(r);if(!n||n===r)throw new Error("Pattern source resolver did not return a usable alternate URL",{cause:s});return gl(n)});if(i.catch(()=>{Mt.get(r)===i&&Mt.delete(r)}),Mt.set(r,i),Mt.size>bu){let s=Mt.keys().next().value;s!==void 0&&Mt.delete(s)}return i}function gl(r){return new Promise((t,e)=>{let i=new Image;i.crossOrigin="anonymous",i.onload=()=>t(i),i.onerror=()=>e(new Error(`Failed to load pattern source: ${r}`)),i.src=r})}function Ii(){Mt.clear()}async function wn(r,t,e,i,s,n,a){let o=await xn(r,a),l=document.createElement("canvas");l.width=Math.max(1,Math.round(e)),l.height=Math.max(1,Math.round(i));let h=l.getContext("2d");return h&&Sn(h,o,t,e,i,s,n),l.toDataURL("image/png")}function Cn(r,t,e,i,s){let n=Math.sqrt(t*t+e*e),a=Math.max(1,n/ml),o=Math.max(a,i*(1+r.horizontalSpacing/100)),l=Math.max(a,s*(1+r.verticalSpacing/100)),h=Math.ceil(n/o)+2,c=Math.ceil(n/l)+2,u=Math.ceil(h/2),d=Math.ceil(c/2),g=o*(pl(r.offsetX)/100),p=l*(pl(r.offsetY)/100),f=[];for(let v=-d;v<=d;v++)for(let y=-u;y<=u;y++){let x=y*o+g,w=v*l+p;r.mode==="brick-horizontal"&&fl(v)===1?x+=o*(r.horizontalOffset/100):r.mode==="brick-vertical"&&fl(y)===1&&(w+=l*(r.horizontalOffset/100));let S=(y*r.rotationStepH+v*r.rotationStepV)*Math.PI/180;f.push({x,y:w,rotation:S})}return f}function Sn(r,t,e,i,s,n,a){r.save(),r.translate(i/2,s/2),r.rotate(e.angle*Math.PI/180);for(let o of Cn(e,i,s,n,a))r.save(),r.translate(o.x,o.y),r.rotate(o.rotation),r.drawImage(t,-n/2,-a/2,n,a),r.restore();r.restore()}function pl(r){return typeof r!="number"||!Number.isFinite(r)?0:Math.max(-100,Math.min(100,r))}function fl(r){return(r%2+2)%2}var Fi={arc:0,wave:0},_n=.5,xu=99.5,wu=.12,Cu=4.1,Su=.9,_u=6,Tu=1e5,ku=.06;function vl(r){return!!r&&typeof r.text=="string"}function Ou(r){let t=r.width;try{return r.set({width:Tu}),r.initDimensions?.(),Math.max(1,r.calcTextWidth?.()??r.width??1)}finally{t!==void 0&&r.set({width:t}),r.initDimensions?.()}}function Mu(r,t){let e=Math.min(100,Math.abs(t)),i=t<0?-1:1,s=e>=xu,n=s?Math.PI*2:Math.max(wu,e/100*Math.PI),a=r/n,o=r/2,l=p=>[o+a*Math.sin(p),i*a*(1-Math.cos(p))],h=i>0?1:0,c=([p,f])=>`${Pt(p)} ${Pt(f)}`;if(s){let p=l(-Math.PI),f=l(0);return{data:[`M ${c(p)}`,`A ${Pt(a)} ${Pt(a)} 0 0 ${h} ${c(f)}`,`A ${Pt(a)} ${Pt(a)} 0 0 ${h} ${c(p)}`].join(" "),length:r}}let u=l(-n/2),d=l(n/2),g=n>Math.PI?1:0;return{data:`M ${c(u)} A ${Pt(a)} ${Pt(a)} 0 ${g} ${h} ${c(d)}`,length:r}}function Pu(r,t,e){let i=N(e,0,100)/100*t*Su,s=Math.max(1,t*Cu),n=Math.max(2,Math.ceil(r/_u)),a=[],o=0,l=null;for(let h=0;h<=n;h++){let c=r*h/n,u=i*Math.sin(c/s*Math.PI*2);l&&(o+=Math.hypot(c-l[0],u-l[1])),l=[c,u],a.push(`${h===0?"M":"L"} ${Pt(c)} ${Pt(u)}`)}return{data:a.join(" "),length:o}}function Pt(r){return Math.round(r*100)/100}function Tn(r,t,e){return Math.abs(r.arc)>=_n?Mu(t,r.arc):r.wave>0?Pu(t,e,r.wave):null}function Eu(r){let t=N(r.arc??0,-100,100);return{arc:t,wave:Math.abs(t)>=_n?0:N(r.wave??0,0,100)}}var ze=class{constructor(t,e,i,s){this.canvas=t;this.layers=e;this.history=i;this.events=s}canvas;layers;history;events;get(t){let e=this.layers.get(t);return!e||!vl(e.fabricObject)?null:e.meta.curve??{...Fi}}isCurved(t){let e=this.get(t);return!!e&&(Math.abs(e.arc)>=_n||e.wave>0)}apply(t,e,i=!0){let s=this.layers.get(t);if(!s||!vl(s.fabricObject))return!1;let n=Eu(e),a=s.fabricObject,o=Ou(a),l=Tn(n,o*(1+ku),a.fontSize);return l?(s.meta.curveWidth===void 0&&(s.meta.curveWidth=a.width??0),a.set({width:Math.max(s.meta.curveWidth,o+2)}),a.set({path:new It(l.data,{visible:!1,objectCaching:!1}),pathAlign:"center",pathSide:"left",pathStartOffset:Math.max(0,(l.length-o)/2)}),s.meta.curve=n):(this.detach(a,s.meta.curveWidth),delete s.meta.curve,delete s.meta.curveWidth),a.initDimensions?.(),a.setCoords(),a.dirty=!0,this.canvas.requestRenderAll(),this.events.emit("layer:modified",{layerId:t}),i&&this.history.save(),!0}clear(t,e=!0){return this.apply(t,Fi,e)}refresh(t,e=!1){let i=this.layers.get(t)?.meta.curve;return i?this.apply(t,i,e):!1}refreshAll(){for(let t of this.layers.getAll())t.meta.curve&&this.refresh(t.id)}detach(t,e){t.set({path:null,pathStartOffset:0}),e!==void 0&&e>0&&t.set({width:e})}};var Li=["circle","square","triangle","star","heart","octagram","arch","zigzag"];function He(r){return typeof r=="string"&&Li.includes(r)}function kn(r,t,e,i=-Math.PI/2){let s=Math.PI/r,n=[];for(let a=0;a<r*2;a++){let o=a%2===0?t:e,l=i+a*s,h=50+Math.cos(l)*o,c=50+Math.sin(l)*o;n.push(`${a===0?"M":"L"} ${yl(h)} ${yl(c)}`)}return`${n.join(" ")} Z`}function yl(r){return Math.round(r*100)/100}var Du={circle:"M 96 50 A 46 46 0 1 1 4 50 A 46 46 0 1 1 96 50 Z",square:"M 4 4 H 96 V 96 H 4 Z",triangle:"M 50 4 L 96 96 L 4 96 Z",star:kn(5,46,22),heart:"M 50 96 C -8 55 12 4 50 28 C 88 4 108 55 50 96 Z",octagram:kn(8,46,27),arch:"M 4 96 V 50 A 46 46 0 0 1 96 50 V 96 Z",zigzag:kn(16,46,39)};function Br(r){return Du[r]}var Ve=100;var Ri=["vignette","halftone","spray","grunge","torn","band"];function Xr(r){return typeof r=="string"&&Ri.includes(r)}var Et=320,Mn=new Map;function On(r){let t=r;return()=>(t=t*16807%2147483647,(t-1)/2147483646)}function bl(r,t,e,i){let s=Et,n=[[i,i],[s-i,i],[s-i,s-i],[i,s-i]];r.beginPath();for(let a=0;a<n.length;a++){let[o,l]=n[a],[h,c]=n[(a+1)%n.length];for(let u=0;u<=26;u++){let d=u/26,g=o+(h-o)*d+(t()-.5)*e,p=l+(c-l)*d+(t()-.5)*e;a===0&&u===0?r.moveTo(g,p):r.lineTo(g,p)}}r.closePath(),r.fill()}function Au(r,t){let e=Et,i=e/2;switch(t.fillStyle="#ffffff",r){case"vignette":{let s=t.createRadialGradient(i,i,e*.18,i,i,e*.52);s.addColorStop(0,"rgba(255,255,255,1)"),s.addColorStop(1,"rgba(255,255,255,0)"),t.fillStyle=s,t.fillRect(0,0,e,e);return}case"band":{let s=t.createLinearGradient(0,0,0,e);s.addColorStop(0,"rgba(255,255,255,0)"),s.addColorStop(.25,"rgba(255,255,255,1)"),s.addColorStop(.75,"rgba(255,255,255,1)"),s.addColorStop(1,"rgba(255,255,255,0)"),t.fillStyle=s,t.fillRect(0,0,e,e);return}case"halftone":{for(let n=16/2;n<e;n+=16)for(let a=16/2;a<e;a+=16){let o=Math.hypot(a-i,n-i)/(e*.52),l=Math.max(0,16/2*(1-o)*1.15);l<.4||(t.beginPath(),t.arc(a,n,l,0,Math.PI*2),t.fill())}return}case"spray":{let s=On(42),n=t.createRadialGradient(i,i,10,i,i,e*.42);n.addColorStop(0,"rgba(255,255,255,1)"),n.addColorStop(1,"rgba(255,255,255,0.85)"),t.fillStyle=n,t.beginPath(),t.arc(i,i,e*.42,0,Math.PI*2),t.fill(),t.fillStyle="rgba(255,255,255,0.9)";for(let a=0;a<900;a++){let o=s()*Math.PI*2,l=e*(.3+s()*.24),h=i+Math.cos(o)*l,c=i+Math.sin(o)*l;t.globalAlpha=1-(l/e-.3)/.24,t.beginPath(),t.arc(h,c,s()*2.4,0,Math.PI*2),t.fill()}t.globalAlpha=1;return}case"grunge":{let s=On(7);bl(t,s,14,e*.06),t.globalCompositeOperation="destination-out";for(let n=0;n<240;n++){let a=s()*e,o=s()*e;!(Math.min(a,o,e-a,e-o)<e*.12)&&s()>=.12||(t.beginPath(),t.arc(a,o,s()*6+1,0,Math.PI*2),t.fill())}t.globalCompositeOperation="source-over";return}case"torn":{bl(t,On(99),10,e*.08);return}}}function $r(r){let t=Mn.get(r);if(t)return t;if(typeof document>"u")throw new Error("Texture masks require a DOM canvas");let e=document.createElement("canvas");e.width=Et,e.height=Et;let i=e.getContext("2d");if(!i)throw new Error("Texture masks require a 2D canvas context");return Au(r,i),Mn.set(r,e),e}function Pn(){Mn.clear()}function Bi(r){return He(r)||Xr(r)}var me=class{constructor(t,e,i,s){this.canvas=t;this.layers=e;this.history=i;this.events=s}canvas;layers;history;events;get(t){return this.layers.get(t)?.meta.maskPreset??null}apply(t,e,i=!0){let s=this.layers.get(t);if(!s)return!1;let n=s.fabricObject;if(e===null){if(!s.meta.maskPreset)return!1;n.clipPath=void 0,delete s.meta.maskPreset}else{if(!Bi(e))return!1;n.clipPath=this.buildClip(e,n),s.meta.maskPreset=e}return n.dirty=!0,n.setCoords(),this.canvas.requestRenderAll(),this.events.emit("layer:modified",{layerId:t}),i&&this.history.save(),!0}clear(t,e=!0){return this.apply(t,null,e)}refresh(t,e=!1){let i=this.get(t);return i?this.apply(t,i,e):!1}refreshAll(){for(let t of this.layers.getAll())t.meta.maskPreset&&this.refresh(t.id)}buildClip(t,e){let i=Math.max(1,e.width??1),s=Math.max(1,e.height??1),n={originX:"center",originY:"center",left:0,top:0,objectCaching:!1};return He(t)?new It(Br(t),{...n,scaleX:i/Ve,scaleY:s/Ve}):new V($r(t),{...n,scaleX:i/Et,scaleY:s/Et})}};var ju=/^(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\([\d.%+\-\s,/]+\)|[a-z]+)$/i;function ee(r,t=!1){if(typeof r!="string")return!1;let e=r.trim();return e?ju.test(e):t}var re={enabled:!1,color:"#000000",blur:12,offsetX:6,offsetY:6};function Yr(r){let t=r.shadow;return!t||typeof t=="string"?{...re}:{enabled:!0,color:typeof t.color=="string"?t.color:re.color,blur:t.blur??re.blur,offsetX:t.offsetX??re.offsetX,offsetY:t.offsetY??re.offsetY}}function Xi(r,t){let e={...Yr(r),...t};if(!e.enabled){r.set({shadow:null});return}let i=ee(e.color)?e.color:re.color;r.set({shadow:new he({color:i,blur:Math.max(0,e.blur),offsetX:e.offsetX,offsetY:e.offsetY})})}var Iu=["ml","mr","mt","mb"];function ve(r,t){for(let e of Iu)r.setControlVisible(e,!t)}function $i(r){r.set({scaleX:1,scaleY:1,angle:0,skewX:0,skewY:0,flipX:!1,flipY:!1}),r.setCoords()}var Ne=class{unit;dpi;constructor(t="px",e=72){this.unit=t,this.dpi=72,this.setDpi(e)}setUnit(t){this.unit=t}setDpi(t){if(!Number.isFinite(t)||t<=0)throw new Error("DPI must be a positive number");this.dpi=t}getUnit(){return this.unit}getDpi(){return this.dpi}toPixels(t,e){switch(e??this.unit){case"px":return t;case"in":return t*this.dpi;case"mm":return t/25.4*this.dpi}}fromPixels(t,e){switch(e??this.unit){case"px":return t;case"in":return t/this.dpi;case"mm":return t/this.dpi*25.4}}};var Fu="2.0.0";function Yi(r){return{version:Fu,canvas:{width:r.canvas.getWidth(),height:r.canvas.getHeight(),unit:r.units.getUnit(),dpi:r.units.getDpi()},layers:r.layers.getAll().map(t=>t.serialize()),background:r.getDesignBackground(),backgroundImage:r.getDesignBackgroundImage()?r.getDesignBackgroundImage().toObject():null,backgroundImageOptions:r.getBackgroundImageOptions(),mockup:r.getMockup()}}async function Wi(r,t){if(!t||!t.canvas||!Array.isArray(t.layers))throw new Error("Invalid editor state");if(!Number.isFinite(t.canvas.width)||!Number.isFinite(t.canvas.height)||t.canvas.width<=0||t.canvas.height<=0||t.canvas.unit!==void 0&&!["px","mm","in"].includes(t.canvas.unit)||t.canvas.dpi!==void 0&&(!Number.isFinite(t.canvas.dpi)||t.canvas.dpi<=0))throw new Error("Invalid editor canvas settings");let e=Number.parseInt(t.version?.split(".")[0]??"1",10);if(!Number.isFinite(e)||e>2)throw new Error(`Unsupported editor state version: ${t.version}`);if(t.background!==void 0&&!ee(t.background,!0))throw new Error("Invalid editor background color");let i=await Promise.all(t.layers.map(async n=>{let a=(await Zt.enlivenObjects([n.fabricObject]))[0];if(!a){let o=n.fabricObject.src;throw typeof o=="string"&&o.startsWith("blob:")?new Error(`Failed to restore expired object URL: ${o}`):new Error(`Failed to restore layer: ${n.id}`)}return{serialized:n,fabricObject:a}})),s=t.backgroundImage?(await Zt.enlivenObjects([t.backgroundImage]))[0]:null;if(t.backgroundImage&&!s){let n=t.backgroundImage.src;throw typeof n=="string"&&n.startsWith("blob:")?new Error(`Failed to restore expired background object URL: ${n}`):new Error("Failed to restore background image")}r.crop.cancel(),r.masks.detach(),r.layers.clear(),t.canvas.unit&&r.units.setUnit(t.canvas.unit),t.canvas.dpi!==void 0&&r.units.setDpi(t.canvas.dpi),r.canvas.setDimensions({width:t.canvas.width,height:t.canvas.height}),t.background!==void 0&&r.setBackground(t.background),r.setBackgroundImageObject(s??null,!1,t.backgroundImageOptions??null),r.setMockup(t.mockup??null);for(let n of i)Lu(r,n.serialized,n.fabricObject);r.canvas.requestRenderAll()}function Lu(r,t,e){let i=r.layers.add(t.type,e,t.name,t.id);return t.meta&&(i.meta=t.meta,i.meta.lockAspect&&ve(e,!0)),t.visible||r.layers.setVisibility(i.id,!1),t.locked&&r.layers.setLocked(i.id,!0),t.opacity!==1&&r.layers.setOpacity(i.id,t.opacity),i}var xl={red:0,green:1,blue:2,alpha:3};function wl(r,t,e){let i=r??t;if(!Number.isFinite(i))throw new Error(`${e} must be finite`);return i}function Ru(r,t,e,i,s,n){let a=Math.max(0,Math.min(t-1,i)),o=Math.max(0,Math.min(e-1,s)),l=Math.floor(a),h=Math.floor(o),c=Math.min(t-1,l+1),u=Math.min(e-1,h+1),d=a-l,g=o-h,p=r[(h*t+l)*4+n]*(1-d)+r[(h*t+c)*4+n]*d,f=r[(u*t+l)*4+n]*(1-d)+r[(u*t+c)*4+n]*d;return p*(1-g)+f*g}function zi(r,t,e,i,s){if(!Number.isInteger(e)||!Number.isInteger(i)||e<=0||i<=0)throw new Error("Displacement dimensions must be positive integers");let n=e*i*4;if(r.length!==n||t.length!==n)throw new Error("Displacement source and map must match the requested dimensions");let a=wl(s.scaleX,10,"Displacement scaleX"),o=wl(s.scaleY,10,"Displacement scaleY"),l=xl[s.channelX??"red"],h=xl[s.channelY??"green"],c=new Uint8ClampedArray(n);for(let u=0;u<i;u+=1)for(let d=0;d<e;d+=1){let g=(u*e+d)*4,p=d+(t[g+l]-128)/127*a,f=u+(t[g+h]-128)/127*o;for(let v=0;v<4;v+=1)c[g+v]=Math.round(Ru(r,e,i,p,f,v))}return c}function Hi(r,t,e,i,s){let n=Math.max(0,Math.min(i,r.left*t)),a=Math.max(0,Math.min(s,r.top*e)),o=Math.max(n,Math.min(i,(r.left+r.width)*t)),l=Math.max(a,Math.min(s,(r.top+r.height)*e));return{left:n,top:a,width:o-n,height:l-a}}function En(r,t,e,i){if(r<=0||t<=0||e<=0||i<=0)throw new Error("Cover dimensions must be positive");let s=Math.max(e/r,i/t),n=r*s,a=t*s;return{left:(e-n)/2,top:(i-a)/2,width:n,height:a}}function Dn(r,t,e){let i=t==="jpeg"?"image/jpeg":`image/${t}`;return new Promise((s,n)=>{r.toBlob(a=>a?s(a):n(new Error(`Failed to export ${t}`)),i,e)})}async function Wr(r,t={}){let{multiplier:e=1,format:i="png",quality:s=1}=t,n=r.toCanvasElement(e);return Dn(n,i,s)}async function zr(r,t,e={}){let i=r.lowerCanvasEl.ownerDocument.createElement("canvas"),s=new Fe(i,{width:e.width??r.getWidth(),height:e.height??r.getHeight(),backgroundColor:e.backgroundColor||void 0});try{let n=e.cloneObjects===!1?t:await Promise.all(t.map(a=>a.clone()));return n.length&&s.add(...n),e.backgroundImage&&(s.backgroundImage=await e.backgroundImage.clone()),s.requestRenderAll(),await Wr(s,e)}finally{s.dispose()}}async function Vi(r,t,e={}){let{multiplier:i=1,format:s="png",quality:n=1}=e,a=r.getWidth(),o=r.getHeight(),l=Hi(t,i,i,a*i,o*i);if(l.width<=0||l.height<=0)throw new Error("Print area does not overlap the canvas");let h=r.lowerCanvasEl.ownerDocument.createElement("canvas"),c=new Fe(h,{width:a,height:o});try{let u=await Promise.all(r.getObjects().map(f=>f.clone()));u.length&&c.add(...u),c.requestRenderAll();let d=c.toCanvasElement(i),g=d.ownerDocument.createElement("canvas");g.width=Math.max(1,Math.round(l.width)),g.height=Math.max(1,Math.round(l.height));let p=g.getContext("2d");if(!p)throw new Error("2D canvas context is unavailable");return p.drawImage(d,-l.left,-l.top),await Dn(g,s,n)}finally{c.dispose()}}async function Ni(r,t,e={}){let{multiplier:i=1,format:s="png",quality:n=1}=e,a=r.toCanvasElement(i),o=a.ownerDocument.createElement("canvas");o.width=a.width,o.height=a.height;let l=o.getContext("2d");if(!l)throw new Error("2D canvas context is unavailable");let h=d=>new Promise((g,p)=>{let f=new Image;f.crossOrigin="anonymous",f.onload=()=>g(f),f.onerror=()=>p(new Error(`Failed to load mockup image: ${d}`)),f.src=d}),c=(d,g=l)=>{let p=En(d.naturalWidth||d.width,d.naturalHeight||d.height,o.width,o.height);g.drawImage(d,p.left,p.top,p.width,p.height)},u=[a];try{c(await h(t.image));let d=a;if(t.displacement){let g=a.getContext("2d");if(!g)throw new Error("2D design context is unavailable");let p=a.ownerDocument.createElement("canvas");u.push(p),p.width=a.width,p.height=a.height;let f=p.getContext("2d");if(!f)throw new Error("2D displacement-map context is unavailable");c(await h(t.displacement.image),f);let v=a.ownerDocument.createElement("canvas");u.push(v),v.width=a.width,v.height=a.height;let y=v.getContext("2d");if(!y)throw new Error("2D displaced-design context is unavailable");let x,w;try{x=g.getImageData(0,0,a.width,a.height).data,w=f.getImageData(0,0,a.width,a.height).data}catch(O){throw new Error("Failed to apply mockup displacement map; verify image CORS access",{cause:O})}let S=zi(x,w,a.width,a.height,{...t.displacement,scaleX:(t.displacement.scaleX??10)*i,scaleY:(t.displacement.scaleY??10)*i}),C=y.createImageData(a.width,a.height);C.data.set(S),y.putImageData(C,0,0),d=v}if(l.save(),t.printArea&&t.clipToPrintArea!==!1){let g=Hi(t.printArea,o.width/r.getWidth(),o.height/r.getHeight(),o.width,o.height);l.beginPath(),l.rect(g.left,g.top,g.width,g.height),l.clip()}return l.globalAlpha=Math.max(0,Math.min(1,t.designOpacity??1)),l.globalCompositeOperation=!t.designBlendMode||t.designBlendMode==="normal"?"source-over":t.designBlendMode,l.drawImage(d,0,0),l.restore(),t.overlay&&(l.save(),l.globalAlpha=Math.max(0,Math.min(1,t.overlay.opacity??1)),l.globalCompositeOperation=t.overlay.blendMode==="normal"?"source-over":t.overlay.blendMode??"multiply",c(await h(t.overlay.image)),l.restore()),await Dn(o,s,n)}finally{for(let d of u)d.width=0,d.height=0}}function Gi(r){return r.toSVG()}function Ui(r,t="png",e=1){return r.toDataURL({format:t,multiplier:e})}function qi(r){return String(r).replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&apos;")}function Ki(r){let t=new DOMParser().parseFromString(r,"image/svg+xml");if(t.querySelector("parsererror"))throw new Error("Invalid template SVG");return t.querySelectorAll("script, foreignObject, iframe, object, embed, link, style").forEach(e=>e.remove()),t.querySelectorAll("*").forEach(e=>{for(let i of[...e.attributes]){let s=i.name.toLowerCase(),n=i.value.trim().toLowerCase(),a=s==="href"||s==="xlink:href"||s==="src",o=n.startsWith("#")||/^data:image\/(?:png|jpeg|webp|gif);base64,/.test(n);(s.startsWith("on")||a&&!o||/url\s*\(/.test(n)&&!/url\s*\(\s*['"]?#/.test(n)||/(?:javascript:|expression\s*\()/.test(n))&&e.removeAttribute(i.name)}}),new XMLSerializer().serializeToString(t.documentElement)}function Bu(r){return/^(?:url|local)\(/.test(r.trim())?r:`url(${JSON.stringify(r)})`}function Xu(r){let t=r.split(/[?#]/)[0].toLowerCase();return t.endsWith(".woff2")?"font/woff2":t.endsWith(".woff")?"font/woff":t.endsWith(".otf")?"font/otf":"font/ttf"}function $u(r){let t=new Uint8Array(r),e="";for(let i=0;i<t.length;i+=32768)e+=String.fromCharCode(...t.subarray(i,i+32768));return btoa(e)}function Ji(r){return JSON.stringify(r).replace(/[<>&]/g,t=>`\\${t.charCodeAt(0).toString(16)} `)}var Yu=/^(?:normal|bold|bolder|lighter|[1-9]\d{0,2}(?:\s+[1-9]\d{0,2})?)$/i,Wu=/^(?:normal|italic|oblique(?:\s+-?\d+(?:\.\d+)?deg)?)$/i,zu=/^(?:auto|block|swap|fallback|optional)$/i;function An(r,t,e){let i=r?.trim();return i&&t.test(i)?i:e}function Hu(r){let t=r.trim();if(t.startsWith("data:"))return t;let e=t.match(/^url\(\s*(['"]?)(.*?)\1\s*\)/i);return e?e[2]:/^local\(/i.test(t)?null:t}function Vu(r){let t=r.trim().match(/^local\(\s*(['"]?)([^)"'{};]*)\1\s*\)$/i);return t&&t[2].trim()||null}var Ge=class{definitions=new Map;loads=new Map;register(t){if(!t.family.trim()||!t.source.trim())throw new Error("Font family and source are required");this.definitions.set(t.family,{...t}),this.loads.delete(t.family)}unregister(t){return this.loads.delete(t),this.definitions.delete(t)}getAll(){return[...this.definitions.values()].map(t=>({...t}))}load(t){let e=this.loads.get(t);if(e)return e;let i=this.definitions.get(t);if(!i)return Promise.reject(new Error(`Font is not registered: ${t}`));if(typeof FontFace>"u"||typeof document>"u")return Promise.reject(new Error("Font loading requires a browser FontFace API"));let s=new FontFace(i.family,Bu(i.source),{weight:i.weight,style:i.style,display:i.display}).load().then(n=>(document.fonts.add(n),n));return s.catch(()=>{this.loads.get(t)===s&&this.loads.delete(t)}),this.loads.set(t,s),s}async ready(){this.definitions.size!==0&&(await Promise.all([...this.definitions.keys()].map(t=>this.load(t))),await document.fonts.ready)}async getEmbeddedCss(){return(await Promise.all(this.getAll().map(async e=>{let i=Hu(e.source),s;if(i&&!i.startsWith("data:")){let l=await fetch(i);if(!l.ok)throw new Error(`Failed to fetch font: ${i}`);let h=$u(await l.arrayBuffer()),c=l.headers.get("content-type")||Xu(i);s=`url(${Ji(`data:${c};base64,${h}`)})`}else if(i)s=`url(${Ji(i)})`;else{let l=Vu(e.source);if(!l)throw new Error(`Unsupported font source for embedding: ${e.family}`);s=`local(${Ji(l)})`}let n=An(e.weight,Yu,"normal"),a=An(e.style,Wu,"normal"),o=An(e.display,zu,"swap");return`@font-face{font-family:${Ji(e.family)};src:${s};font-weight:${n};font-style:${a};font-display:${o}}`}))).join(`
504
+ `}applyTo2d({imageData:{data:r}}){let t=-this.vibrance;for(let e=0;e<r.length;e+=4){let i=r[e],s=r[e+1],n=r[e+2],a=Math.max(i,s,n),o=(i+s+n)/3,l=2*Math.abs(a-o)/255*t;r[e]+=a===i?0:(a-i)*l,r[e+1]+=a===s?0:(a-s)*l,r[e+2]+=a===n?0:(a-n)*l}}sendUniformData(r,t){r.uniform1f(t.uVibrance,-this.vibrance)}isNeutralState(){return this.vibrance===0}};m(Cr,"type","Vibrance"),m(Cr,"defaults",{vibrance:0}),m(Cr,"uniformLocations",["uVibrance"]),_.setClass(Cr);var Lr=Ar({BaseFilter:()=>W,BlackWhite:()=>cu,BlendColor:()=>lr,BlendImage:()=>hr,Blur:()=>cr,Brightness:()=>ur,Brownie:()=>su,ColorMatrix:()=>le,Composed:()=>Xs,Contrast:()=>dr,Convolute:()=>gr,Gamma:()=>pr,Grayscale:()=>fr,HueRotation:()=>oi,Invert:()=>mr,Kodachrome:()=>au,Noise:()=>vr,Pixelate:()=>yr,Polaroid:()=>lu,RemoveColor:()=>br,Resize:()=>xr,Saturation:()=>wr,Sepia:()=>hu,Technicolor:()=>ou,Vibrance:()=>Cr,Vintage:()=>nu});var Le=class{listeners=new Map;on(t,e){this.listeners.has(t)||this.listeners.set(t,new Set),this.listeners.get(t).add(e)}off(t,e){this.listeners.get(t)?.delete(e)}once(t,e){let i=s=>{this.off(t,i),e(s)};this.on(t,i)}emit(t,e){let i=this.listeners.get(t);if(i)for(let s of i)s(e)}removeAllListeners(t){t?this.listeners.delete(t):this.listeners.clear()}};var vn=Ml("crypto");var hl="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";var pu=128,Qt,Re;function fu(r){if(r<0)throw new RangeError("Wrong ID size");try{!Qt||Qt.length<r?(Qt=Buffer.allocUnsafe(r*pu),vn.webcrypto.getRandomValues(Qt),Re=0):Re+r>Qt.length&&(vn.webcrypto.getRandomValues(Qt),Re=0)}catch(t){throw Qt=void 0,t}Re+=r}function cl(r=21){fu(r|=0);let t="";for(let e=Re-r;e<Re;e++)t+=hl[Qt[e]&63];return t}var te=()=>cl(12);var Rr=class{id;type;name;visible;locked;opacity;meta;fabricObject;constructor(t,e,i,s){this.id=s??te(),this.type=t,this.name=i??`${t}-${this.id.slice(0,4)}`,this.visible=!0,this.locked=!1,this.opacity=1,this.meta={},this.fabricObject=e,this.fabricObject._layerId=this.id}hasMeta(){return Object.keys(this.meta).length>0}toData(){return{id:this.id,type:this.type,name:this.name,visible:this.visible,locked:this.locked,opacity:this.opacity,...this.hasMeta()?{meta:this.meta}:{}}}serialize(){return{...this.toData(),fabricObject:this.fabricObject.toObject()}}},Be=class{constructor(t,e){this.canvas=t;this.events=e}canvas;events;layers=[];onPropertyChanged;setHistoryCallback(t){this.onPropertyChanged=t}add(t,e,i,s){let n=new Rr(t,e,i,s);return this.layers.push(n),this.canvas.add(e),this.events.emit("layer:added",{layer:n.toData()}),this.emitChanged(),n}remove(t){let e=this.layers.findIndex(s=>s.id===t);if(e===-1)return!1;let i=this.layers[e];return this.canvas.remove(i.fabricObject),this.layers.splice(e,1),this.events.emit("layer:removed",{layerId:t}),this.emitChanged(),this.onPropertyChanged?.(),!0}replaceObject(t,e){let i=this.get(t);if(!i||i.fabricObject===e)return!1;let s=i.fabricObject,n=this.canvas.getObjects().indexOf(s),a=this.canvas.getActiveObject()===s;return this.canvas.remove(s),i.fabricObject=e,e._layerId=t,e.set({visible:i.visible,opacity:i.opacity,selectable:!i.locked,evented:!i.locked}),this.canvas.insertAt(Math.max(0,n),e),a&&this.canvas.setActiveObject(e),this.canvas.requestRenderAll(),this.events.emit("layer:modified",{layerId:t}),this.emitChanged(),this.onPropertyChanged?.(),!0}reorder(t,e){let i=this.layers.findIndex(a=>a.id===t);if(i===-1||!Number.isFinite(e))return!1;let s=Math.max(0,Math.min(this.layers.length-1,Math.round(e)));if(i===s)return!1;let[n]=this.layers.splice(i,1);return this.layers.splice(s,0,n),this.layers.forEach((a,o)=>{this.canvas.moveObjectTo(a.fabricObject,o)}),this.events.emit("layer:reordered",{layerIds:this.layers.map(a=>a.id)}),this.emitChanged(),this.onPropertyChanged?.(),!0}select(t){if(t===null)this.canvas.discardActiveObject();else{let i=this.get(t);i&&this.canvas.setActiveObject(i.fabricObject)}this.canvas.requestRenderAll(),this.events.emit("layer:selected",{layerId:t});let e=t&&this.get(t)?[t]:[];this.events.emit("selection:changed",{selected:e})}get(t){return this.layers.find(e=>e.id===t)}getAll(){return[...this.layers]}findByObject(t){let e=t._layerId;return e?this.get(e):this.layers.find(i=>i.fabricObject===t)}setVisibility(t,e){let i=this.get(t);i&&i.visible!==e&&(i.visible=e,i.fabricObject.visible=e,this.canvas.requestRenderAll(),this.emitChanged(),this.onPropertyChanged?.())}setLocked(t,e){let i=this.get(t);i&&i.locked!==e&&(i.locked=e,i.fabricObject.selectable=!e,i.fabricObject.evented=!e,this.canvas.requestRenderAll(),this.emitChanged(),this.onPropertyChanged?.())}setOpacity(t,e){let i=this.get(t);if(!i||!Number.isFinite(e))return;let s=Math.max(0,Math.min(1,e));i.opacity!==s&&(i.opacity=s,i.fabricObject.opacity=s,this.canvas.requestRenderAll(),this.emitChanged(),this.onPropertyChanged?.())}setName(t,e){let i=this.get(t);i&&i.name!==e&&(i.name=e,this.emitChanged(),this.onPropertyChanged?.())}setMeta(t,e){let i=this.get(t);if(!i)return;let s={...i.meta},n=!1;for(let[a,o]of Object.entries(e)){if(o===void 0){a in s&&(delete s[a],n=!0);continue}s[a]!==o&&(n=!0),s[a]=o}n&&(i.meta=s,this.emitChanged(),this.onPropertyChanged?.())}clear(){for(let t of this.layers)this.canvas.remove(t.fabricObject);this.layers=[],this.emitChanged()}count(){return this.layers.length}emitChanged(){this.events.emit("layers:changed",{layers:this.layers.map(t=>t.toData())})}};var Xe=class r{static ASSET_KEY="__canvasEditorHistoryAsset";undoStack=[];redoStack=[];assets=new Map;assetIds=new Map;nextAssetId=1;maxSize;maxBytes;paused=!1;debounceTimer=null;debounceMs;getState;restoreState;events;transactionDepth=0;transactionDirty=!1;constructor(t){this.getState=t.getState,this.restoreState=t.restoreState,this.events=t.events,this.maxSize=t.maxSize??50,this.maxBytes=t.maxBytes??50*1024*1024,this.debounceMs=t.debounceMs??300}save(){if(!this.paused){if(this.transactionDepth>0){this.transactionDirty=!0;return}this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(()=>{this.saveImmediate()},this.debounceMs),this.emitChanged()}}saveImmediate(){if(this.paused){this.cancelPending();return}if(this.transactionDepth>0){this.transactionDirty=!0;return}this.cancelPending();let t=this.getState(),e=this.compactState(t);if(this.undoStack.at(-1)===e){this.emitChanged();return}for(this.undoStack.push(e);this.undoStack.length>this.maxSize;)this.undoStack.shift();this.redoStack=[],this.trimToBudget(),this.events.emit("history:snapshot",{bytes:t.length*2,totalBytes:this.snapshotBytes(),entries:this.undoStack.length}),this.emitChanged()}beginTransaction(){this.transactionDepth===0&&this.debounceTimer&&this.saveImmediate(),this.transactionDepth+=1}endTransaction(){this.transactionDepth!==0&&(this.transactionDepth-=1,this.transactionDepth===0&&this.transactionDirty&&(this.transactionDirty=!1,this.saveImmediate()))}async transaction(t){this.beginTransaction();try{return await t()}finally{this.endTransaction()}}async undo(){this.cancelPending();let t=this.undoStack.at(-1);if(!t)return;let e=this.compactState(this.getState()),i=e===t;if(i&&this.undoStack.length<2)return;let s=i?this.undoStack[this.undoStack.length-2]:t;this.paused=!0;try{await this.restoreState(this.expandState(s)),i&&this.undoStack.pop(),this.redoStack.push(e),this.trimToBudget()}catch(n){throw this.events.emit("error",{message:"Failed to undo the last change",error:n}),n}finally{this.paused=!1,this.emitChanged()}}async redo(){this.cancelPending();let t=this.redoStack.at(-1);if(t){this.paused=!0;try{await this.restoreState(this.expandState(t)),this.redoStack.pop(),this.undoStack.at(-1)!==t&&this.undoStack.push(t),this.trimToBudget()}catch(e){throw this.events.emit("error",{message:"Failed to redo the last change",error:e}),e}finally{this.paused=!1,this.emitChanged()}}}isRestoring(){return this.paused}pause(){this.paused=!0}resume(){this.paused=!1}canUndo(){return this.undoStack.length>1||this.debounceTimer!==null}canRedo(){return this.redoStack.length>0}clear(){this.cancelPending(),this.undoStack=[],this.redoStack=[],this.assets.clear(),this.assetIds.clear(),this.emitChanged()}getSnapshotBytes(){return this.snapshotBytes()}cancelPending(){this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null)}dispose(){this.cancelPending(),this.transactionDepth=0,this.transactionDirty=!1,this.undoStack=[],this.redoStack=[],this.assets.clear(),this.assetIds.clear()}emitChanged(){this.events.emit("history:changed",{canUndo:this.canUndo(),canRedo:this.canRedo()})}snapshotBytes(){let t=[...this.undoStack,...this.redoStack].reduce((i,s)=>i+s.length*2,0),e=[...this.assets.values()].reduce((i,s)=>i+s.length*2,0);return t+e}trimToBudget(){for(this.pruneAssets();this.undoStack.length>1&&this.snapshotBytes()>this.maxBytes;)this.undoStack.shift(),this.pruneAssets();for(;this.redoStack.length>1&&this.snapshotBytes()>this.maxBytes;)this.redoStack.shift(),this.pruneAssets()}compactState(t){let e;try{e=JSON.parse(t)}catch{return t}let i=s=>{if(typeof s=="string"&&/^data:image\/(?:png|jpeg|webp);base64,/i.test(s)){let n=this.assetIds.get(s);return n||(n=`a${this.nextAssetId++}`,this.assetIds.set(s,n),this.assets.set(n,s)),{[r.ASSET_KEY]:n}}return Array.isArray(s)?s.map(i):!s||typeof s!="object"?s:Object.fromEntries(Object.entries(s).map(([n,a])=>[n,i(a)]))};return JSON.stringify(i(e))}expandState(t){let e;try{e=JSON.parse(t)}catch{return t}let i=s=>{if(Array.isArray(s))return s.map(i);if(!s||typeof s!="object")return s;let n=s,a=n[r.ASSET_KEY];if(typeof a=="string"&&Object.keys(n).length===1){let o=this.assets.get(a);if(!o)throw new Error(`Missing history raster asset: ${a}`);return o}return Object.fromEntries(Object.entries(n).map(([o,l])=>[o,i(l)]))};return JSON.stringify(i(e))}pruneAssets(){if(this.assets.size===0)return;let t=[...this.undoStack,...this.redoStack];for(let[e,i]of this.assets){let s=`"${r.ASSET_KEY}":"${e}"`;t.some(n=>n.includes(s))||(this.assets.delete(e),this.assetIds.delete(i))}}};var mu="#22c55e",$e=class{constructor(t,e){this.canvas=t;this.events=e;this.onMoving=i=>this.handleMoving(i.target),this.onAfterRender=()=>this.drawGuides(),this.onModified=()=>this.clearGuides(),this.canvas.on("object:moving",this.onMoving),this.canvas.on("after:render",this.onAfterRender),this.canvas.on("mouse:up",this.onModified),this.canvas.on("selection:cleared",this.onModified)}canvas;events;enabled=!1;threshold=8;guides=[];onMoving;onAfterRender;onModified;setEnabled(t){this.enabled!==t&&(this.enabled=t,t||this.clearGuides(),this.events.emit("snap:changed",{enabled:t}))}isEnabled(){return this.enabled}setThreshold(t){this.threshold=Math.max(0,t)}dispose(){this.canvas.off("object:moving",this.onMoving),this.canvas.off("after:render",this.onAfterRender),this.canvas.off("mouse:up",this.onModified),this.canvas.off("selection:cleared",this.onModified),this.guides=[]}handleMoving(t){if(!this.enabled||!t)return;t.setCoords();let e=t.getBoundingRect(),i=this.canvas.getWidth(),s=this.canvas.getHeight(),{xs:n,ys:a}=vu(this.canvas,t,i,s);this.guides=[];let o=ul([e.left,e.left+e.width/2,e.left+e.width],n,this.threshold);o!==null&&(t.set("left",(t.left??0)+o.delta),this.guides.push({x:o.line}));let l=ul([e.top,e.top+e.height/2,e.top+e.height],a,this.threshold);l!==null&&(t.set("top",(t.top??0)+l.delta),this.guides.push({y:l.line})),t.setCoords()}drawGuides(){if(!this.enabled||this.guides.length===0)return;let t=this.canvas.contextTop;if(!t)return;let e=this.canvas.getRetinaScaling(),i=this.canvas.getWidth(),s=this.canvas.getHeight();t.save(),t.setTransform(e,0,0,e,0,0),t.lineWidth=1,t.strokeStyle=mu,t.setLineDash([4,4]),t.beginPath();for(let n of this.guides)n.x!==void 0&&(t.moveTo(n.x,0),t.lineTo(n.x,s)),n.y!==void 0&&(t.moveTo(0,n.y),t.lineTo(i,n.y));t.stroke(),t.restore()}clearGuides(){this.guides.length!==0&&(this.guides=[],this.canvas.clearContext(this.canvas.contextTop))}};function vu(r,t,e,i){let s=[0,e/2,e],n=[0,i/2,i];for(let a of r.getObjects()){if(a===t||!a.visible)continue;a.setCoords();let o=a.getBoundingRect();s.push(o.left,o.left+o.width/2,o.left+o.width),n.push(o.top,o.top+o.height/2,o.top+o.height)}return{xs:s,ys:n}}function ul(r,t,e){let i=null;for(let s of r)for(let n of t){let a=Math.abs(s-n);a<=e&&(i===null||a<i.dist)&&(i={delta:n-s,line:n,dist:a})}return i?{delta:i.delta,line:i.line}:null}function N(r,t,e){return Math.min(e,Math.max(t,r))}function J(r){return Math.round(r*100)/100}var Ye=class{constructor(t,e,i){this.canvas=t;this.history=e;this.events=i;this.onSelectionCleared=()=>{this.session&&this.cancel()},this.canvas.on("selection:cleared",this.onSelectionCleared)}canvas;history;events;session=null;onSelectionCleared;isActive(){return this.session!==null}activeLayerId(){return this.session?.layerId??null}start(t){if(t.type!=="image")return;this.session&&this.cancel();let e=t.fabricObject,i=e.angle??0;i&&e.rotate(0),e.setCoords();let s=e.getBoundingRect(),n=new jt({left:s.left,top:s.top,width:s.width,height:s.height,originX:"left",originY:"top",fill:"rgba(34,197,94,0.12)",stroke:dl,strokeWidth:1,strokeDashArray:[4,4],strokeUniform:!0,lockRotation:!0,cornerColor:dl,transparentCorners:!1});n.setControlsVisibility({mtr:!1});let a=e.selectable??!0,o=e.evented??!0;e.selectable=!1,e.evented=!1,this.canvas.add(n),this.canvas.setActiveObject(n),this.canvas.requestRenderAll(),this.session={layerId:t.id,image:e,rect:n,prevSelectable:a,prevEvented:o,prevAngle:i},this.events.emit("crop:changed",{active:!0,layerId:t.id})}apply(){let t=this.session;if(!t)return;let{image:e,rect:i}=t;i.setCoords(),e.setCoords();let s=e.scaleX??1,n=e.scaleY??1,a=e.left??0,o=e.top??0,l=e.getElement(),h=l.naturalWidth||e.width||0,c=l.naturalHeight||e.height||0,u=(e.cropX??0)+(i.left-a)/s,d=(e.cropY??0)+(i.top-o)/n,g=i.getScaledWidth()/s,p=i.getScaledHeight()/n;u=N(u,0,Math.max(0,h-1)),d=N(d,0,Math.max(0,c-1)),g=N(g,1,h-u),p=N(p,1,c-d),e.set({cropX:u,cropY:d,width:g,height:p,left:a+(u-(e.cropX??0))*s,top:o+(d-(e.cropY??0))*n}),e.setCoords(),t.prevAngle&&(e.rotate(t.prevAngle),e.setCoords()),this.finish(),this.history.save()}cancel(){let t=this.session;t&&(t.prevAngle&&(t.image.rotate(t.prevAngle),t.image.setCoords()),this.finish())}dispose(){this.cancel(),this.canvas.off("selection:cleared",this.onSelectionCleared)}finish(){let t=this.session;t&&(this.session=null,this.canvas.remove(t.rect),t.image.selectable=t.prevSelectable,t.image.evented=t.prevEvented,this.canvas.setActiveObject(t.image),this.canvas.requestRenderAll(),this.events.emit("crop:changed",{active:!1,layerId:null}))}},dl="#22c55e";var ml=200,We=class{constructor(t,e,i,s,n){this.canvas=t;this.layers=e;this.history=i;this.events=s;this.sourceResolver=n}canvas;layers;history;events;sourceResolver;chains=new Map;isPattern(t){return!!this.layers.get(t)?.meta.pattern}getConfig(t){return this.layers.get(t)?.meta.pattern?.config??null}apply(t,e){return this.enqueue(t,async()=>{let i=this.layers.get(t);if(!i||i.type!=="image")return;let s=i.fabricObject,n=!i.meta.pattern;if(i.meta.pattern)i.meta.pattern.config=e;else{let a=s.clipPath;i.meta.pattern={config:e,originalSrc:yu(s)??s.getSrc(),originalClip:a?a.toObject():null,originalLocks:yn(s),original:{left:s.left??0,top:s.top??0,scaleX:s.scaleX??1,scaleY:s.scaleY??1,width:s.width??0,height:s.height??0,angle:s.angle??0,cropX:s.cropX??0,cropY:s.cropY??0}}}try{await this.renderLayer(i)}catch(a){throw n&&delete i.meta.pattern,a}this.history.save()}).catch(i=>{throw this.events.emit("error",{message:"Failed to apply image pattern",error:i}),i})}repinAll(){let t=this.canvas.getWidth(),e=this.canvas.getHeight(),i=!1;for(let s of this.layers.getAll()){if(!s.meta.pattern||s.type!=="image")continue;let n=s.fabricObject;n.set({left:0,top:0,angle:0,scaleX:t/(n.width||t),scaleY:e/(n.height||e)}),ji(n),n.setCoords(),i=!0}i&&this.canvas.requestRenderAll()}disable(t){return this.enqueue(t,async()=>{let e=this.layers.get(t),i=e?.meta.pattern;if(!e||!i)return;let s=e.fabricObject;await s.setSrc(i.originalSrc),s.set({left:i.original.left,top:i.original.top,scaleX:i.original.scaleX,scaleY:i.original.scaleY,width:i.original.width,height:i.original.height,cropX:i.original.cropX,cropY:i.original.cropY,angle:i.original.angle}),s.clipPath=i.originalClip?(await Zt.enlivenObjects([i.originalClip]))[0]:void 0,bn(s,i.originalLocks),s.setCoords(),delete e.meta.pattern,this.canvas.requestRenderAll(),this.history.save()}).catch(e=>{throw this.events.emit("error",{message:"Failed to clear image pattern",error:e}),e})}enqueue(t,e){let s=(this.chains.get(t)??Promise.resolve()).then(e,e);return this.chains.set(t,s.catch(()=>{})),s}async renderLayer(t){let e=t.meta.pattern;if(!e)return;let i=t.fabricObject,s=this.canvas.getWidth(),n=this.canvas.getHeight(),a=Math.max(1,e.config.scale??100)/100,o=Math.sqrt(s*s+n*n),l=Math.max(2,o/ml),h=Math.max(l,e.original.width*e.original.scaleX*a),c=Math.max(l,e.original.height*e.original.scaleY*a),u=await wn(e.originalSrc,e.config,s,n,h,c,this.sourceResolver);await i.setSrc(u),i.set({left:0,top:0,scaleX:1,scaleY:1,width:s,height:n,cropX:0,cropY:0,angle:0}),i.clipPath=void 0,ji(i),i.setCoords(),this.canvas.requestRenderAll()}};function yn(r){return{lockMovementX:r.lockMovementX??!1,lockMovementY:r.lockMovementY??!1,lockScalingX:r.lockScalingX??!1,lockScalingY:r.lockScalingY??!1,lockRotation:r.lockRotation??!1,hasControls:r.hasControls??!0}}function ji(r){r.set({lockMovementX:!0,lockMovementY:!0,lockScalingX:!0,lockScalingY:!0,lockRotation:!0,hasControls:!1})}function bn(r,t){r.set(t??{lockMovementX:!1,lockMovementY:!1,lockScalingX:!1,lockScalingY:!1,lockRotation:!1,hasControls:!0})}function yu(r){try{let t=r.getElement(),e=t.naturalWidth||t.width,i=t.naturalHeight||t.height;if(!e||!i)return null;let s=document.createElement("canvas");s.width=e,s.height=i;let n=s.getContext("2d");return n?(n.drawImage(t,0,0),s.toDataURL("image/png")):null}catch{return null}}var bu=16,Mt=new Map;function xn(r,t){let e=Mt.get(r);if(e)return Mt.delete(r),Mt.set(r,e),e;let i=gl(r).catch(async s=>{if(!t)throw s;let n=await t(r);if(!n||n===r)throw new Error("Pattern source resolver did not return a usable alternate URL",{cause:s});return gl(n)});if(i.catch(()=>{Mt.get(r)===i&&Mt.delete(r)}),Mt.set(r,i),Mt.size>bu){let s=Mt.keys().next().value;s!==void 0&&Mt.delete(s)}return i}function gl(r){return new Promise((t,e)=>{let i=new Image;i.crossOrigin="anonymous",i.onload=()=>t(i),i.onerror=()=>e(new Error(`Failed to load pattern source: ${r}`)),i.src=r})}function Ii(){Mt.clear()}async function wn(r,t,e,i,s,n,a){let o=await xn(r,a),l=document.createElement("canvas");l.width=Math.max(1,Math.round(e)),l.height=Math.max(1,Math.round(i));let h=l.getContext("2d");return h&&Sn(h,o,t,e,i,s,n),l.toDataURL("image/png")}function Cn(r,t,e,i,s){let n=Math.sqrt(t*t+e*e),a=Math.max(1,n/ml),o=Math.max(a,i*(1+r.horizontalSpacing/100)),l=Math.max(a,s*(1+r.verticalSpacing/100)),h=Math.ceil(n/o)+2,c=Math.ceil(n/l)+2,u=Math.ceil(h/2),d=Math.ceil(c/2),g=o*(pl(r.offsetX)/100),p=l*(pl(r.offsetY)/100),f=[];for(let v=-d;v<=d;v++)for(let y=-u;y<=u;y++){let x=y*o+g,w=v*l+p;r.mode==="brick-horizontal"&&fl(v)===1?x+=o*(r.horizontalOffset/100):r.mode==="brick-vertical"&&fl(y)===1&&(w+=l*(r.horizontalOffset/100));let S=(y*r.rotationStepH+v*r.rotationStepV)*Math.PI/180;f.push({x,y:w,rotation:S})}return f}function Sn(r,t,e,i,s,n,a){r.save(),r.translate(i/2,s/2),r.rotate(e.angle*Math.PI/180);for(let o of Cn(e,i,s,n,a))r.save(),r.translate(o.x,o.y),r.rotate(o.rotation),r.drawImage(t,-n/2,-a/2,n,a),r.restore();r.restore()}function pl(r){return typeof r!="number"||!Number.isFinite(r)?0:Math.max(-100,Math.min(100,r))}function fl(r){return(r%2+2)%2}var Fi={arc:0,wave:0},_n=.5,xu=99.5,wu=.12,Cu=4.1,Su=.9,_u=6,Tu=1e5,ku=.06;function vl(r){return!!r&&typeof r.text=="string"}function Ou(r){let t=r.width;try{return r.set({width:Tu}),r.initDimensions?.(),Math.max(1,r.calcTextWidth?.()??r.width??1)}finally{t!==void 0&&r.set({width:t}),r.initDimensions?.()}}function Mu(r,t){let e=Math.min(100,Math.abs(t)),i=t<0?-1:1,s=e>=xu,n=s?Math.PI*2:Math.max(wu,e/100*Math.PI),a=r/n,o=r/2,l=p=>[o+a*Math.sin(p),i*a*(1-Math.cos(p))],h=i>0?1:0,c=([p,f])=>`${Pt(p)} ${Pt(f)}`;if(s){let p=l(-Math.PI),f=l(0);return{data:[`M ${c(p)}`,`A ${Pt(a)} ${Pt(a)} 0 0 ${h} ${c(f)}`,`A ${Pt(a)} ${Pt(a)} 0 0 ${h} ${c(p)}`].join(" "),length:r}}let u=l(-n/2),d=l(n/2),g=n>Math.PI?1:0;return{data:`M ${c(u)} A ${Pt(a)} ${Pt(a)} 0 ${g} ${h} ${c(d)}`,length:r}}function Pu(r,t,e){let i=N(e,0,100)/100*t*Su,s=Math.max(1,t*Cu),n=Math.max(2,Math.ceil(r/_u)),a=[],o=0,l=null;for(let h=0;h<=n;h++){let c=r*h/n,u=i*Math.sin(c/s*Math.PI*2);l&&(o+=Math.hypot(c-l[0],u-l[1])),l=[c,u],a.push(`${h===0?"M":"L"} ${Pt(c)} ${Pt(u)}`)}return{data:a.join(" "),length:o}}function Pt(r){return Math.round(r*100)/100}function Tn(r,t,e){return Math.abs(r.arc)>=_n?Mu(t,r.arc):r.wave>0?Pu(t,e,r.wave):null}function Eu(r){let t=N(r.arc??0,-100,100);return{arc:t,wave:Math.abs(t)>=_n?0:N(r.wave??0,0,100)}}var ze=class{constructor(t,e,i,s){this.canvas=t;this.layers=e;this.history=i;this.events=s}canvas;layers;history;events;get(t){let e=this.layers.get(t);return!e||!vl(e.fabricObject)?null:e.meta.curve??{...Fi}}isCurved(t){let e=this.get(t);return!!e&&(Math.abs(e.arc)>=_n||e.wave>0)}apply(t,e,i=!0){let s=this.layers.get(t);if(!s||!vl(s.fabricObject))return!1;let n=Eu(e),a=s.fabricObject,o=Ou(a),l=Tn(n,o*(1+ku),a.fontSize);return l?(s.meta.curveWidth===void 0&&(s.meta.curveWidth=a.width??0),a.set({width:Math.max(s.meta.curveWidth,o+2)}),a.set({path:new It(l.data,{visible:!1,objectCaching:!1}),pathAlign:"center",pathSide:"left",pathStartOffset:Math.max(0,(l.length-o)/2)}),s.meta.curve=n):(this.detach(a,s.meta.curveWidth),delete s.meta.curve,delete s.meta.curveWidth),a.initDimensions?.(),a.setCoords(),a.dirty=!0,this.canvas.requestRenderAll(),this.events.emit("layer:modified",{layerId:t}),i&&this.history.save(),!0}clear(t,e=!0){return this.apply(t,Fi,e)}refresh(t,e=!1){let i=this.layers.get(t)?.meta.curve;return i?this.apply(t,i,e):!1}refreshAll(){for(let t of this.layers.getAll())t.meta.curve&&this.refresh(t.id)}detach(t,e){t.set({path:null,pathStartOffset:0}),e!==void 0&&e>0&&t.set({width:e})}};var Li=["circle","square","triangle","star","heart","octagram","arch","zigzag"];function He(r){return typeof r=="string"&&Li.includes(r)}function kn(r,t,e,i=-Math.PI/2){let s=Math.PI/r,n=[];for(let a=0;a<r*2;a++){let o=a%2===0?t:e,l=i+a*s,h=50+Math.cos(l)*o,c=50+Math.sin(l)*o;n.push(`${a===0?"M":"L"} ${yl(h)} ${yl(c)}`)}return`${n.join(" ")} Z`}function yl(r){return Math.round(r*100)/100}var Du={circle:"M 96 50 A 46 46 0 1 1 4 50 A 46 46 0 1 1 96 50 Z",square:"M 4 4 H 96 V 96 H 4 Z",triangle:"M 50 4 L 96 96 L 4 96 Z",star:kn(5,46,22),heart:"M 50 96 C -8 55 12 4 50 28 C 88 4 108 55 50 96 Z",octagram:kn(8,46,27),arch:"M 4 96 V 50 A 46 46 0 0 1 96 50 V 96 Z",zigzag:kn(16,46,39)};function Br(r){return Du[r]}var Ve=100;var Ri=["vignette","halftone","spray","grunge","torn","band"];function Xr(r){return typeof r=="string"&&Ri.includes(r)}var Et=320,Mn=new Map;function On(r){let t=r;return()=>(t=t*16807%2147483647,(t-1)/2147483646)}function bl(r,t,e,i){let s=Et,n=[[i,i],[s-i,i],[s-i,s-i],[i,s-i]];r.beginPath();for(let a=0;a<n.length;a++){let[o,l]=n[a],[h,c]=n[(a+1)%n.length];for(let u=0;u<=26;u++){let d=u/26,g=o+(h-o)*d+(t()-.5)*e,p=l+(c-l)*d+(t()-.5)*e;a===0&&u===0?r.moveTo(g,p):r.lineTo(g,p)}}r.closePath(),r.fill()}function Au(r,t){let e=Et,i=e/2;switch(t.fillStyle="#ffffff",r){case"vignette":{let s=t.createRadialGradient(i,i,e*.18,i,i,e*.52);s.addColorStop(0,"rgba(255,255,255,1)"),s.addColorStop(1,"rgba(255,255,255,0)"),t.fillStyle=s,t.fillRect(0,0,e,e);return}case"band":{let s=t.createLinearGradient(0,0,0,e);s.addColorStop(0,"rgba(255,255,255,0)"),s.addColorStop(.25,"rgba(255,255,255,1)"),s.addColorStop(.75,"rgba(255,255,255,1)"),s.addColorStop(1,"rgba(255,255,255,0)"),t.fillStyle=s,t.fillRect(0,0,e,e);return}case"halftone":{for(let n=16/2;n<e;n+=16)for(let a=16/2;a<e;a+=16){let o=Math.hypot(a-i,n-i)/(e*.52),l=Math.max(0,16/2*(1-o)*1.15);l<.4||(t.beginPath(),t.arc(a,n,l,0,Math.PI*2),t.fill())}return}case"spray":{let s=On(42),n=t.createRadialGradient(i,i,10,i,i,e*.42);n.addColorStop(0,"rgba(255,255,255,1)"),n.addColorStop(1,"rgba(255,255,255,0.85)"),t.fillStyle=n,t.beginPath(),t.arc(i,i,e*.42,0,Math.PI*2),t.fill(),t.fillStyle="rgba(255,255,255,0.9)";for(let a=0;a<900;a++){let o=s()*Math.PI*2,l=e*(.3+s()*.24),h=i+Math.cos(o)*l,c=i+Math.sin(o)*l;t.globalAlpha=1-(l/e-.3)/.24,t.beginPath(),t.arc(h,c,s()*2.4,0,Math.PI*2),t.fill()}t.globalAlpha=1;return}case"grunge":{let s=On(7);bl(t,s,14,e*.06),t.globalCompositeOperation="destination-out";for(let n=0;n<240;n++){let a=s()*e,o=s()*e;!(Math.min(a,o,e-a,e-o)<e*.12)&&s()>=.12||(t.beginPath(),t.arc(a,o,s()*6+1,0,Math.PI*2),t.fill())}t.globalCompositeOperation="source-over";return}case"torn":{bl(t,On(99),10,e*.08);return}}}function $r(r){let t=Mn.get(r);if(t)return t;if(typeof document>"u")throw new Error("Texture masks require a DOM canvas");let e=document.createElement("canvas");e.width=Et,e.height=Et;let i=e.getContext("2d");if(!i)throw new Error("Texture masks require a 2D canvas context");return Au(r,i),Mn.set(r,e),e}function Pn(){Mn.clear()}function Bi(r){return He(r)||Xr(r)}var me=class{constructor(t,e,i,s){this.canvas=t;this.layers=e;this.history=i;this.events=s}canvas;layers;history;events;get(t){return this.layers.get(t)?.meta.maskPreset??null}apply(t,e,i=!0){let s=this.layers.get(t);if(!s)return!1;let n=s.fabricObject;if(e===null){if(!s.meta.maskPreset)return!1;n.clipPath=void 0,delete s.meta.maskPreset}else{if(!Bi(e))return!1;n.clipPath=this.buildClip(e,n),s.meta.maskPreset=e}return n.dirty=!0,n.setCoords(),this.canvas.requestRenderAll(),this.events.emit("layer:modified",{layerId:t}),i&&this.history.save(),!0}clear(t,e=!0){return this.apply(t,null,e)}refresh(t,e=!1){let i=this.get(t);return i?this.apply(t,i,e):!1}refreshAll(){for(let t of this.layers.getAll())t.meta.maskPreset&&this.refresh(t.id)}buildClip(t,e){let i=Math.max(1,e.width??1),s=Math.max(1,e.height??1),n={originX:"center",originY:"center",left:0,top:0,objectCaching:!1};return He(t)?new It(Br(t),{...n,scaleX:i/Ve,scaleY:s/Ve}):new V($r(t),{...n,scaleX:i/Et,scaleY:s/Et})}};var ju=/^(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\([\d.%+\-\s,/]+\)|[a-z]+)$/i;function ee(r,t=!1){if(typeof r!="string")return!1;let e=r.trim();return e?ju.test(e):t}var re={enabled:!1,color:"#000000",blur:12,offsetX:6,offsetY:6};function Yr(r){let t=r.shadow;return!t||typeof t=="string"?{...re}:{enabled:!0,color:typeof t.color=="string"?t.color:re.color,blur:t.blur??re.blur,offsetX:t.offsetX??re.offsetX,offsetY:t.offsetY??re.offsetY}}function Xi(r,t){let e={...Yr(r),...t};if(!e.enabled){r.set({shadow:null});return}let i=ee(e.color)?e.color:re.color;r.set({shadow:new he({color:i,blur:Math.max(0,e.blur),offsetX:e.offsetX,offsetY:e.offsetY})})}var Iu=["ml","mr","mt","mb"];function ve(r,t){for(let e of Iu)r.setControlVisible(e,!t)}function $i(r){r.set({scaleX:1,scaleY:1,angle:0,skewX:0,skewY:0,flipX:!1,flipY:!1}),r.setCoords()}var Ne=class{unit;dpi;constructor(t="px",e=72){this.unit=t,this.dpi=72,this.setDpi(e)}setUnit(t){this.unit=t}setDpi(t){if(!Number.isFinite(t)||t<=0)throw new Error("DPI must be a positive number");this.dpi=t}getUnit(){return this.unit}getDpi(){return this.dpi}toPixels(t,e){switch(e??this.unit){case"px":return t;case"in":return t*this.dpi;case"mm":return t/25.4*this.dpi}}fromPixels(t,e){switch(e??this.unit){case"px":return t;case"in":return t/this.dpi;case"mm":return t/this.dpi*25.4}}};var Fu="2.0.0";function Yi(r){return{version:Fu,canvas:{width:r.canvas.getWidth(),height:r.canvas.getHeight(),unit:r.units.getUnit(),dpi:r.units.getDpi()},layers:r.layers.getAll().map(t=>t.serialize()),background:r.getDesignBackground(),backgroundImage:r.getDesignBackgroundImage()?r.getDesignBackgroundImage().toObject():null,backgroundImageOptions:r.getBackgroundImageOptions(),mockup:r.getMockup()}}async function Wi(r,t){if(!t||!t.canvas||!Array.isArray(t.layers))throw new Error("Invalid editor state");if(!Number.isFinite(t.canvas.width)||!Number.isFinite(t.canvas.height)||t.canvas.width<=0||t.canvas.height<=0||t.canvas.unit!==void 0&&!["px","mm","in"].includes(t.canvas.unit)||t.canvas.dpi!==void 0&&(!Number.isFinite(t.canvas.dpi)||t.canvas.dpi<=0))throw new Error("Invalid editor canvas settings");let e=Number.parseInt(t.version?.split(".")[0]??"1",10);if(!Number.isFinite(e)||e>2)throw new Error(`Unsupported editor state version: ${t.version}`);if(t.background!==void 0&&!ee(t.background,!0))throw new Error("Invalid editor background color");let i=await Promise.all(t.layers.map(async n=>{let a=(await Zt.enlivenObjects([n.fabricObject]))[0];if(!a){let o=n.fabricObject.src;throw typeof o=="string"&&o.startsWith("blob:")?new Error(`Failed to restore expired object URL: ${o}`):new Error(`Failed to restore layer: ${n.id}`)}return{serialized:n,fabricObject:a}})),s=t.backgroundImage?(await Zt.enlivenObjects([t.backgroundImage]))[0]:null;if(t.backgroundImage&&!s){let n=t.backgroundImage.src;throw typeof n=="string"&&n.startsWith("blob:")?new Error(`Failed to restore expired background object URL: ${n}`):new Error("Failed to restore background image")}r.crop.cancel(),r.masks.detach(),r.layers.clear(),t.canvas.unit&&r.units.setUnit(t.canvas.unit),t.canvas.dpi!==void 0&&r.units.setDpi(t.canvas.dpi),r.canvas.setDimensions({width:t.canvas.width,height:t.canvas.height}),t.background!==void 0&&r.setBackground(t.background),r.setBackgroundImageObject(s??null,!1,t.backgroundImageOptions??null),r.setMockup(t.mockup??null);for(let n of i)Lu(r,n.serialized,n.fabricObject);r.canvas.requestRenderAll()}function Lu(r,t,e){let i=r.layers.add(t.type,e,t.name,t.id);return t.meta&&(i.meta=t.meta,i.meta.lockAspect&&ve(e,!0)),t.visible||r.layers.setVisibility(i.id,!1),t.locked&&r.layers.setLocked(i.id,!0),t.opacity!==1&&r.layers.setOpacity(i.id,t.opacity),i}var xl={red:0,green:1,blue:2,alpha:3};function wl(r,t,e){let i=r??t;if(!Number.isFinite(i))throw new Error(`${e} must be finite`);return i}function Ru(r,t,e,i,s,n){let a=Math.max(0,Math.min(t-1,i)),o=Math.max(0,Math.min(e-1,s)),l=Math.floor(a),h=Math.floor(o),c=Math.min(t-1,l+1),u=Math.min(e-1,h+1),d=a-l,g=o-h,p=r[(h*t+l)*4+n]*(1-d)+r[(h*t+c)*4+n]*d,f=r[(u*t+l)*4+n]*(1-d)+r[(u*t+c)*4+n]*d;return p*(1-g)+f*g}function zi(r,t,e,i,s){if(!Number.isInteger(e)||!Number.isInteger(i)||e<=0||i<=0)throw new Error("Displacement dimensions must be positive integers");let n=e*i*4;if(r.length!==n||t.length!==n)throw new Error("Displacement source and map must match the requested dimensions");let a=wl(s.scaleX,10,"Displacement scaleX"),o=wl(s.scaleY,10,"Displacement scaleY"),l=xl[s.channelX??"red"],h=xl[s.channelY??"green"],c=new Uint8ClampedArray(n);for(let u=0;u<i;u+=1)for(let d=0;d<e;d+=1){let g=(u*e+d)*4,p=d+(t[g+l]-128)/127*a,f=u+(t[g+h]-128)/127*o;for(let v=0;v<4;v+=1)c[g+v]=Math.round(Ru(r,e,i,p,f,v))}return c}function Hi(r,t,e,i,s){let n=Math.max(0,Math.min(i,r.left*t)),a=Math.max(0,Math.min(s,r.top*e)),o=Math.max(n,Math.min(i,(r.left+r.width)*t)),l=Math.max(a,Math.min(s,(r.top+r.height)*e));return{left:n,top:a,width:o-n,height:l-a}}function En(r,t,e,i){if(r<=0||t<=0||e<=0||i<=0)throw new Error("Cover dimensions must be positive");let s=Math.max(e/r,i/t),n=r*s,a=t*s;return{left:(e-n)/2,top:(i-a)/2,width:n,height:a}}function Dn(r,t,e){let i=t==="jpeg"?"image/jpeg":`image/${t}`;return new Promise((s,n)=>{r.toBlob(a=>a?s(a):n(new Error(`Failed to export ${t}`)),i,e)})}async function Wr(r,t={}){let{multiplier:e=1,format:i="png",quality:s=1}=t,n=r.toCanvasElement(e);return Dn(n,i,s)}async function zr(r,t,e={}){let i=r.lowerCanvasEl.ownerDocument.createElement("canvas"),s=new Fe(i,{width:e.width??r.getWidth(),height:e.height??r.getHeight(),backgroundColor:e.backgroundColor||void 0});try{let n=e.cloneObjects===!1?t:await Promise.all(t.map(a=>a.clone()));return n.length&&s.add(...n),e.backgroundImage&&(s.backgroundImage=await e.backgroundImage.clone()),s.requestRenderAll(),await Wr(s,e)}finally{s.dispose()}}async function Vi(r,t,e={}){let{multiplier:i=1,format:s="png",quality:n=1}=e,a=r.getWidth(),o=r.getHeight(),l=Hi(t,i,i,a*i,o*i);if(l.width<=0||l.height<=0)throw new Error("Print area does not overlap the canvas");let h=r.lowerCanvasEl.ownerDocument.createElement("canvas"),c=new Fe(h,{width:a,height:o});try{let u=await Promise.all(r.getObjects().map(f=>f.clone()));u.length&&c.add(...u),c.requestRenderAll();let d=c.toCanvasElement(i),g=d.ownerDocument.createElement("canvas");g.width=Math.max(1,Math.round(l.width)),g.height=Math.max(1,Math.round(l.height));let p=g.getContext("2d");if(!p)throw new Error("2D canvas context is unavailable");return p.drawImage(d,-l.left,-l.top),await Dn(g,s,n)}finally{c.dispose()}}async function Ni(r,t,e={}){let{multiplier:i=1,format:s="png",quality:n=1}=e,a=r.toCanvasElement(i),o=a.ownerDocument.createElement("canvas");o.width=a.width,o.height=a.height;let l=o.getContext("2d");if(!l)throw new Error("2D canvas context is unavailable");let h=d=>new Promise((g,p)=>{let f=new Image;f.crossOrigin="anonymous",f.onload=()=>g(f),f.onerror=()=>p(new Error(`Failed to load mockup image: ${d}`)),f.src=d}),c=(d,g=l)=>{let p=En(d.naturalWidth||d.width,d.naturalHeight||d.height,o.width,o.height);g.drawImage(d,p.left,p.top,p.width,p.height)},u=[a];try{c(await h(t.image));let d=a;if(t.displacement){let g=a.getContext("2d");if(!g)throw new Error("2D design context is unavailable");let p=a.ownerDocument.createElement("canvas");u.push(p),p.width=a.width,p.height=a.height;let f=p.getContext("2d");if(!f)throw new Error("2D displacement-map context is unavailable");c(await h(t.displacement.image),f);let v=a.ownerDocument.createElement("canvas");u.push(v),v.width=a.width,v.height=a.height;let y=v.getContext("2d");if(!y)throw new Error("2D displaced-design context is unavailable");let x,w;try{x=g.getImageData(0,0,a.width,a.height).data,w=f.getImageData(0,0,a.width,a.height).data}catch(O){throw new Error("Failed to apply mockup displacement map; verify image CORS access",{cause:O})}let S=zi(x,w,a.width,a.height,{...t.displacement,scaleX:(t.displacement.scaleX??10)*i,scaleY:(t.displacement.scaleY??10)*i}),C=y.createImageData(a.width,a.height);C.data.set(S),y.putImageData(C,0,0),d=v}if(l.save(),t.printArea&&t.clipToPrintArea!==!1){let g=Hi(t.printArea,o.width/r.getWidth(),o.height/r.getHeight(),o.width,o.height);l.beginPath(),l.rect(g.left,g.top,g.width,g.height),l.clip()}return l.globalAlpha=Math.max(0,Math.min(1,t.designOpacity??1)),l.globalCompositeOperation=!t.designBlendMode||t.designBlendMode==="normal"?"source-over":t.designBlendMode,l.drawImage(d,0,0),l.restore(),t.overlay&&(l.save(),l.globalAlpha=Math.max(0,Math.min(1,t.overlay.opacity??1)),l.globalCompositeOperation=t.overlay.blendMode==="normal"?"source-over":t.overlay.blendMode??"multiply",c(await h(t.overlay.image)),l.restore()),await Dn(o,s,n)}finally{for(let d of u)d.width=0,d.height=0}}function Gi(r){return r.toSVG()}function Ui(r,t="png",e=1){return r.toDataURL({format:t,multiplier:e})}function qi(r){return String(r).replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&apos;")}function Ki(r){let t=new DOMParser().parseFromString(r,"image/svg+xml");if(t.querySelector("parsererror"))throw new Error("Invalid template SVG");return t.querySelectorAll("script, foreignObject, iframe, object, embed, link, style").forEach(e=>e.remove()),t.querySelectorAll("*").forEach(e=>{for(let i of[...e.attributes]){let s=i.name.toLowerCase(),n=i.value.trim().toLowerCase(),a=s==="href"||s==="xlink:href"||s==="src",o=n.startsWith("#")||/^data:image\/(?:png|jpeg|webp|gif);base64,/.test(n);(s.startsWith("on")||a&&!o||/url\s*\(/.test(n)&&!/url\s*\(\s*['"]?#/.test(n)||/(?:javascript:|expression\s*\()/.test(n))&&e.removeAttribute(i.name)}}),new XMLSerializer().serializeToString(t.documentElement)}function Bu(r){return/^(?:url|local)\(/.test(r.trim())?r:`url(${JSON.stringify(r)})`}function Xu(r){let t=r.split(/[?#]/)[0].toLowerCase();return t.endsWith(".woff2")?"font/woff2":t.endsWith(".woff")?"font/woff":t.endsWith(".otf")?"font/otf":"font/ttf"}function $u(r){let t=new Uint8Array(r),e="";for(let i=0;i<t.length;i+=32768)e+=String.fromCharCode(...t.subarray(i,i+32768));return btoa(e)}function Ji(r){return JSON.stringify(r).replace(/[<>&]/g,t=>`\\${t.charCodeAt(0).toString(16)} `)}var Yu=/^(?:normal|bold|bolder|lighter|[1-9]\d{0,2}(?:\s+[1-9]\d{0,2})?)$/i,Wu=/^(?:normal|italic|oblique(?:\s+-?\d+(?:\.\d+)?deg)?)$/i,zu=/^(?:auto|block|swap|fallback|optional)$/i;function An(r,t,e){let i=r?.trim();return i&&t.test(i)?i:e}function Hu(r){let t=r.trim();if(t.startsWith("data:"))return t;let e=t.match(/^url\(\s*(['"]?)(.*?)\1\s*\)/i);return e?e[2]:/^local\(/i.test(t)?null:t}function Vu(r){let t=r.trim().match(/^local\(\s*(['"]?)([^)"'{};]*)\1\s*\)$/i);return t&&t[2].trim()||null}var Ge=class{definitions=new Map;loads=new Map;register(t){if(!t.family.trim()||!t.source.trim())throw new Error("Font family and source are required");this.definitions.set(t.family,{...t}),this.loads.delete(t.family)}unregister(t){return this.loads.delete(t),this.definitions.delete(t)}getAll(){return[...this.definitions.values()].map(t=>({...t}))}load(t){let e=this.loads.get(t);if(e)return e;let i=this.definitions.get(t);if(!i)return Promise.reject(new Error(`Font is not registered: ${t}`));if(typeof FontFace>"u"||typeof document>"u")return Promise.reject(new Error("Font loading requires a browser FontFace API"));let s=new FontFace(i.family,Bu(i.source),{weight:i.weight,style:i.style,display:i.display}).load().then(n=>(document.fonts.add(n),n));return s.catch(()=>{this.loads.get(t)===s&&this.loads.delete(t)}),this.loads.set(t,s),s}async ready(){this.definitions.size!==0&&(await Promise.all([...this.definitions.keys()].map(t=>this.load(t))),await document.fonts.ready)}async getEmbeddedCss(){return(await Promise.all(this.getAll().map(async e=>{let i=Hu(e.source),s;if(i&&!i.startsWith("data:")){let l=await fetch(i);if(!l.ok)throw new Error(`Failed to fetch font: ${i}`);let h=$u(await l.arrayBuffer()),c=l.headers.get("content-type")||Xu(i);s=`url(${Ji(`data:${c};base64,${h}`)})`}else if(i)s=`url(${Ji(i)})`;else{let l=Vu(e.source);if(!l)throw new Error(`Unsupported font source for embedding: ${e.family}`);s=`local(${Ji(l)})`}let n=An(e.weight,Yu,"normal"),a=An(e.style,Wu,"normal"),o=An(e.display,zu,"swap");return`@font-face{font-family:${Ji(e.family)};src:${s};font-weight:${n};font-style:${a};font-display:${o}}`}))).join(`
505
505
  `)}};function Nu(r,t){let e=r.toLowerCase(),i=t.toLowerCase();if(i.startsWith("*.")){let s=i.slice(1);return e.endsWith(s)&&e.length>s.length}return e===i}function Gu(r){return r==="localhost"||r==="127.0.0.1"||r==="::1"||r.endsWith(".localhost")}var Ue=class{constructor(t={}){this.config=t;let e=t.hostname??globalThis.location?.hostname??"localhost";(t.environment??"development")!=="production"||Gu(e)?(this.status={state:"exempt",payload:null},this.readyPromise=Promise.resolve(this.status)):t.key?(this.status={state:"checking",payload:null},this.readyPromise=this.validate(t.key,e)):(this.status={state:"community",payload:null},this.readyPromise=Promise.resolve(this.status))}config;status;readyPromise;getStatus(){return this.status}ready(){return this.readyPromise}hasFeature(t){return this.status.state==="valid"&&(this.status.payload.features??[]).includes(t)}track(t){this.config.onUsage?.({name:t,at:new Date().toISOString(),licenseId:this.status.state==="valid"?this.status.payload.id:void 0})}async validate(t,e){let i=await this.config.verifyOffline?.(t)??null;return i?i.expiresAt&&Date.parse(i.expiresAt)<Date.now()?this.status={state:"expired",payload:i}:i.domains.some(s=>Nu(e,s))?this.status={state:"valid",payload:i}:this.status={state:"domain-mismatch",payload:i}:this.status={state:"invalid",payload:null}}};var qe=class{constructor(t){this.editor=t;let e={id:te(),name:"Page 1",state:t.toJSON()};this.pages=[e],this.activePageId=e.id}editor;pages;activePageId;getAll(){return this.pages.map(({id:t,name:e})=>({id:t,name:e}))}getActivePageId(){return this.activePageId}add(t=`Page ${this.pages.length+1}`,e=!1){this.saveCurrent();let i=structuredClone(this.editor.toJSON()),s=e?i:this.blankState(i),n={id:te(),name:t,state:s};return this.pages.push(n),this.emitChanged(),n.id}async switchTo(t){if(t===this.activePageId)return!0;let e=this.pages.find(i=>i.id===t);return e?(this.saveCurrent(),await this.editor.fromJSON(structuredClone(e.state)),this.activePageId=t,this.emitChanged(),!0):!1}async duplicate(t){this.saveCurrent();let e=this.pages.find(n=>n.id===t);if(!e)return null;let i={id:te(),name:`${e.name} copy`,state:structuredClone(e.state)},s=this.pages.indexOf(e);return this.pages.splice(s+1,0,i),this.emitChanged(),i.id}async remove(t){if(this.pages.length===1)return!1;let e=this.pages.findIndex(i=>i.id===t);if(e<0)return!1;if(t===this.activePageId){let i=this.pages[e+1]??this.pages[e-1];await this.editor.fromJSON(structuredClone(i.state)),this.activePageId=i.id}return this.pages.splice(e,1),this.emitChanged(),!0}rename(t,e){let i=this.pages.find(n=>n.id===t),s=e.trim();return!i||!s||i.name===s?!1:(i.name=s,this.emitChanged(),!0)}reorder(t,e){let i=this.pages.findIndex(a=>a.id===t);if(i<0||!Number.isFinite(e))return!1;let s=Math.max(0,Math.min(this.pages.length-1,Math.round(e)));if(s===i)return!1;let[n]=this.pages.splice(i,1);return this.pages.splice(s,0,n),this.emitChanged(),!0}toJSON(){return this.saveCurrent(),{version:"1.0.0",activePageId:this.activePageId,pages:structuredClone(this.pages)}}async fromJSON(t){if(t?.version!=="1.0.0"||!Array.isArray(t.pages)||t.pages.length===0||!t.pages.some(s=>s.id===t.activePageId))throw new Error("Invalid project state");let e=structuredClone(t.pages),i=e.find(s=>s.id===t.activePageId);await this.editor.fromJSON(structuredClone(i.state)),this.pages=e,this.activePageId=i.id,this.emitChanged()}saveCurrent(){let t=this.pages.find(e=>e.id===this.activePageId);t&&(t.state=structuredClone(this.editor.toJSON()))}blankState(t){return{...t,layers:[],mockup:null}}emitChanged(){this.editor.events.emit("project:changed",{activePageId:this.activePageId,pages:this.getAll()})}};var Dt=class extends Error{constructor(e,i,s){super(i);this.code=e;this.cause=s;this.name="MaskRefinementError"}code;cause},Ke=class{constructor(t){this.editor=t}editor;backing=null;context=null;layerId=null;brush=null;previousPoint=null;strokeBackup=null;strokeStartedAt=null;lastInteractionLatencyMs=0;refinement=null;disposed=!1;async create(t=this.editor.canvas.getWidth(),e=this.editor.canvas.getHeight()){if(this.assertActive(),!Number.isInteger(t)||!Number.isInteger(e)||t<=0||e<=0)throw new Error("Mask dimensions must be positive integers");let i=this.makeCanvas(t,e),s=new V(i,{left:0,top:0,originX:"left",originY:"top",selectable:!1}),n=this.editor.layers.add("mask",s,"Mask");return n.meta.mask={width:t,height:e,revision:0},this.editor.history.saveImmediate(),this.attachBacking(n.id,i),n}attach(t){this.assertActive(),this.cancelStroke();let e=this.requireMask(t),i=e.fabricObject,s=e.meta.mask?.width??i.width??this.editor.canvas.getWidth(),n=e.meta.mask?.height??i.height??this.editor.canvas.getHeight(),a=this.makeCanvas(s,n),o=a.getContext("2d");if(!o)throw new Error("2D mask context is unavailable");let l=i.getElement();l&&o.drawImage(l,0,0,s,n),this.attachBacking(t,a)}beginStroke(t){if(this.assertActive(),!this.context||!this.backing||!this.layerId)throw new Error("Attach a mask first");if(this.brush)throw new Error("A mask stroke is already active");if(!Number.isFinite(t.size)||t.size<=0)throw new Error("Mask brush size must be positive");this.brush={...t,hardness:N(t.hardness,0,1)},this.previousPoint=null,this.strokeBackup=this.context.getImageData(0,0,this.backing.width,this.backing.height),this.strokeStartedAt=performance.now()}addPoint(t){if(!this.brush||!this.context||!this.backing||!this.layerId)throw new Error("No active mask stroke");if(!Number.isFinite(t.x)||!Number.isFinite(t.y))return;let e=this.previousPoint??t,i=Math.hypot(t.x-e.x,t.y-e.y),s=Math.max(1,this.brush.size/4),n=Math.max(1,Math.ceil(i/s));for(let a=0;a<=n;a+=1){let o=a/n;this.drawDot({x:e.x+(t.x-e.x)*o,y:e.y+(t.y-e.y)*o})}this.previousPoint=t,this.requireMask(this.layerId).fabricObject.setElement(this.backing),this.editor.canvas.requestRenderAll()}async endStroke(){if(!this.brush||!this.backing||!this.layerId)return;let t=this.layerId;this.brush=null,this.previousPoint=null,this.strokeBackup=null;let e=this.backing.toDataURL("image/png");await this.editor.history.transaction(async()=>{await this.editor.replaceImageSource(t,e);let i=this.requireMask(t);i.meta.mask&&(i.meta.mask.revision+=1)}),this.attach(t),this.strokeStartedAt!==null&&(this.lastInteractionLatencyMs=performance.now()-this.strokeStartedAt,this.strokeStartedAt=null)}cancelStroke(){this.strokeBackup&&this.context&&this.backing&&this.layerId&&(this.context.putImageData(this.strokeBackup,0,0),this.requireMask(this.layerId).fabricObject.setElement(this.backing),this.editor.canvas.requestRenderAll()),this.brush=null,this.previousPoint=null,this.strokeBackup=null,this.strokeStartedAt=null}isStrokeActive(){return this.brush!==null}activeLayerId(){return this.layerId}detach(t){t&&this.layerId!==t||(this.cancelStroke(),this.cancelRefinement(),this.backing=null,this.context=null,this.layerId=null)}async refine(t,e,i,s={}){this.assertActive();let n=this.editor.layers.get(t);if(!n||n.type!=="mask")throw new Dt("not-found",`Mask layer not found: ${t}`);this.cancelRefinement();let a=new AbortController;this.refinement=a;let o=()=>a.abort(s.signal?.reason);s.signal?.addEventListener("abort",o,{once:!0}),s.signal?.aborted&&o();try{let l=n.fabricObject,h=await e.refine({mask:l.getSrc(),width:n.meta.mask?.width??l.width??1,height:n.meta.mask?.height??l.height??1,prompts:structuredClone(i)},{signal:a.signal,onProgress:s.onProgress});if(a.signal.aborted)throw new Dt("cancelled","Mask refinement cancelled");if(!/^data:image\/(?:png|jpeg|webp);base64,/i.test(h.dataUrl))throw new Dt("invalid-result","Mask refinement must return a base64 PNG, JPEG, or WebP data URL");return await this.editor.history.transaction(async()=>{await this.editor.replaceImageSource(t,h.dataUrl),n.meta.mask&&(n.meta.mask.revision+=1)}),this.attach(t),h}catch(l){throw l instanceof Dt?l:a.signal.aborted?new Dt("cancelled","Mask refinement cancelled",l):new Dt("provider","Mask refinement provider failed",l)}finally{s.signal?.removeEventListener("abort",o),this.refinement===a&&(this.refinement=null)}}cancelRefinement(){this.refinement?.abort(new DOMException("Cancelled","AbortError")),this.refinement=null}measure(){if(!this.backing)return null;let t=performance.now();this.context?.getImageData(0,0,1,1);let e=this.backing.width*this.backing.height*4,i=this.strokeBackup?e:0,s=performance;return{width:this.backing.width,height:this.backing.height,backingBytes:e,strokeBackupBytes:i,estimatedPeakBytes:e+i,historyBytes:this.editor.history.getSnapshotBytes(),interactionLatencyMs:this.lastInteractionLatencyMs,...typeof s.memory?.usedJSHeapSize=="number"?{usedJsHeapBytes:s.memory.usedJSHeapSize}:{},elapsedMs:performance.now()-t}}dispose(){this.detach(),this.disposed=!0}drawDot(t){let e=this.context,i=this.brush,s=i.size/2;e.save(),e.globalCompositeOperation=i.mode==="subtract"?"destination-out":"source-over";let n=e.createRadialGradient(t.x,t.y,s*i.hardness,t.x,t.y,s),a=i.mode==="subtract"?"rgba(0,0,0,1)":"rgba(255,255,255,1)";n.addColorStop(0,a),n.addColorStop(1,"rgba(255,255,255,0)"),e.fillStyle=n,e.beginPath(),e.arc(t.x,t.y,s,0,Math.PI*2),e.fill(),e.restore()}makeCanvas(t,e){let i=this.editor.canvas.lowerCanvasEl.ownerDocument.createElement("canvas");return i.width=t,i.height=e,i}attachBacking(t,e){let i=e.getContext("2d");if(!i)throw new Error("2D mask context is unavailable");this.layerId=t,this.backing=e,this.context=i}requireMask(t){let e=this.editor.layers.get(t);if(!e||e.type!=="mask")throw new Error(`Mask layer not found: ${t}`);return e}assertActive(){if(this.disposed)throw new Error("Mask controller has been disposed")}};var Uu=.1,qu=8;function Ku(r){return r instanceof DOMException&&r.name==="SecurityError"||r instanceof Error&&/taint|cross-origin|insecure/i.test(r.message)}var Zi=class{canvas;layers;history;events;units;snapping;crop;patterns;curves;maskPresets;fonts;licensing;pages;masks;fileAdapter;imageProvider;zoomLevel=1;mockup=null;designBackground;designBackgroundImage=null;backgroundImageOptions=null;constructor(t,e){this.events=new Le,this.fonts=new Ge,e.fonts?.forEach(n=>this.fonts.register(n)),this.licensing=new Ue(e.license),this.units=new Ne(e.unit??"px",e.dpi??72);let i=this.units.toPixels(e.width),s=this.units.toPixels(e.height);this.designBackground=e.backgroundColor??"#ffffff",this.canvas=new mi(t,{width:i,height:s,backgroundColor:this.designBackground,preserveObjectStacking:e.preserveObjectStacking??!0,selection:!0}),this.layers=new Be(this.canvas,this.events),this.fileAdapter=e.fileAdapter,this.imageProvider=e.imageProvider,this.history=new Xe({getState:()=>JSON.stringify(this.toJSON()),restoreState:async n=>{let a=JSON.parse(n);await this.fromJSON(a)},events:this.events}),this.layers.setHistoryCallback(()=>this.history.save()),this.snapping=new $e(this.canvas,this.events),this.crop=new Ye(this.canvas,this.history,this.events),this.patterns=new We(this.canvas,this.layers,this.history,this.events,e.patternSourceResolver),this.curves=new ze(this.canvas,this.layers,this.history,this.events),this.maskPresets=new me(this.canvas,this.layers,this.history,this.events),this.setupCanvasEvents(),this.history.saveImmediate(),this.pages=new qe(this),this.masks=new Ke(this)}async addImage(t,e){try{let i=await V.fromURL(t,{},{originX:"left",originY:"top",...e}),s=this.layers.add("image",i);return this.history.save(),s}catch(i){throw this.events.emit("error",{message:"Failed to add image",error:i}),i}}async replaceImageSource(t,e){let i=this.layers.get(t);if(!i||i.type!=="image"&&i.type!=="mask")throw new Error(`Image or mask layer not found: ${t}`);if(i.meta.pattern)throw new Error("Clear the pattern before replacing the image source");this.crop.activeLayerId()===t&&this.crop.cancel();let s=i.fabricObject;try{let n=await V.fromURL(e,{},{originX:"left",originY:"top"});return n.set({left:s.left,top:s.top,originX:s.originX,originY:s.originY,width:s.width,height:s.height,cropX:s.cropX,cropY:s.cropY,scaleX:s.scaleX,scaleY:s.scaleY,angle:s.angle,skewX:s.skewX,skewY:s.skewY,flipX:s.flipX,flipY:s.flipY}),n.filters=[...s.filters],n.applyFilters(),n.setCoords(),this.layers.replaceObject(t,n),i}catch(n){throw this.events.emit("error",{message:"Failed to replace image source",error:n}),n}}addText(t,e){let i=new Te(t,{fontSize:32,fontFamily:"Arial",fill:"#000000",width:200,originX:"left",originY:"top",...e}),s=this.layers.add("text",i);return this.history.save(),s}addShape(t,e){let i=t.create(e),s=this.layers.add("shape",i,t.name);return this.history.save(),s}async addTemplate(t,e){let i={};for(let c of t.parameters){let u=e[c.key]??c.default;if(u===void 0)throw new Error(`Missing template parameter: ${c.key}`);if(c.type==="number"&&!Number.isFinite(Number(u)))throw new Error(`Invalid number for template parameter: ${c.key}`);if(c.type==="color"&&!ee(u))throw new Error(`Invalid color for template parameter: ${c.key}`);i[c.key]=u}let s=Ki(t.svg.replace(/\{\{(\w+)(?:[|:]([^}]*))?\}\}/g,(c,u,d)=>{let g=i[u]??d;return g===void 0?c:qi(g)})),{objects:n,options:a}=await al(s),o=n.filter(c=>c!==null);if(o.length===0)throw new Error("Template SVG contains no renderable objects");let l=Zt.groupSVGElements(o,a);l.set({left:this.canvas.getWidth()/2,top:this.canvas.getHeight()/2,originX:"center",originY:"center"});let h=this.layers.add("template",l,t.name);return this.history.save(),h}removeLayer(t){this.crop.activeLayerId()===t&&this.crop.cancel(),this.masks.activeLayerId()===t&&this.masks.detach(t),this.layers.remove(t)&&this.history.save()}selectLayer(t){this.layers.select(t)}getSelectedLayer(){let t=this.canvas.getActiveObject();return t?this.layers.findByObject(t)??null:null}flipLayer(t,e){let i=this.layers.get(t);if(!i)return;let s=i.fabricObject;e==="horizontal"?s.set("flipX",!s.flipX):s.set("flipY",!s.flipY),s.setCoords(),this.canvas.requestRenderAll(),this.history.save()}async duplicateLayer(t){let e=this.layers.get(t);if(!e)return null;let i=await e.fabricObject.clone();e.meta.pattern||i.set({left:(i.left??0)+15,top:(i.top??0)+15}),i.setCoords();let s=this.layers.add(e.type,i,`${e.name} copy`);return s.meta=structuredClone(e.meta),s.visible=e.visible,s.locked=e.locked,s.opacity=e.opacity,i.set({visible:e.visible,selectable:!e.locked,evented:!e.locked,opacity:e.opacity}),this.canvas.setActiveObject(i),this.canvas.requestRenderAll(),this.history.save(),s}applyImageAdjustments(t,e){let i=this.layers.get(t);if(!i||i.type!=="image")return!1;let s=i.fabricObject,a={...i.meta.imageAdjustments??{},...e},o=(l,h=-1)=>N(l??0,h,1);return s.filters=[new Lr.Brightness({brightness:o(a.brightness)}),new Lr.Contrast({contrast:o(a.contrast)}),new Lr.Saturation({saturation:o(a.saturation)}),new Lr.Blur({blur:o(a.blur,0)})],i.meta.imageAdjustments=a,s.applyFilters(),this.canvas.requestRenderAll(),this.history.save(),!0}async groupLayers(t,e="Group"){let i=[...new Set(t)],s=i.map(n=>this.layers.get(n)).filter(n=>n!==void 0);return s.length<2||s.length!==i.length?null:this.history.transaction(()=>{let n=s.map(h=>structuredClone(h.toData())),a=s.map(h=>h.fabricObject);for(let h of s)this.layers.remove(h.id);let o=new Ft(a),l=this.layers.add("group",o,e);return l.meta.groupChildren=n,this.layers.select(l.id),this.history.save(),l})}async ungroupLayer(t){let e=this.layers.get(t),i=e?.meta.groupChildren;if(!e||e.type!=="group"||!Array.isArray(i))return[];let s=e.fabricObject;return this.history.transaction(()=>{let n=s.calcTransformMatrix(),a=s.removeAll();this.layers.remove(t);let o=a.map((l,h)=>{Zt.addTransformToObject(l,n),l.setCoords();let c=i[h],u=this.layers.add(c?.type??"group",l,c?.name,c?.id);return c?.meta&&(u.meta=structuredClone(c.meta)),c&&!c.visible&&this.layers.setVisibility(u.id,!1),c?.locked&&this.layers.setLocked(u.id,!0),c&&c.opacity!==1&&this.layers.setOpacity(u.id,c.opacity),u});return this.history.save(),this.layers.select(o[0]?.id??null),o})}toJSON(){return Yi(this)}async fromJSON(t){let e=this.history.isRestoring();e||(this.history.saveImmediate(),this.history.pause());try{await Wi(this,t),this.patterns.repinAll()}catch(i){throw e||this.events.emit("error",{message:"Failed to load editor state",error:i}),i}finally{e||this.history.resume()}e||(this.history.clear(),this.history.saveImmediate())}async toPNG(t){return this.toRaster(t?.format??"png",t)}async toJPEG(t){return this.toRaster("jpeg",t)}async toWebP(t){return this.toRaster("webp",t)}async exportLayer(t,e={}){let i=this.layers.get(t);if(!i)throw new Error(`Layer not found: ${t}`);try{if(e.resolution==="source"&&i.fabricObject instanceof V){let s=await i.fabricObject.clone();return s.set({left:0,top:0,originX:"left",originY:"top",scaleX:1,scaleY:1,angle:0,flipX:!1,flipY:!1}),await zr(this.canvas,[s],{...e,width:s.width||1,height:s.height||1,cloneObjects:!1})}return await zr(this.canvas,[i.fabricObject],e)}catch(s){throw this.events.emit("error",{message:`Failed to export layer: ${t}`,error:s}),s}}async exportBackground(t={}){try{return await zr(this.canvas,[],{...t,backgroundColor:this.designBackground,backgroundImage:this.designBackgroundImage})}catch(e){throw this.events.emit("error",{message:"Failed to export background",error:e}),e}}async toRaster(t,e){this.events.emit("export:start",{format:t});try{await this.fonts.ready();let i=await this.withDesignBackground(()=>Wr(this.canvas,{...e,format:t}));return this.events.emit("export:complete",{format:t}),this.licensing.track(`export:${t}`),i}catch(i){throw this.events.emit("error",{message:Ku(i)?"Canvas export was blocked by cross-origin image data; load remote images with CORS enabled":`Failed to export ${t.toUpperCase()}`,error:i}),i}}toSVG(){this.events.emit("export:start",{format:"svg"});try{let t=this.withDesignBackground(()=>Gi(this.canvas));return this.events.emit("export:complete",{format:"svg"}),this.licensing.track("export:svg"),t}catch(t){throw this.events.emit("error",{message:"Failed to export SVG",error:t}),t}}async toSVGAsync(t={}){await this.fonts.ready();let e=this.toSVG();if(t.embedFonts===!1||this.fonts.getAll().length===0)return e;try{let i=await this.fonts.getEmbeddedCss();return e.replace(/(<svg\b[^>]*>)/i,`$1<defs><style>${i}</style></defs>`)}catch(i){throw this.events.emit("error",{message:"Failed to embed fonts in SVG",error:i}),i}}toDataURL(t="png",e=1){return this.withDesignBackground(()=>Ui(this.canvas,t,e))}async toPrintFile(t={}){await this.fonts.ready();try{let e=this.mockup?.printArea,i=e?await Vi(this.canvas,e,t):await zr(this.canvas,this.canvas.getObjects(),t);return this.licensing.track(`export:print:${t.format??"png"}`),i}catch(e){throw this.events.emit("error",{message:"Failed to export print file",error:e}),e}}async toMockupImage(t={}){if(!this.mockup)throw new Error("No mockup is configured");await this.fonts.ready();try{let e=await Ni(this.canvas,this.mockup,t);return this.licensing.track(`export:mockup:${t.format??"png"}`),e}catch(e){throw this.events.emit("error",{message:"Failed to export mockup",error:e}),e}}withDesignBackground(t){if(!this.mockup)return t();let e=this.canvas.backgroundColor,i=this.canvas.backgroundImage;this.canvas.backgroundColor=this.designBackground,this.canvas.backgroundImage=this.designBackgroundImage??void 0;try{return t()}finally{this.canvas.backgroundColor=e,this.canvas.backgroundImage=i}}toPrintifyPositioning(){let t={},e=this.canvas.getWidth(),i=this.canvas.getHeight(),s=this.layers.getAll().filter(n=>n.type==="image");if(s.length===0)return t.front={x:.5,y:.5,scale:1,angle:0},t;for(let n of s){let a=n.fabricObject,o=a.getCenterPoint(),l=t[n.name]?`${n.name}-${n.id}`:n.name;t[l]={x:J(o.x/e),y:J(o.y/i),scale:J(a.scaleX??1),angle:J(a.angle??0)}}return t}toNormalizedPositioning(){let t=this.canvas.getWidth(),e=this.canvas.getHeight();return this.layers.getAll().map(i=>{let s=i.fabricObject,n=s.getCenterPoint(),a=s.getBoundingRect();return{layerId:i.id,name:i.name,type:i.type,centerX:J(n.x/t),centerY:J(n.y/e),width:J(a.width/t),height:J(a.height/e),scaleX:J(s.scaleX??1),scaleY:J(s.scaleY??1),angle:J(s.angle??0)}})}toProviderPositioning(t){return t.map(this.toNormalizedPositioning(),{width:this.canvas.getWidth(),height:this.canvas.getHeight()})}async save(t,e){if(!this.fileAdapter)return;let i;e==="png"?i=await this.toPNG():e==="jpeg"?i=await this.toJPEG():e==="webp"?i=await this.toWebP():e==="svg"?i=await this.toSVGAsync():i=JSON.stringify(this.toJSON(),null,2);try{return await this.fileAdapter.save(i,t,e)}catch(s){throw this.events.emit("error",{message:`Failed to save ${e}`,error:s}),s}}async uploadImage(t){if(this.imageProvider?.upload)try{return await this.imageProvider.upload(t)}catch(e){throw this.events.emit("error",{message:"Failed to upload image",error:e}),e}}async browseImages(){if(!this.imageProvider?.browse)return null;try{return await this.imageProvider.browse()}catch(t){throw this.events.emit("error",{message:"Failed to browse images",error:t}),t}}async searchImages(t,e){if(!this.imageProvider?.search)return null;try{return await this.imageProvider.search(t,e)}catch(i){throw this.events.emit("error",{message:"Failed to search images",error:i}),i}}async addProviderImage(t,e){try{await this.imageProvider?.trackUse?.(t)}catch(i){throw this.events.emit("error",{message:"Failed to record image use",error:i}),i}return this.addImage(t.url,e)}setFileAdapter(t){this.fileAdapter=t}setImageProvider(t){this.imageProvider=t}setBackground(t){this.designBackground=t,this.mockup||(this.canvas.backgroundColor=t,this.canvas.requestRenderAll()),this.history.save(),this.events.emit("canvas:modified",{})}getDesignBackground(){return this.designBackground}getDesignBackgroundImage(){return this.designBackgroundImage}getBackgroundImageOptions(){return this.backgroundImageOptions?{...this.backgroundImageOptions}:null}async setBackgroundImage(t,e={}){if(t===null){this.setBackgroundImageObject(null);return}try{let i=await V.fromURL(t,{crossOrigin:e.crossOrigin??null,signal:e.signal},{originX:"left",originY:"top"}),s=i.width||1,n=i.height||1,a=this.canvas.getWidth(),o=this.canvas.getHeight(),l=e.fit??"cover",h=a/s,c=o/n,u=l==="stretch"?h:l==="contain"?Math.min(h,c):Math.max(h,c),d=l==="stretch"?c:u;i.set({left:(a-s*u)/2,top:(o-n*d)/2,scaleX:u,scaleY:d,opacity:N(e.opacity??1,0,1),selectable:!1,evented:!1});let g={...e};delete g.signal,this.setBackgroundImageObject(i,!0,g)}catch(i){throw this.events.emit("error",{message:"Failed to set background image",error:i}),i}}setBackgroundImageObject(t,e=!0,i=null){this.designBackgroundImage=t,this.backgroundImageOptions=t?i:null,this.canvas.backgroundImage=this.mockup?void 0:t??void 0,this.canvas.requestRenderAll(),e&&this.history.save(),this.events.emit("canvas:modified",{})}setTransparentBackground(){this.setBackground("")}resize(t,e,i={}){let s=this.units.toPixels(t),n=this.units.toPixels(e),a=this.canvas.getWidth(),o=this.canvas.getHeight();if((i.scaleContent??!0)&&a>0&&o>0){let h=s/a,c=n/o;for(let u of this.layers.getAll()){if(u.meta.pattern)continue;let d=u.fabricObject;d.set({left:(d.left??0)*h,top:(d.top??0)*c,scaleX:(d.scaleX??1)*h,scaleY:(d.scaleY??1)*c}),d.setCoords()}this.designBackgroundImage&&(this.designBackgroundImage.set({left:(this.designBackgroundImage.left??0)*h,top:(this.designBackgroundImage.top??0)*c,scaleX:(this.designBackgroundImage.scaleX??1)*h,scaleY:(this.designBackgroundImage.scaleY??1)*c}),this.designBackgroundImage.setCoords())}this.canvas.setDimensions({width:s,height:n}),this.patterns.repinAll(),this.canvas.requestRenderAll(),this.history.save(),this.events.emit("canvas:modified",{})}getImageDpi(t){let e=this.layers.get(t);if(!e||e.type!=="image")return null;let i=e.fabricObject,s=i.width??0,n=i.getScaledWidth();return s<=0||n<=0?null:J(s/(n/this.units.getDpi()))}validateImageDpi(t=300){return this.layers.getAll().filter(e=>e.type==="image"&&!e.meta.pattern).flatMap(e=>{let i=this.getImageDpi(e.id);return i!==null&&i<t?[{layerId:e.id,layerName:e.name,effectiveDpi:i,minimumDpi:t}]:[]})}toThumbnail(t=320,e=320,i="png"){let s=Math.min(1,t/this.canvas.getWidth(),e/this.canvas.getHeight());return this.toDataURL(i,s)}bringToFront(t){return this.layers.reorder(t,this.layers.count()-1)}sendToBack(t){return this.layers.reorder(t,0)}bringForward(t){let e=this.layers.getAll().findIndex(i=>i.id===t);return e>=0&&this.layers.reorder(t,e+1)}sendBackward(t){let e=this.layers.getAll().findIndex(i=>i.id===t);return e>=0&&this.layers.reorder(t,e-1)}setZoom(t){let e=N(J(t),Uu,qu);e!==this.zoomLevel&&(this.zoomLevel=e,this.events.emit("zoom:changed",{zoom:e}))}zoom(t){this.setZoom(t)}getZoom(){return this.zoomLevel}zoomIn(t=.1){this.setZoom(this.zoomLevel+t)}zoomOut(t=.1){this.setZoom(this.zoomLevel-t)}resetZoom(){this.setZoom(1)}zoomToFit(t,e,i=0){let s=this.canvas.getWidth(),n=this.canvas.getHeight();if(s<=0||n<=0)return;let a=(t-i*2)/s,o=(e-i*2)/n;this.setZoom(Math.min(a,o))}zoomToSelection(t=24){let e=this.canvas.getActiveObject();if(!e)return;e.setCoords();let i=e.getBoundingRect();i.width<=0||i.height<=0||this.setZoom(Math.min((this.canvas.getWidth()-t*2)/i.width,(this.canvas.getHeight()-t*2)/i.height))}applyPattern(t,e){return this.patterns.apply(t,e)}clearPattern(t){return this.patterns.disable(t)}applyTextCurve(t,e){return this.curves.apply(t,e)}clearTextCurve(t){return this.curves.clear(t)}getTextCurve(t){return this.curves.get(t)}applyMaskPreset(t,e){return this.maskPresets.apply(t,e)}clearMaskPreset(t){return this.maskPresets.clear(t)}getMaskPreset(t){return this.maskPresets.get(t)}setLayerAspectLock(t,e){let i=this.layers.get(t);return i?(ve(i.fabricObject,e),e?i.meta.lockAspect=!0:delete i.meta.lockAspect,this.canvas.requestRenderAll(),this.events.emit("layer:modified",{layerId:t}),this.history.save(),!0):!1}getLayerAspectLock(t){return this.layers.get(t)?.meta.lockAspect===!0}restoreAspectLocks(){for(let t of this.layers.getAll())t.meta.lockAspect&&ve(t.fabricObject,!0)}resetLayerTransform(t){let e=this.layers.get(t);return e?($i(e.fabricObject),this.canvas.requestRenderAll(),this.events.emit("layer:modified",{layerId:t}),this.history.save(),!0):!1}setLayerShadow(t,e){let i=this.layers.get(t);return i?(Xi(i.fabricObject,e),i.fabricObject.dirty=!0,this.canvas.requestRenderAll(),this.events.emit("layer:modified",{layerId:t}),this.history.save(),!0):!1}getLayerShadow(t){let e=this.layers.get(t);return e?Yr(e.fabricObject):null}setMockup(t,e={}){this.mockup=t,this.canvas.backgroundColor=t?"":this.designBackground,this.canvas.backgroundImage=t?void 0:this.designBackgroundImage??void 0,this.canvas.requestRenderAll(),this.events.emit("mockup:changed",{mockup:t}),e.history!==!1&&this.history.save()}clearMockup(){this.setMockup(null)}getMockup(){return this.mockup}dispose(){this.masks.dispose(),this.snapping.dispose(),this.crop.dispose(),this.history.dispose(),Ii(),this.events.removeAllListeners(),this.canvas.dispose()}setupCanvasEvents(){this.canvas.on("object:modified",t=>{if(!t.target)return;let e=this.layers.findByObject(t.target);e&&(this.events.emit("layer:modified",{layerId:e.id}),this.history.save())}),this.canvas.on("selection:created",t=>{let e=(t.selected??[]).map(i=>this.layers.findByObject(i)?.id).filter(i=>i!==void 0);this.events.emit("selection:changed",{selected:e})}),this.canvas.on("selection:updated",t=>{let e=(t.selected??[]).map(i=>this.layers.findByObject(i)?.id).filter(i=>i!==void 0);this.events.emit("selection:changed",{selected:e})}),this.canvas.on("selection:cleared",()=>{this.events.emit("selection:changed",{selected:[]})})}};var Cl={mode:"grid",scale:100,horizontalSpacing:0,verticalSpacing:0,angle:0,horizontalOffset:0,offsetX:0,offsetY:0,rotationStepH:0,rotationStepV:0};var Sl=[{id:"a4-portrait",name:"A4 portrait",width:210,height:297,unit:"mm",dpi:300},{id:"a4-landscape",name:"A4 landscape",width:297,height:210,unit:"mm",dpi:300},{id:"us-letter",name:"US Letter",width:8.5,height:11,unit:"in",dpi:300},{id:"shirt-front",name:"Garment front",width:12,height:16,unit:"in",dpi:300},{id:"instagram-square",name:"Social square",width:1080,height:1080,unit:"px",dpi:72},{id:"story",name:"Story",width:1080,height:1920,unit:"px",dpi:72}];var Qi=class{items=new Map;transform={zoom:1,panX:0,panY:0,devicePixelRatio:1};set(t){this.items.set(t.id,structuredClone(t))}remove(t){return this.items.delete(t)}clear(){this.items.clear()}getAll(){return[...this.items.values()].map(t=>structuredClone(t))}setTransform(t){if(!Number.isFinite(t.zoom)||t.zoom<=0)throw new Error("Annotation zoom must be positive");this.transform={...t,devicePixelRatio:t.devicePixelRatio??1}}documentToViewport(t){return{x:t.x*this.transform.zoom+this.transform.panX,y:t.y*this.transform.zoom+this.transform.panY}}viewportToDocument(t){return{x:(t.x-this.transform.panX)/this.transform.zoom,y:(t.y-this.transform.panY)/this.transform.zoom}}documentToDevice(t){let e=this.documentToViewport(t),i=this.transform.devicePixelRatio??1;return{x:e.x*i,y:e.y*i}}};return Dl(Ju);})();
506
506
  //# sourceMappingURL=index.global.js.map