polotno-node 2.9.36 → 2.9.38

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/README.md CHANGED
@@ -1,7 +1,12 @@
1
1
  # Polotno-node
2
2
 
3
- Export Polotno JSON into images and pdf files. NodeJS package to work with [Polotno Store API](https://polotno.dev/).
4
- Should work fine with lambda functions as well.
3
+ Export Polotno JSON into images and pdf files. NodeJS package to work with [Polotno SDK](https://polotno.com/).
4
+
5
+ > **🚀 Optimize Your Workflow with Cloud Render API!**
6
+ >
7
+ > Instead of managing your own server infrastructure with `polotno-node`, consider using our [Cloud Render API](https://polotno.com/cloud-render). It provides all the powerful export capabilities of Polotno with none of the server maintenance. Seamlessly convert your designs into images, PDFs, and videos at scale, with the reliability and speed of cloud-based rendering.
8
+ >
9
+ > **Get started now and focus on what truly matters—creating stunning designs!**
5
10
 
6
11
  ## Usage
7
12
 
@@ -231,7 +231,7 @@ For more info see: https://github.com/konvajs/react-konva/issues/194
231
231
  <path d="M14 19L14 5C14 3.89543 14.8954 3 16 3L17 3C18.1046 3 19 3.89543 19 5L19 19C19 20.1046 18.1046 21 17 21L16 21C14.8954 21 14 20.1046 14 19Z" stroke="#323232" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
232
232
  <path d="M10 19L10 5C10 3.89543 9.10457 3 8 3L7 3C5.89543 3 5 3.89543 5 5L5 19C5 20.1046 5.89543 21 7 21L8 21C9.10457 21 10 20.1046 10 19Z" stroke="#323232" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
233
233
  </svg>
234
- `);function P(A,L,z,q,K,F,$){for(var B=new ImageData(L,z),Y=new Int32Array(A.data.buffer),X=A.width,Z=new Int32Array(B.data.buffer),te=B.width,ee=L/F,ne=z/$,ie=Math.round(1/ee),ce=Math.round(1/ne),Oe=ie*ce,Te=0;Te<B.height;Te++)for(var ae=0;ae<te;ae++){for(var de=q+Math.round(ae/ee)+(K+Math.round(Te/ne))*X,ye=0,ve=0,re=0,oe=0,be=0;be<ce;be++)for(var Ee=0;Ee<ie;Ee++){var Ge=Y[de+Ee+be*X];ye+=Ge<<24>>>24,ve+=Ge<<16>>>24,re+=Ge<<8>>>24,oe+=Ge>>>24}ye=Math.round(ye/Oe),ve=Math.round(ve/Oe),re=Math.round(re/Oe),oe=Math.round(oe/Oe),Z[ae+Te*te]=oe<<24|re<<16|ve<<8|ye}return B}function O(A,L){var z,q;const K=d();K.width=A.width,K.height=A.height,(z=K.getContext("2d"))===null||z===void 0||z.drawImage(A,0,0,K.width,K.height);const F=P(K.getContext("2d").getImageData(0,0,K.width,K.height),Math.floor(K.width*L),Math.floor(K.height*L),0,0,K.width,K.height);return K.width=Math.floor(K.width*L),K.height=Math.floor(K.height*L),(q=K.getContext("2d"))===null||q===void 0||q.putImageData(F,0,0),K}const x=(A,L,z,q,K=0,F=!1)=>{const $=Math.floor(Math.max(A.width*q,1)),B=Math.floor(Math.max(A.height*q,1)),Y=Math.min(K*q,$/2,B/2),X=Math.max(A.width/z.width,A.height/z.height)*q,Z=A.page._exportingOrRendering&&b.flags.imageDownScalingEnabled&&X<1&&!F,te=z.x===0&&z.y===0&&z.width===(L==null?void 0:L.width)&&z.height===(L==null?void 0:L.height),ee=a.default.useMemo(()=>{if(!(!L||!L.width||!L.height))return te&&Y===0&&!Z?void 0:d()},[L,Y,Z,te]);return a.default.useLayoutEffect(()=>{if(!ee||!L)return;ee.width=$,ee.height=B;const ne=ee.getContext("2d");if(!ne)return;Y&&(ne.beginPath(),ne.moveTo(Y,0),ne.lineTo($-Y,0),ne.arc($-Y,Y,Y,3*Math.PI/2,0,!1),ne.lineTo($,B-Y),ne.arc($-Y,B-Y,Y,0,Math.PI/2,!1),ne.lineTo(Y,B),ne.arc(Y,B-Y,Y,Math.PI/2,Math.PI,!1),ne.lineTo(0,Y),ne.arc(Y,Y,Y,Math.PI,3*Math.PI/2,!1),ne.clip());const ie=Z?O(L,X):L,ce=Z?{x:Math.floor(z.x*X),y:Math.floor(z.y*X),width:Math.floor(z.width*X),height:Math.floor(z.height*X)}:z;ne.drawImage(ie,ce.x,ce.y,ce.width,ce.height,0,0,ee.width,ee.height)},[ee,A.width,A.height,z.x,z.y,z.width,z.height,K,q,F,A.page._exportingOrRendering,Z]),a.default.useEffect(()=>()=>{ee&&ee.nodeName==="CANVAS"&&h.default.Util.releaseCanvas(ee)},[ee]),ee||L},k=(A,L,z,q)=>{const K=_(A.clipSrc||""),[F,$]=G(K,"anonymous"),B=A.clipSrc?$:"loaded";(0,e.useImageLoader)(B,A.id+"-clip");const Y=a.default.useMemo(()=>{if(L&&F)return d()},[L,F]);return a.default.useLayoutEffect(()=>{var X;if(!F||!L||!L.width||!L.height||!F||!F.width||!F.height||!Y)return;const Z=d(),te=Math.max(A.width/F.width*z,A.height/F.height*z);Z.width=F.width*te,Z.height=F.height*te,(X=Z.getContext("2d"))===null||X===void 0||X.drawImage(F,0,0,Z.width,Z.height),Y.width=Math.max(L.width,1),Y.height=Math.max(L.height,1);const ee=Y.getContext("2d");ee&&(ee.save(),ee.drawImage(Z,0,0,L.width,L.height),h.default.Util.releaseCanvas(Z),ee.globalCompositeOperation="source-in",ee.drawImage(L,0,0,Y.width,Y.height),ee.restore())},[Y,L,F,A.width,A.height,z,...q]),A.clipSrc&&F?Y:L},M=d(),I=(0,o.observer)(({element:A})=>{const L=Math.min(30,A.width/4,A.height/4),z=a.default.useRef(null);return a.default.useEffect(()=>{const q=z.current;if(!q)return;const K=new h.default.Animation(F=>{q.rotate(((F==null?void 0:F.timeDiff)||0)/2)},q.getLayer());return K.start(),()=>{K.stop()}}),a.default.createElement(u.Group,{x:A.x,y:A.y,rotation:A.rotation,listening:!1,opacity:A.a.opacity,hideInExport:!A.showInExport},a.default.createElement(u.Rect,{width:A.width,height:A.height,fill:"rgba(124, 173, 212, 0.8)"}),a.default.createElement(u.Arc,{ref:z,x:A.width/2,y:A.height/2,fill:"white",outerRadius:Math.abs(L),innerRadius:Math.max(1,L-5),angle:270}))}),H=(0,o.observer)(({element:A})=>{const L="Can not load the video...",z=Math.max(10,Math.min(30,A.width/25));return a.default.createElement(u.Group,{x:A.x,y:A.y,rotation:A.rotation,listening:!1,opacity:A.a.opacity,hideInExport:!A.showInExport},a.default.createElement(u.Rect,{width:A.width,height:A.height,fill:"rgba(223, 102, 102, 0.8)"}),a.default.createElement(u.Text,{text:L,fontSize:z,width:A.width,height:A.height,align:"center",fill:"white",verticalAlign:"middle",padding:5}))});let G=f.default;const Q=A=>{G=A};e.setImageLoaderHook=Q;const W=(A,L)=>{const z=a.default.useRef(),q=()=>{var K;(K=z.current)===null||K===void 0||K.call(z),z.current=void 0};a.default.useEffect(()=>q,[]),a.default.useLayoutEffect(()=>{A!=="loading"||z.current||(z.current=(0,p.incrementLoader)(`video ${L}`)),A!=="loading"&&q(),A==="failed"&&(0,p.triggerLoadError)(`video ${L}`)},[A])};e.useImageLoader=W;function U(A,L){for(var z=A.buffered,q=0;q<z.length;q++)if(L>=z.start(q)&&L<=z.end(q))return!0;return!1}function j(A,L,z){const q=a.default.useRef("loading"),K=a.default.useRef(null),[F,$]=a.default.useState(0),B=a.default.useRef(),Y=a.default.useRef(),X=a.default.useRef();return B.current===A&&Y.current===L&&X.current===z||(q.current="loading",K.current=void 0,B.current=A,Y.current=L,X.current=z),a.default.useLayoutEffect(function(){if(A){var Z=document.createElement("video");return Z.addEventListener("canplay",te),Z.addEventListener("error",ee),Z.crossOrigin=L,Z.src=A,function(){Z.removeEventListener("canplay",te),Z.removeEventListener("error",ee)}}function te(){q.current="loaded",K.current=Z,K.current.currentTime=0,$(Math.random()),K.current.removeEventListener("canplay",te)}function ee(ne){q.current="failed",K.current=void 0,$(Math.random())}},[A,L,z]),[K.current,q.current]}e.VideoElement=(0,o.observer)(({element:A,store:L})=>{var z;const[q,K]=a.default.useState(!1),F=a.default.useRef(null),$=a.default.useRef(null),[B,Y]=a.default.useState(!1),X=L.selectedShapes.indexOf(A)>=0,[Z,te]=a.default.useState(!1),[ee,ne]=j(A.src,"anonymous"),ie=L.activePage===A.page;console.log(A.id,ne),(0,e.useImageLoader)(ne,A.id+"-video"),ee&&(ee.width=ee.videoWidth,ee.height=ee.videoHeight);const ce=ee||M;a.default.useEffect(()=>{ee&&L.history.ignore(()=>{A.set({duration:1e3*ee.duration})})},[ee]),a.default.useEffect(()=>{var xe;if(!ee)return;const Fe=ie&&(L.isPlaying||Z);if(!Fe)return void ee.pause();Fe&&(ee.currentTime=A.startTime*ee.duration,ee.play());const tt=new h.default.Animation(()=>{},(xe=F.current)===null||xe===void 0?void 0:xe.getLayer());tt.start();const mt=()=>{te(!1),ee.currentTime=A.startTime*ee.duration},Ot=()=>{ee.currentTime>=A.endTime*ee.duration&&(ee.pause(),ee.currentTime=A.startTime*ee.duration,te(!1))};return ee.addEventListener("ended",mt),ee.addEventListener("timeupdate",Ot),()=>{tt.stop(),ee.removeEventListener("ended",mt),ee.removeEventListener("timeupdate",Ot)}},[ee,Z,L.isPlaying,ie]),a.default.useEffect(()=>{ee&&(ee.volume=A.volume)},[ee,A.volume]);const Oe=a.default.useRef();a.default.useEffect(()=>{const xe=(0,l.autorun)(()=>{var Fe,tt;if(ee){const mt=(L.currentTime-A.page.startTime)%A.duration;(Math.abs(1e3*ee.currentTime-mt)>500||!L.isPlaying)&&(ee.currentTime=mt/1e3,L.isPlaying||(Oe.current=(0,p.incrementLoader)(`video ${A.id}`))),(tt=(Fe=F.current)===null||Fe===void 0?void 0:Fe.getLayer())===null||tt===void 0||tt.batchDraw()}});return()=>{xe(),Oe.current&&(Oe.current(),Oe.current=null)}},[L,ee]),a.default.useEffect(()=>{if(!ee)return;let xe=null;const Fe=()=>{var mt,Ot;Oe.current&&((Ot=(mt=F.current)===null||mt===void 0?void 0:mt.getLayer())===null||Ot===void 0||Ot.batchDraw(),Oe.current(),Oe.current=null),U(ee,ee.currentTime)||(xe&&(console.error("finish already exists"),xe()),xe=(0,p.incrementLoader)(`video ${A.id}`))},tt=()=>{xe&&(xe(),xe=null)};return ee.addEventListener("timeupdate",Fe),ee.addEventListener("canplay",tt),()=>{ee.removeEventListener("timeupdate",Fe),ee.removeEventListener("canplay",tt)}},[ee,A.id,p.incrementLoader]);let{cropX:Te,cropY:ae,cropWidth:de,cropHeight:ye}=A;ne!=="loaded"&&(Te=ae=0,de=ye=1);const ve=ce.width*de,re=ce.height*ye,oe=A.width/A.height;let be,Ee;const Ge=ve/re,et=A.type==="svg";et?(be=ve,Ee=re):oe>=Ge?(be=ve,Ee=ve/oe):(be=re*oe,Ee=re);const Ae={x:ce.width*Te,y:ce.height*ae,width:be,height:Ee},Ce=(z=A.cornerRadius)!==null&&z!==void 0?z:0;let ke=k(A,x(A,ce,Ae,L._elementsPixelRatio,Ce,q||A._cropModeEnabled||A.type==="svg"),L._elementsPixelRatio,[Ae,Ce,L._elementsPixelRatio]);const Ne=Math.max(A.width/be,A.height/Ee);a.default.useEffect(()=>{var xe;if(!A._cropModeEnabled)return;const Fe=(xe=F.current)===null||xe===void 0?void 0:xe.getStage();function tt(Ot){A._cropModeEnabled&&Ot.target!==$.current&&A.toggleCropMode(!1)}function mt(Ot){A._cropModeEnabled&&Ot.target.parentNode!==Fe.content&&A.toggleCropMode(!1)}return document.body.addEventListener("click",mt),Fe==null||Fe.on("click",tt),Fe==null||Fe.on("tap",tt),()=>{document.body.removeEventListener("click",mt),document.body.removeEventListener("touchstart",mt),Fe==null||Fe.off("click",tt),Fe==null||Fe.off("click",tt)}},[A._cropModeEnabled]),a.default.useLayoutEffect(()=>{if(!(q||A._cropModeEnabled))return(0,m.applyFilter)(F.current,A),(0,l.autorun)(()=>{(0,m.applyFilter)(F.current,A)},{delay:100})},[ce,q,de,ye,A._cropModeEnabled]),a.default.useLayoutEffect(()=>{var xe;q||A._cropModeEnabled?(xe=F.current)===null||xe===void 0||xe.clearCache():(0,m.applyFilter)(F.current,A)},[q,A.width,A.height,A._cropModeEnabled]),a.default.useEffect(()=>{(0,m.applyFilter)(F.current,A)},[A.shadowEnabled,A.shadowBlur,A.cornerRadius,A.shadowColor,A.shadowOffsetX,A.shadowOffsetY,A.shadowOpacity]);const Ze=a.default.useRef(null),ue=a.default.useRef(null),fe=a.default.useRef(null);a.default.useLayoutEffect(()=>{A._cropModeEnabled&&(ue.current.nodes([Ze.current]),fe.current.nodes([$.current]))},[A._cropModeEnabled]);const Ye=xe=>{Math.round(xe.target.x())>0&&(xe.target.x(0),xe.target.scaleX(1)),Math.round(xe.target.y())>0&&(xe.target.y(0),xe.target.scaleY(1));const Fe=xe.target.width()*xe.target.scaleX(),tt=xe.target.height()*xe.target.scaleY(),mt=Math.min(1,be/Fe),Ot=Math.min(1,Ee/tt),Lr=1-mt,Vr=Math.min(Lr,Math.max(0,Math.round(-xe.target.x())/Fe)),Or=1-Ot,Rn=Math.min(Or,Math.max(0,Math.round(-xe.target.y())/tt));xe.target.setAttrs({x:-Vr*ce.width,y:-Rn*ce.height,scaleX:1,scaleY:1}),A.set({cropX:Vr,cropY:Rn,cropWidth:mt,cropHeight:Ot})},_e=()=>{A.type!=="svg"&&A.contentEditable&&setTimeout(()=>{A.toggleCropMode(!0)})},De=ne==="loading",Le=ne==="failed",we=!De&&!Le,Qe=a.default.useRef({cropX:0,cropY:0,cropWidth:0,cropHeight:0}),Se=we?A.a.opacity:0;(0,v.useFadeIn)(F,Se);const Ke=A.selectable||L.role==="admin",Mr=(0,y.isTouchDevice)();return a.default.createElement(a.default.Fragment,null,De&&a.default.createElement(I,{element:A}),Le&&a.default.createElement(H,{element:A}),a.default.createElement(u.Image,{ref:F,name:"element",id:A.id,image:ce,x:A.x,y:A.y,width:A.width||1,height:A.height||1,rotation:A.rotation,opacity:Se,shadowEnabled:A.shadowEnabled,shadowBlur:A.shadowBlur,shadowOffsetX:A.shadowOffsetX,shadowOffsetY:A.shadowOffsetY,shadowColor:A.shadowColor,shadowOpacity:A.shadowOpacity,customCrop:Ae,listening:Ke,cropX:Ae.x,cropY:Ae.y,cropWidth:Ae.width,cropHeight:Ae.height,draggable:Mr?A.draggable&&X:A.draggable,preventDefault:!Mr||X,hideInExport:!A.showInExport,onMouseEnter:()=>{Y(!0)},onMouseLeave:()=>{Y(!1)},onDragMove:xe=>{A.set({x:xe.target.x(),y:xe.target.y()})},onDragEnd:xe=>{A.set({x:xe.target.x(),y:xe.target.y()})},onDblClick:_e,onDblTap:_e,onTransformStart:()=>{K(!0),Qe.current={cropX:A.cropX,cropY:A.cropY,cropWidth:A.cropWidth,cropHeight:A.cropHeight}},onTransform:xe=>{var Fe;const tt=xe.currentTarget,mt=Math.abs(tt.scaleX()-1)<1e-7?1:tt.scaleX(),Ot=Math.abs(tt.scaleY()-1)<1e-7?1:tt.scaleY();tt.scaleX(1),tt.scaleY(1);const Lr=(Fe=xe.target.getStage())===null||Fe===void 0?void 0:Fe.findOne("Transformer"),Vr=1-be/ce.width,Or=Math.min(Vr,Math.max(0,A.cropX)),Rn=1-Ee/ce.height,mn=Math.min(Rn,Math.max(0,A.cropY)),yn=Lr.getActiveAnchor(),Zn=!(yn.indexOf("middle")>=0||yn.indexOf("center")>=0),Ei=!Zn&&mt<1&&Qe.current.cropHeight>Ee/ce.height;let Ie=Zn?A.cropWidth:A.cropWidth*mt;Ei&&(Ie=A.cropWidth);const rt=!Zn&&Ot<1&&Qe.current.cropWidth>be/ce.width;let pt=Zn?A.cropHeight:A.cropHeight*Ot;rt&&(pt=A.cropHeight),et&&(Ie=A.cropWidth,pt=A.cropHeight),A.set({cropX:Or,cropY:mn,x:tt.x(),y:tt.y(),width:tt.width()*mt,height:tt.height()*Ot,rotation:xe.target.rotation(),cropWidth:Math.min(Ie,1-Or),cropHeight:Math.min(pt,1-mn)})},onTransformEnd:xe=>{const Fe=xe.currentTarget;A.set({width:Fe.width(),height:Fe.height(),x:Fe.x(),y:Fe.y(),rotation:xe.target.rotation(),cropWidth:be/ce.width,cropHeight:Ee/ce.height}),K(!1)}}),a.default.createElement(u.Rect,{x:A.x,y:A.y,width:Math.max(A.width-A.borderSize,0),height:Math.max(A.height-A.borderSize,0),opacity:Se,offsetX:-A.borderSize/2,offsetY:-A.borderSize/2,stroke:A.borderColor,strokeWidth:A.borderSize,listening:!1,visible:!!A.borderSize,rotation:A.rotation,cornerRadius:Math.max(0,Ce-A.borderSize),hideInExport:!A.showInExport}),!Z&&!L.isPlaying&&a.default.createElement(u.Image,{image:T,x:A.x+A.width/2-15/L.scale,y:A.y+A.height/2-15/L.scale,width:30/L.scale,height:30/L.scale,hideInExport:!0,onClick:()=>{te(!0)}}),Z&&!L.isPlaying&&a.default.createElement(u.Image,{image:C,x:A.x+A.width/2-15/L.scale,y:A.y+A.height/2-15/L.scale,width:30/L.scale,height:30/L.scale,hideInExport:!0,onClick:()=>{te(!1)}}),A._cropModeEnabled&&a.default.createElement(E.Portal,{selector:".page-abs-container",enabled:!0},a.default.createElement(u.Rect,{x:-window.innerWidth/L.scale,y:-window.innerWidth/L.scale,width:window.innerWidth/L.scale*3,height:window.innerWidth/L.scale*3,fill:"rgba(0,0,0,0.3)"}),a.default.createElement(u.Image,{listening:!1,image:ke,x:A.x,y:A.y,width:A.width,height:A.height,rotation:A.rotation,shadowEnabled:A.shadowEnabled,shadowBlur:A.shadowBlur}),a.default.createElement(u.Group,{x:A.x,y:A.y,rotation:A.rotation,scaleX:Ne,scaleY:Ne},a.default.createElement(u.Image,{image:ce,ref:$,opacity:.4,draggable:!0,x:-A.cropX*ce.width,y:-A.cropY*ce.height,onDragMove:Ye,onTransform:Ye}),a.default.createElement(u.Transformer,{ref:fe,anchorSize:20,enabledAnchors:["top-left","top-right","bottom-left","bottom-right"],boundBoxFunc:(xe,Fe)=>Fe.width<5||Fe.height<5?xe:Fe,rotateEnabled:!1,borderEnabled:!1,anchorCornerRadius:10,anchorStrokeWidth:2,borderStrokeWidth:2}),a.default.createElement(u.Rect,{width:be,height:Ee,ref:Ze,listening:!1,onTransform:xe=>{xe.target.x()<-A.cropX*ce.width-1e-9&&(xe.target.x(-A.cropX*ce.width),xe.target.scaleX(1)),xe.target.y()<-A.cropY*ce.height-1e-9&&(xe.target.y(-A.cropY*ce.height),xe.target.scaleY(1));const Fe=Math.min(1,Math.max(0,A.cropX+xe.target.x()/ce.width)),tt=Math.min(1,Math.max(0,xe.target.y()/ce.height+A.cropY)),mt=xe.target.width()*xe.target.scaleX(),Ot=xe.target.height()*xe.target.scaleY(),Lr=Math.min(1-Fe,mt/ce.width),Vr=Math.min(1-tt,Ot/ce.height),Or=xe.target.getAbsolutePosition(xe.target.getParent().getParent());xe.target.scale({x:1,y:1}),xe.target.position({x:0,y:0}),A.set({x:Or.x,y:Or.y,cropX:Fe,cropY:tt,cropWidth:Lr,cropHeight:Vr,width:Math.min(mt*Ne,ce.width*(1-Fe)*Ne),height:Math.min(Ot*Ne,ce.height*(1-tt)*Ne)})}}),a.default.createElement(u.Transformer,{ref:ue,enabledAnchors:["top-left","top-right","bottom-left","bottom-right"],boundBoxFunc:(xe,Fe)=>Fe.width<5||Fe.height<5?xe:Fe,keepRatio:!1,rotateEnabled:!1,anchorFill:"rgb(240, 240, 240)",anchorStrokeWidth:2,borderStrokeWidth:2}))),(B||X)&&a.default.createElement(w.Highlighter,{element:A}))})})(fS);var dS={},Qp={};(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.figureToSvg=e.subTypeToPathDataFunc=e.TYPES=e.crossPath=e.speechBubblePath=e.hexagonPath=e.pentagonPath=e.diamondPath=e.starPath=e.circleData=e.rightTriangleData=e.triangleData=e.rectData=void 0;const t=({width:b,height:m,cornerRadius:v})=>{if(v>0){const y=Math.min(v,b/2,m/2);return`M 0 ${y} A ${y} ${y} 0 0 1 ${y} 0 L ${b-y} 0 A ${y} ${y} 0 0 1 ${b} ${y} L ${b} ${m-y} A ${y} ${y} 0 0 1 ${b-y} ${m} L ${y} ${m} A ${y} ${y} 0 0 1 0 ${m-y} Z`}return`M 0 0 L ${b} 0 L ${b} ${m} L 0 ${m} Z`};e.rectData=t;const r=({width:b,height:m})=>`M ${b/2} 0 L ${b} ${m} L 0 ${m} Z`;e.triangleData=r;const n=({width:b,height:m})=>`M 0 0 L ${b} 0 L 0 ${m} Z`;e.rightTriangleData=n;const i=({width:b,height:m})=>`M ${b/2} ${m/2} m -${b/2}, 0 a ${b/2},${m/2} 0 1,0 ${b},0 a ${b/2},${m/2} 0 1,0 -${b},0`;function a({width:b,height:m}){const v=b/2,y=m/2,d=b/2,g=m/2,_=d/2,T=g/2;let C="",P=Math.PI/5;for(let O=0;O<10;O++){const x=O%2==0?g:T,k=v+(O%2==0?d:_)*Math.sin(O*P),M=y-x*Math.cos(O*P);O===0?C=`M ${k} ${M}`:C+=` L ${k} ${M}`}return C+" Z"}function o({width:b,height:m}){const v=b/2,y=m/2;return`M ${v} 0 L ${b} ${y} L ${v} ${m} L 0 ${y} Z`}function l({width:b,height:m}){const v=b/2,y=m/2,d=b/2,g=m/2;let _="",T=2*Math.PI/5;for(let C=0;C<5;C++){const P=g,O=v+d*Math.sin(C*T),x=y-P*Math.cos(C*T);C===0?_=`M ${O} ${x}`:_+=` L ${O} ${x}`}return _+" Z"}function u({width:b,height:m}){const v=b/2,y=m/2,d=b/2,g=m/2;let _="",T=2*Math.PI/6;for(let C=0;C<6;C++){const P=g,O=v+d*Math.sin(C*T),x=y-P*Math.cos(C*T);C===0?_=`M ${O} ${x}`:_+=` L ${O} ${x}`}return _+" Z"}function f({path:b,aspectRatio:m,width:v,height:y}){return{path:b,scaleX:v/m.width,scaleY:y/m.height}}function h({width:b,height:m}){const v=.1*Math.min(b,m),y=.2*b,d=.2*m,g=.5*b;let _=`M ${v},0`;return _+=" H "+(b-v),_+=` A ${v},${v} 0 0 1 ${b},${v}`,_+=" V "+(m-v-d),_+=` A ${v},${v} 0 0 1 ${b-v},${m-d}`,_+=` H ${g+y/2}`,_+=` L ${g},${m}`,_+=` L ${g-y/2},${m-d}`,_+=` H ${v}`,_+=` A ${v},${v} 0 0 1 0,${m-v-d}`,_+=` V ${v}`,_+=` A ${v},${v} 0 0 1 ${v},0`,_+=" Z",_}function E({width:b,height:m}){const v=.3*b,y=.3*m,d=b/2,g=m/2,_=d-v/2,T=d+v/2,C=g-y/2,P=g+y/2;let O=`M ${_},0 `;return O+=`H ${T} `,O+=`V ${C} `,O+=`H ${b} `,O+=`V ${P} `,O+=`H ${T} `,O+=`V ${m} `,O+=`H ${_} `,O+=`V ${P} `,O+="H 0 ",O+=`V ${C} `,O+=`H ${_} `,O+="V 0 ",O+="Z",O}function w(b){return e.TYPES[b]||e.rectData}function p(b,m){const{width:v,height:y,fill:d,stroke:g,strokeWidth:_,dash:T}=b,C=(T||[]).map(M=>M*_);let P=m(b),O=1,x=1;typeof P!="string"&&(O=P.scaleX,x=P.scaleY,P=P.path);const k=`clip-${b.id||Math.random()}`;return`
234
+ `);function P(A,L,z,q,K,F,$){for(var B=new ImageData(L,z),Y=new Int32Array(A.data.buffer),X=A.width,Z=new Int32Array(B.data.buffer),te=B.width,ee=L/F,ne=z/$,ie=Math.round(1/ee),ce=Math.round(1/ne),Oe=ie*ce,Te=0;Te<B.height;Te++)for(var ae=0;ae<te;ae++){for(var de=q+Math.round(ae/ee)+(K+Math.round(Te/ne))*X,ye=0,ve=0,re=0,oe=0,be=0;be<ce;be++)for(var Ee=0;Ee<ie;Ee++){var Ge=Y[de+Ee+be*X];ye+=Ge<<24>>>24,ve+=Ge<<16>>>24,re+=Ge<<8>>>24,oe+=Ge>>>24}ye=Math.round(ye/Oe),ve=Math.round(ve/Oe),re=Math.round(re/Oe),oe=Math.round(oe/Oe),Z[ae+Te*te]=oe<<24|re<<16|ve<<8|ye}return B}function O(A,L){var z,q;const K=d();K.width=A.width,K.height=A.height,(z=K.getContext("2d"))===null||z===void 0||z.drawImage(A,0,0,K.width,K.height);const F=P(K.getContext("2d").getImageData(0,0,K.width,K.height),Math.floor(K.width*L),Math.floor(K.height*L),0,0,K.width,K.height);return K.width=Math.floor(K.width*L),K.height=Math.floor(K.height*L),(q=K.getContext("2d"))===null||q===void 0||q.putImageData(F,0,0),K}const x=(A,L,z,q,K=0,F=!1)=>{const $=Math.floor(Math.max(A.width*q,1)),B=Math.floor(Math.max(A.height*q,1)),Y=Math.min(K*q,$/2,B/2),X=Math.max(A.width/z.width,A.height/z.height)*q,Z=A.page._exportingOrRendering&&b.flags.imageDownScalingEnabled&&X<1&&!F,te=z.x===0&&z.y===0&&z.width===(L==null?void 0:L.width)&&z.height===(L==null?void 0:L.height),ee=a.default.useMemo(()=>{if(!(!L||!L.width||!L.height))return te&&Y===0&&!Z?void 0:d()},[L,Y,Z,te]);return a.default.useLayoutEffect(()=>{if(!ee||!L)return;ee.width=$,ee.height=B;const ne=ee.getContext("2d");if(!ne)return;Y&&(ne.beginPath(),ne.moveTo(Y,0),ne.lineTo($-Y,0),ne.arc($-Y,Y,Y,3*Math.PI/2,0,!1),ne.lineTo($,B-Y),ne.arc($-Y,B-Y,Y,0,Math.PI/2,!1),ne.lineTo(Y,B),ne.arc(Y,B-Y,Y,Math.PI/2,Math.PI,!1),ne.lineTo(0,Y),ne.arc(Y,Y,Y,Math.PI,3*Math.PI/2,!1),ne.clip());const ie=Z?O(L,X):L,ce=Z?{x:Math.floor(z.x*X),y:Math.floor(z.y*X),width:Math.floor(z.width*X),height:Math.floor(z.height*X)}:z;ne.drawImage(ie,ce.x,ce.y,ce.width,ce.height,0,0,ee.width,ee.height)},[ee,A.width,A.height,z.x,z.y,z.width,z.height,K,q,F,A.page._exportingOrRendering,Z]),a.default.useEffect(()=>()=>{ee&&ee.nodeName==="CANVAS"&&h.default.Util.releaseCanvas(ee)},[ee]),ee||L},k=(A,L,z,q)=>{const K=_(A.clipSrc||""),[F,$]=G(K,"anonymous"),B=A.clipSrc?$:"loaded";(0,e.useImageLoader)(B,A.id+"-clip");const Y=a.default.useMemo(()=>{if(L&&F)return d()},[L,F]);return a.default.useLayoutEffect(()=>{var X;if(!F||!L||!L.width||!L.height||!F||!F.width||!F.height||!Y)return;const Z=d(),te=Math.max(A.width/F.width*z,A.height/F.height*z);Z.width=F.width*te,Z.height=F.height*te,(X=Z.getContext("2d"))===null||X===void 0||X.drawImage(F,0,0,Z.width,Z.height),Y.width=Math.max(L.width,1),Y.height=Math.max(L.height,1);const ee=Y.getContext("2d");ee&&(ee.save(),ee.drawImage(Z,0,0,L.width,L.height),h.default.Util.releaseCanvas(Z),ee.globalCompositeOperation="source-in",ee.drawImage(L,0,0,Y.width,Y.height),ee.restore())},[Y,L,F,A.width,A.height,z,...q]),A.clipSrc&&F?Y:L},M=d(),I=(0,o.observer)(({element:A})=>{const L=Math.min(30,A.width/4,A.height/4),z=a.default.useRef(null);return a.default.useEffect(()=>{const q=z.current;if(!q)return;const K=new h.default.Animation(F=>{q.rotate(((F==null?void 0:F.timeDiff)||0)/2)},q.getLayer());return K.start(),()=>{K.stop()}}),a.default.createElement(u.Group,{x:A.x,y:A.y,rotation:A.rotation,listening:!1,opacity:A.a.opacity,hideInExport:!A.showInExport},a.default.createElement(u.Rect,{width:A.width,height:A.height,fill:"rgba(124, 173, 212, 0.8)"}),a.default.createElement(u.Arc,{ref:z,x:A.width/2,y:A.height/2,fill:"white",outerRadius:Math.abs(L),innerRadius:Math.max(1,L-5),angle:270}))}),H=(0,o.observer)(({element:A})=>{const L="Can not load the video...",z=Math.max(10,Math.min(30,A.width/25));return a.default.createElement(u.Group,{x:A.x,y:A.y,rotation:A.rotation,listening:!1,opacity:A.a.opacity,hideInExport:!A.showInExport},a.default.createElement(u.Rect,{width:A.width,height:A.height,fill:"rgba(223, 102, 102, 0.8)"}),a.default.createElement(u.Text,{text:L,fontSize:z,width:A.width,height:A.height,align:"center",fill:"white",verticalAlign:"middle",padding:5}))});let G=f.default;const Q=A=>{G=A};e.setImageLoaderHook=Q;const W=(A,L)=>{const z=a.default.useRef(),q=()=>{var K;(K=z.current)===null||K===void 0||K.call(z),z.current=void 0};a.default.useEffect(()=>q,[]),a.default.useLayoutEffect(()=>{A!=="loading"||z.current||(z.current=(0,p.incrementLoader)(`video ${L}`)),A!=="loading"&&q(),A==="failed"&&(0,p.triggerLoadError)(`video ${L}`)},[A])};e.useImageLoader=W;function U(A,L){for(var z=A.buffered,q=0;q<z.length;q++)if(L>=z.start(q)&&L<=z.end(q))return!0;return!1}function j(A,L,z){const q=a.default.useRef("loading"),K=a.default.useRef(null),[F,$]=a.default.useState(0),B=a.default.useRef(),Y=a.default.useRef(),X=a.default.useRef();return B.current===A&&Y.current===L&&X.current===z||(q.current="loading",K.current=void 0,B.current=A,Y.current=L,X.current=z),a.default.useLayoutEffect(function(){if(A){var Z=document.createElement("video");return Z.addEventListener("canplay",te),Z.addEventListener("error",ee),Z.crossOrigin=L,Z.src=A,function(){Z.removeEventListener("canplay",te),Z.removeEventListener("error",ee)}}function te(){q.current="loaded",K.current=Z,K.current.currentTime=0,$(Math.random()),K.current.removeEventListener("canplay",te)}function ee(ne){q.current="failed",K.current=void 0,$(Math.random())}},[A,L,z]),[K.current,q.current]}e.VideoElement=(0,o.observer)(({element:A,store:L})=>{var z;const[q,K]=a.default.useState(!1),F=a.default.useRef(null),$=a.default.useRef(null),[B,Y]=a.default.useState(!1),X=L.selectedShapes.indexOf(A)>=0,[Z,te]=a.default.useState(!1),[ee,ne]=j(A.src,"anonymous"),ie=L.activePage===A.page;(0,e.useImageLoader)(ne,A.id+"-video"),ee&&(ee.width=ee.videoWidth,ee.height=ee.videoHeight);const ce=ee||M;a.default.useEffect(()=>{ee&&L.history.ignore(()=>{A.set({duration:1e3*ee.duration})})},[ee]),a.default.useEffect(()=>{var xe;if(!ee)return;const Fe=ie&&(L.isPlaying||Z);if(!Fe)return void ee.pause();Fe&&(ee.currentTime=A.startTime*ee.duration,ee.play());const tt=new h.default.Animation(()=>{},(xe=F.current)===null||xe===void 0?void 0:xe.getLayer());tt.start();const mt=()=>{te(!1),ee.currentTime=A.startTime*ee.duration},Ot=()=>{ee.currentTime>=A.endTime*ee.duration&&(ee.pause(),ee.currentTime=A.startTime*ee.duration,te(!1))};return ee.addEventListener("ended",mt),ee.addEventListener("timeupdate",Ot),()=>{tt.stop(),ee.removeEventListener("ended",mt),ee.removeEventListener("timeupdate",Ot)}},[ee,Z,L.isPlaying,ie]),a.default.useEffect(()=>{ee&&(ee.volume=A.volume)},[ee,A.volume]);const Oe=a.default.useRef();a.default.useEffect(()=>{const xe=(0,l.autorun)(()=>{var Fe,tt;if(ee){const mt=(L.currentTime-A.page.startTime)%A.duration;(Math.abs(1e3*ee.currentTime-mt)>500||!L.isPlaying)&&(ee.currentTime=mt/1e3,L.isPlaying||(Oe.current=(0,p.incrementLoader)(`video ${A.id}`))),(tt=(Fe=F.current)===null||Fe===void 0?void 0:Fe.getLayer())===null||tt===void 0||tt.batchDraw()}});return()=>{xe(),Oe.current&&(Oe.current(),Oe.current=null)}},[L,ee]),a.default.useEffect(()=>{if(!ee)return;let xe=null;const Fe=()=>{var mt,Ot;Oe.current&&((Ot=(mt=F.current)===null||mt===void 0?void 0:mt.getLayer())===null||Ot===void 0||Ot.batchDraw(),Oe.current(),Oe.current=null),U(ee,ee.currentTime)||(xe&&(console.error("finish already exists"),xe()),xe=(0,p.incrementLoader)(`video ${A.id}`))},tt=()=>{xe&&(xe(),xe=null)};return ee.addEventListener("timeupdate",Fe),ee.addEventListener("canplay",tt),()=>{ee.removeEventListener("timeupdate",Fe),ee.removeEventListener("canplay",tt)}},[ee,A.id,p.incrementLoader]);let{cropX:Te,cropY:ae,cropWidth:de,cropHeight:ye}=A;ne!=="loaded"&&(Te=ae=0,de=ye=1);const ve=ce.width*de,re=ce.height*ye,oe=A.width/A.height;let be,Ee;const Ge=ve/re,et=A.type==="svg";et?(be=ve,Ee=re):oe>=Ge?(be=ve,Ee=ve/oe):(be=re*oe,Ee=re);const Ae={x:ce.width*Te,y:ce.height*ae,width:be,height:Ee},Ce=(z=A.cornerRadius)!==null&&z!==void 0?z:0;let ke=k(A,x(A,ce,Ae,L._elementsPixelRatio,Ce,q||A._cropModeEnabled||A.type==="svg"),L._elementsPixelRatio,[Ae,Ce,L._elementsPixelRatio]);const Ne=Math.max(A.width/be,A.height/Ee);a.default.useEffect(()=>{var xe;if(!A._cropModeEnabled)return;const Fe=(xe=F.current)===null||xe===void 0?void 0:xe.getStage();function tt(Ot){A._cropModeEnabled&&Ot.target!==$.current&&A.toggleCropMode(!1)}function mt(Ot){A._cropModeEnabled&&Ot.target.parentNode!==Fe.content&&A.toggleCropMode(!1)}return document.body.addEventListener("click",mt),Fe==null||Fe.on("click",tt),Fe==null||Fe.on("tap",tt),()=>{document.body.removeEventListener("click",mt),document.body.removeEventListener("touchstart",mt),Fe==null||Fe.off("click",tt),Fe==null||Fe.off("click",tt)}},[A._cropModeEnabled]),a.default.useLayoutEffect(()=>{if(!(q||A._cropModeEnabled))return(0,m.applyFilter)(F.current,A),(0,l.autorun)(()=>{(0,m.applyFilter)(F.current,A)},{delay:100})},[ce,q,de,ye,A._cropModeEnabled]),a.default.useLayoutEffect(()=>{var xe;q||A._cropModeEnabled?(xe=F.current)===null||xe===void 0||xe.clearCache():(0,m.applyFilter)(F.current,A)},[q,A.width,A.height,A._cropModeEnabled]),a.default.useEffect(()=>{(0,m.applyFilter)(F.current,A)},[A.shadowEnabled,A.shadowBlur,A.cornerRadius,A.shadowColor,A.shadowOffsetX,A.shadowOffsetY,A.shadowOpacity]);const Ze=a.default.useRef(null),ue=a.default.useRef(null),fe=a.default.useRef(null);a.default.useLayoutEffect(()=>{A._cropModeEnabled&&(ue.current.nodes([Ze.current]),fe.current.nodes([$.current]))},[A._cropModeEnabled]);const Ye=xe=>{Math.round(xe.target.x())>0&&(xe.target.x(0),xe.target.scaleX(1)),Math.round(xe.target.y())>0&&(xe.target.y(0),xe.target.scaleY(1));const Fe=xe.target.width()*xe.target.scaleX(),tt=xe.target.height()*xe.target.scaleY(),mt=Math.min(1,be/Fe),Ot=Math.min(1,Ee/tt),Lr=1-mt,Vr=Math.min(Lr,Math.max(0,Math.round(-xe.target.x())/Fe)),Or=1-Ot,Rn=Math.min(Or,Math.max(0,Math.round(-xe.target.y())/tt));xe.target.setAttrs({x:-Vr*ce.width,y:-Rn*ce.height,scaleX:1,scaleY:1}),A.set({cropX:Vr,cropY:Rn,cropWidth:mt,cropHeight:Ot})},_e=()=>{A.type!=="svg"&&A.contentEditable&&setTimeout(()=>{A.toggleCropMode(!0)})},De=ne==="loading",Le=ne==="failed",we=!De&&!Le,Qe=a.default.useRef({cropX:0,cropY:0,cropWidth:0,cropHeight:0}),Se=we?A.a.opacity:0;(0,v.useFadeIn)(F,Se);const Ke=A.selectable||L.role==="admin",Mr=(0,y.isTouchDevice)();return a.default.createElement(a.default.Fragment,null,De&&a.default.createElement(I,{element:A}),Le&&a.default.createElement(H,{element:A}),a.default.createElement(u.Image,{ref:F,name:"element",id:A.id,image:ce,x:A.x,y:A.y,width:A.width||1,height:A.height||1,rotation:A.rotation,opacity:Se,shadowEnabled:A.shadowEnabled,shadowBlur:A.shadowBlur,shadowOffsetX:A.shadowOffsetX,shadowOffsetY:A.shadowOffsetY,shadowColor:A.shadowColor,shadowOpacity:A.shadowOpacity,customCrop:Ae,listening:Ke,cropX:Ae.x,cropY:Ae.y,cropWidth:Ae.width,cropHeight:Ae.height,draggable:Mr?A.draggable&&X:A.draggable,preventDefault:!Mr||X,hideInExport:!A.showInExport,onMouseEnter:()=>{Y(!0)},onMouseLeave:()=>{Y(!1)},onDragMove:xe=>{A.set({x:xe.target.x(),y:xe.target.y()})},onDragEnd:xe=>{A.set({x:xe.target.x(),y:xe.target.y()})},onDblClick:_e,onDblTap:_e,onTransformStart:()=>{K(!0),Qe.current={cropX:A.cropX,cropY:A.cropY,cropWidth:A.cropWidth,cropHeight:A.cropHeight}},onTransform:xe=>{var Fe;const tt=xe.currentTarget,mt=Math.abs(tt.scaleX()-1)<1e-7?1:tt.scaleX(),Ot=Math.abs(tt.scaleY()-1)<1e-7?1:tt.scaleY();tt.scaleX(1),tt.scaleY(1);const Lr=(Fe=xe.target.getStage())===null||Fe===void 0?void 0:Fe.findOne("Transformer"),Vr=1-be/ce.width,Or=Math.min(Vr,Math.max(0,A.cropX)),Rn=1-Ee/ce.height,mn=Math.min(Rn,Math.max(0,A.cropY)),yn=Lr.getActiveAnchor(),Zn=!(yn.indexOf("middle")>=0||yn.indexOf("center")>=0),Ei=!Zn&&mt<1&&Qe.current.cropHeight>Ee/ce.height;let Ie=Zn?A.cropWidth:A.cropWidth*mt;Ei&&(Ie=A.cropWidth);const rt=!Zn&&Ot<1&&Qe.current.cropWidth>be/ce.width;let pt=Zn?A.cropHeight:A.cropHeight*Ot;rt&&(pt=A.cropHeight),et&&(Ie=A.cropWidth,pt=A.cropHeight),A.set({cropX:Or,cropY:mn,x:tt.x(),y:tt.y(),width:tt.width()*mt,height:tt.height()*Ot,rotation:xe.target.rotation(),cropWidth:Math.min(Ie,1-Or),cropHeight:Math.min(pt,1-mn)})},onTransformEnd:xe=>{const Fe=xe.currentTarget;A.set({width:Fe.width(),height:Fe.height(),x:Fe.x(),y:Fe.y(),rotation:xe.target.rotation(),cropWidth:be/ce.width,cropHeight:Ee/ce.height}),K(!1)}}),a.default.createElement(u.Rect,{x:A.x,y:A.y,width:Math.max(A.width-A.borderSize,0),height:Math.max(A.height-A.borderSize,0),opacity:Se,offsetX:-A.borderSize/2,offsetY:-A.borderSize/2,stroke:A.borderColor,strokeWidth:A.borderSize,listening:!1,visible:!!A.borderSize,rotation:A.rotation,cornerRadius:Math.max(0,Ce-A.borderSize),hideInExport:!A.showInExport}),!Z&&!L.isPlaying&&a.default.createElement(u.Image,{image:T,x:A.x+A.width/2-15/L.scale,y:A.y+A.height/2-15/L.scale,width:30/L.scale,height:30/L.scale,hideInExport:!0,onClick:()=>{te(!0)}}),Z&&!L.isPlaying&&a.default.createElement(u.Image,{image:C,x:A.x+A.width/2-15/L.scale,y:A.y+A.height/2-15/L.scale,width:30/L.scale,height:30/L.scale,hideInExport:!0,onClick:()=>{te(!1)}}),A._cropModeEnabled&&a.default.createElement(E.Portal,{selector:".page-abs-container",enabled:!0},a.default.createElement(u.Rect,{x:-window.innerWidth/L.scale,y:-window.innerWidth/L.scale,width:window.innerWidth/L.scale*3,height:window.innerWidth/L.scale*3,fill:"rgba(0,0,0,0.3)"}),a.default.createElement(u.Image,{listening:!1,image:ke,x:A.x,y:A.y,width:A.width,height:A.height,rotation:A.rotation,shadowEnabled:A.shadowEnabled,shadowBlur:A.shadowBlur}),a.default.createElement(u.Group,{x:A.x,y:A.y,rotation:A.rotation,scaleX:Ne,scaleY:Ne},a.default.createElement(u.Image,{image:ce,ref:$,opacity:.4,draggable:!0,x:-A.cropX*ce.width,y:-A.cropY*ce.height,onDragMove:Ye,onTransform:Ye}),a.default.createElement(u.Transformer,{ref:fe,anchorSize:20,enabledAnchors:["top-left","top-right","bottom-left","bottom-right"],boundBoxFunc:(xe,Fe)=>Fe.width<5||Fe.height<5?xe:Fe,rotateEnabled:!1,borderEnabled:!1,anchorCornerRadius:10,anchorStrokeWidth:2,borderStrokeWidth:2}),a.default.createElement(u.Rect,{width:be,height:Ee,ref:Ze,listening:!1,onTransform:xe=>{xe.target.x()<-A.cropX*ce.width-1e-9&&(xe.target.x(-A.cropX*ce.width),xe.target.scaleX(1)),xe.target.y()<-A.cropY*ce.height-1e-9&&(xe.target.y(-A.cropY*ce.height),xe.target.scaleY(1));const Fe=Math.min(1,Math.max(0,A.cropX+xe.target.x()/ce.width)),tt=Math.min(1,Math.max(0,xe.target.y()/ce.height+A.cropY)),mt=xe.target.width()*xe.target.scaleX(),Ot=xe.target.height()*xe.target.scaleY(),Lr=Math.min(1-Fe,mt/ce.width),Vr=Math.min(1-tt,Ot/ce.height),Or=xe.target.getAbsolutePosition(xe.target.getParent().getParent());xe.target.scale({x:1,y:1}),xe.target.position({x:0,y:0}),A.set({x:Or.x,y:Or.y,cropX:Fe,cropY:tt,cropWidth:Lr,cropHeight:Vr,width:Math.min(mt*Ne,ce.width*(1-Fe)*Ne),height:Math.min(Ot*Ne,ce.height*(1-tt)*Ne)})}}),a.default.createElement(u.Transformer,{ref:ue,enabledAnchors:["top-left","top-right","bottom-left","bottom-right"],boundBoxFunc:(xe,Fe)=>Fe.width<5||Fe.height<5?xe:Fe,keepRatio:!1,rotateEnabled:!1,anchorFill:"rgb(240, 240, 240)",anchorStrokeWidth:2,borderStrokeWidth:2}))),(B||X)&&a.default.createElement(w.Highlighter,{element:A}))})})(fS);var dS={},Qp={};(function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.figureToSvg=e.subTypeToPathDataFunc=e.TYPES=e.crossPath=e.speechBubblePath=e.hexagonPath=e.pentagonPath=e.diamondPath=e.starPath=e.circleData=e.rightTriangleData=e.triangleData=e.rectData=void 0;const t=({width:b,height:m,cornerRadius:v})=>{if(v>0){const y=Math.min(v,b/2,m/2);return`M 0 ${y} A ${y} ${y} 0 0 1 ${y} 0 L ${b-y} 0 A ${y} ${y} 0 0 1 ${b} ${y} L ${b} ${m-y} A ${y} ${y} 0 0 1 ${b-y} ${m} L ${y} ${m} A ${y} ${y} 0 0 1 0 ${m-y} Z`}return`M 0 0 L ${b} 0 L ${b} ${m} L 0 ${m} Z`};e.rectData=t;const r=({width:b,height:m})=>`M ${b/2} 0 L ${b} ${m} L 0 ${m} Z`;e.triangleData=r;const n=({width:b,height:m})=>`M 0 0 L ${b} 0 L 0 ${m} Z`;e.rightTriangleData=n;const i=({width:b,height:m})=>`M ${b/2} ${m/2} m -${b/2}, 0 a ${b/2},${m/2} 0 1,0 ${b},0 a ${b/2},${m/2} 0 1,0 -${b},0`;function a({width:b,height:m}){const v=b/2,y=m/2,d=b/2,g=m/2,_=d/2,T=g/2;let C="",P=Math.PI/5;for(let O=0;O<10;O++){const x=O%2==0?g:T,k=v+(O%2==0?d:_)*Math.sin(O*P),M=y-x*Math.cos(O*P);O===0?C=`M ${k} ${M}`:C+=` L ${k} ${M}`}return C+" Z"}function o({width:b,height:m}){const v=b/2,y=m/2;return`M ${v} 0 L ${b} ${y} L ${v} ${m} L 0 ${y} Z`}function l({width:b,height:m}){const v=b/2,y=m/2,d=b/2,g=m/2;let _="",T=2*Math.PI/5;for(let C=0;C<5;C++){const P=g,O=v+d*Math.sin(C*T),x=y-P*Math.cos(C*T);C===0?_=`M ${O} ${x}`:_+=` L ${O} ${x}`}return _+" Z"}function u({width:b,height:m}){const v=b/2,y=m/2,d=b/2,g=m/2;let _="",T=2*Math.PI/6;for(let C=0;C<6;C++){const P=g,O=v+d*Math.sin(C*T),x=y-P*Math.cos(C*T);C===0?_=`M ${O} ${x}`:_+=` L ${O} ${x}`}return _+" Z"}function f({path:b,aspectRatio:m,width:v,height:y}){return{path:b,scaleX:v/m.width,scaleY:y/m.height}}function h({width:b,height:m}){const v=.1*Math.min(b,m),y=.2*b,d=.2*m,g=.5*b;let _=`M ${v},0`;return _+=" H "+(b-v),_+=` A ${v},${v} 0 0 1 ${b},${v}`,_+=" V "+(m-v-d),_+=` A ${v},${v} 0 0 1 ${b-v},${m-d}`,_+=` H ${g+y/2}`,_+=` L ${g},${m}`,_+=` L ${g-y/2},${m-d}`,_+=` H ${v}`,_+=` A ${v},${v} 0 0 1 0,${m-v-d}`,_+=` V ${v}`,_+=` A ${v},${v} 0 0 1 ${v},0`,_+=" Z",_}function E({width:b,height:m}){const v=.3*b,y=.3*m,d=b/2,g=m/2,_=d-v/2,T=d+v/2,C=g-y/2,P=g+y/2;let O=`M ${_},0 `;return O+=`H ${T} `,O+=`V ${C} `,O+=`H ${b} `,O+=`V ${P} `,O+=`H ${T} `,O+=`V ${m} `,O+=`H ${_} `,O+=`V ${P} `,O+="H 0 ",O+=`V ${C} `,O+=`H ${_} `,O+="V 0 ",O+="Z",O}function w(b){return e.TYPES[b]||e.rectData}function p(b,m){const{width:v,height:y,fill:d,stroke:g,strokeWidth:_,dash:T}=b,C=(T||[]).map(M=>M*_);let P=m(b),O=1,x=1;typeof P!="string"&&(O=P.scaleX,x=P.scaleY,P=P.path);const k=`clip-${b.id||Math.random()}`;return`
235
235
  <svg xmlns="http://www.w3.org/2000/svg" width="${v}" height="${y}">
236
236
  <defs>
237
237
  <clipPath id="${k}">
package/dist/index.html CHANGED
@@ -8,7 +8,7 @@
8
8
  }
9
9
  </style>
10
10
  <meta name="viewport" content="width=device-width, initial-scale=1" />
11
- <script type="module" crossorigin src="./assets/index-Q-NKf7Mv.js"></script>
11
+ <script type="module" crossorigin src="./assets/index-BWNdW2kw.js"></script>
12
12
  </head>
13
13
  <body>
14
14
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polotno-node",
3
- "version": "2.9.36",
3
+ "version": "2.9.38",
4
4
  "description": "Polotno workflow from NodeJS",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -26,7 +26,7 @@
26
26
  "gifencoder": "^2.0.1",
27
27
  "pixelmatch": "^6.0.0",
28
28
  "pngjs": "^7.0.0",
29
- "polotno": "^2.11.4",
29
+ "polotno": "^2.11.5",
30
30
  "react": "^18.3.1",
31
31
  "react-dom": "^18.3.1",
32
32
  "vite": "^5.3.4"
package/video-parallel.js CHANGED
@@ -57,21 +57,23 @@ const fileToDataUrl = (filename) => {
57
57
  });
58
58
  };
59
59
 
60
- const convertVideo = async (url, tempFolder) => {
60
+ const convertVideo = async (url, tempFolder, skipWebm) => {
61
61
  const shortUrl = url.slice(0, 50) + '...';
62
62
  console.log('Downloading video: ' + shortUrl);
63
63
  const filename = Math.random().toString(36).substring(7);
64
64
  const mp4Destination = path.join(tempFolder.name, filename + '.mp4');
65
65
  await downloadVideo(url, mp4Destination);
66
- console.log('Converting video to webm: ' + filename);
67
- const webmDestination = mp4Destination.replace('.mp4', '.webm');
68
- await convertToWebM(mp4Destination, webmDestination);
69
- const dataURL = await fileToDataUrl(webmDestination);
66
+ let dataURL = '';
67
+ if (!skipWebm) {
68
+ console.log('Converting video to webm: ' + filename);
69
+ const webmDestination = mp4Destination.replace('.mp4', '.webm');
70
+ await convertToWebM(mp4Destination, webmDestination);
71
+ dataURL = await fileToDataUrl(webmDestination);
72
+ console.log('Converting video finished: ' + filename);
73
+ }
70
74
 
71
- console.log('Converting video finished: ' + filename);
72
75
  return {
73
76
  dataURL,
74
- file: webmDestination,
75
77
  mp4File: mp4Destination,
76
78
  };
77
79
  };
@@ -106,7 +108,9 @@ module.exports.jsonToVideo = async function jsonToVideo(
106
108
  tempFolder,
107
109
  attrs.skipWebm
108
110
  );
109
- el.src = dataURL;
111
+ if (!attrs.skipWebm) {
112
+ el.src = dataURL;
113
+ }
110
114
  el.file = file;
111
115
  el.mp4File = mp4File;
112
116
  })
@@ -115,9 +119,13 @@ module.exports.jsonToVideo = async function jsonToVideo(
115
119
  const duration = json.pages.reduce((acc, page) => {
116
120
  return acc + (page.duration ?? 5000);
117
121
  }, 0);
122
+
123
+ if (duration === 0) {
124
+ throw new Error('Video duration is 0');
125
+ }
118
126
  const parallel = attrs.parallel || 5;
119
127
 
120
- const fps = attrs.fps || 15;
128
+ const fps = attrs.fps || 30;
121
129
  const timePerFrame = 1000 / fps;
122
130
 
123
131
  // loop through the images and add each to the animation
@@ -149,6 +157,8 @@ module.exports.jsonToVideo = async function jsonToVideo(
149
157
  chunks.map(async (chunk, chunkIndex) => {
150
158
  const instance = typeof inst === 'function' ? await inst() : inst;
151
159
  const page = await instance.createPage();
160
+ page.setDefaultNavigationTimeout(60000); // Increase timeout to 60 seconds
161
+
152
162
  await page.evaluate(async (json) => {
153
163
  store.loadJSON(json);
154
164
  await store.waitLoading();
@@ -217,7 +227,7 @@ module.exports.jsonToVideo = async function jsonToVideo(
217
227
  finishedFramesNumber += 1;
218
228
  if (attrs.onProgress) {
219
229
  const frameTime = Date.now() - startTime;
220
- const progress = finishedFramesNumber / framesNumber;
230
+ const progress = (finishedFramesNumber / framesNumber) * 0.95;
221
231
  attrs.onProgress(progress, frameTime);
222
232
  }
223
233
  }
@@ -251,6 +261,7 @@ module.exports.jsonToVideo = async function jsonToVideo(
251
261
  inputEndTime: elEndTime,
252
262
  outputStartTime: pageStartTime,
253
263
  outputEndTime: pageStartTime + pageDuration,
264
+ volume: el.volume,
254
265
  });
255
266
  }
256
267
  }
@@ -267,6 +278,8 @@ module.exports.jsonToVideo = async function jsonToVideo(
267
278
  .outputOptions('-pix_fmt yuv420p')
268
279
  .videoFilters('scale=trunc(iw/2)*2:trunc(ih/2)*2'); // Ensure dimensions are divisible by 2
269
280
 
281
+ const audioInputs = [];
282
+
270
283
  // Add each audio segment as a separate input
271
284
  inputs.forEach((input, index) => {
272
285
  const inputStartSec = (input.inputStartTime / 1000).toFixed(3);
@@ -274,31 +287,50 @@ module.exports.jsonToVideo = async function jsonToVideo(
274
287
  (input.inputEndTime - input.inputStartTime) /
275
288
  1000
276
289
  ).toFixed(3);
277
- const outputOffsetSec = (input.outputStartTime / 1000).toFixed(3);
290
+ const outputOffsetMs = Math.round(input.outputStartTime);
291
+ console.log({ outputOffsetMs });
292
+ const volume = input.volume !== undefined ? input.volume : 1;
278
293
 
279
- // Apply `-itsoffset` before each input file to shift its audio stream
280
294
  ffmpegCmd
281
- .inputOptions([`-itsoffset ${outputOffsetSec}`]) // Shift the input time
282
- .input(input.mp4File) // Add the actual input file
283
- .inputOptions([`-ss ${inputStartSec}`, `-t ${inputDurationSec}`]); // Specify the timing to cut the audio
295
+ .input(input.mp4File)
296
+ .inputOptions([`-ss ${inputStartSec}`, `-t ${inputDurationSec}`]);
297
+
298
+ audioInputs.push({
299
+ index: index + 1, // +1 because the first input is the image sequence
300
+ delay: outputOffsetMs,
301
+ volume: volume,
302
+ });
284
303
  });
285
304
 
286
305
  // Map the video stream from the image sequence
287
306
  ffmpegCmd.outputOptions(['-map 0:v']);
288
307
 
289
- // Map each audio stream
290
- inputs.forEach((_, index) => {
291
- ffmpegCmd.outputOptions([`-map ${index + 1}:a?`]);
292
- });
308
+ // Prepare audio filter complex
309
+ if (audioInputs.length > 0) {
310
+ const audioFilters = audioInputs.map(
311
+ (input, i) =>
312
+ `[${input.index}:a]adelay=${input.delay}|${input.delay},volume=${input.volume}[a${i}]`
313
+ );
314
+ const audioMerge = audioInputs.map((_, i) => `[a${i}]`).join('');
315
+ const filterComplex = `${audioFilters.join(
316
+ ';'
317
+ )};${audioMerge}amix=inputs=${
318
+ audioInputs.length
319
+ }:duration=longest[aout]`;
320
+
321
+ ffmpegCmd.complexFilter(filterComplex);
322
+ ffmpegCmd.outputOptions(['-map [aout]']);
323
+ }
293
324
 
294
325
  ffmpegCmd
295
326
  .format(format)
296
327
  .audioCodec('aac')
328
+ .on('start', (command) => console.log('FFmpeg command:', command))
297
329
  .on('end', () => resolve())
298
330
  .on('error', (err, stdout, stderr) => {
299
- console.log(err.message);
300
- console.log('stdout:\n' + stdout);
301
- console.log('stderr:\n' + stderr);
331
+ console.error('Error:', err.message);
332
+ console.error('stdout:', stdout);
333
+ console.error('stderr:', stderr);
302
334
  reject(err);
303
335
  })
304
336
  .save(attrs.out);