polotno 4.2.1 → 4.3.0

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.
Files changed (64) hide show
  1. package/blueprint/pages-timeline/page-preview.js +2 -2
  2. package/blueprint/toolbar/html-toolbar.js +3 -3
  3. package/canvas/apply-filters.d.ts +11 -0
  4. package/canvas/apply-filters.js +1 -1
  5. package/canvas/audio.js +1 -1
  6. package/canvas/element.js +1 -1
  7. package/canvas/gif-element.js +1 -1
  8. package/canvas/hotkeys.d.ts +8 -0
  9. package/canvas/hotkeys.js +1 -1
  10. package/canvas/html-element.js +1 -1
  11. package/canvas/image-element.js +1 -1
  12. package/canvas/render-tag-element.js +1 -1
  13. package/canvas/rich-editor.js +2 -2
  14. package/canvas/table-element.js +1 -1
  15. package/canvas/text-element/fit-font-size.js +1 -1
  16. package/canvas/text-element.js +1 -1
  17. package/canvas/tooltip.js +1 -1
  18. package/canvas/use-filtered-source.d.ts +2 -0
  19. package/canvas/use-filtered-source.js +1 -0
  20. package/canvas/use-mediabunny-video.js +1 -1
  21. package/canvas/video-element.d.ts +1 -1
  22. package/canvas/video-element.js +1 -1
  23. package/canvas/workspace-canvas.d.ts +2 -1
  24. package/canvas/workspace-canvas.js +1 -1
  25. package/model/group-model.d.ts +1 -0
  26. package/model/group-model.js +1 -1
  27. package/model/page-model.d.ts +1 -0
  28. package/model/store.d.ts +9 -0
  29. package/model/store.js +1 -1
  30. package/model/text-model.d.ts +1 -0
  31. package/model/text-model.js +1 -1
  32. package/package.json +3 -3
  33. package/pages-timeline/page-preview.js +1 -1
  34. package/polotno.bundle.js +127 -126
  35. package/side-panel/effects-panel.js +1 -1
  36. package/side-panel/upload-panel.d.ts +1 -3
  37. package/side-panel/upload-panel.js +1 -1
  38. package/toolbar/html-toolbar.js +3 -3
  39. package/utils/base64.d.ts +2 -0
  40. package/utils/base64.js +1 -0
  41. package/utils/clipboard.d.ts +361 -0
  42. package/utils/clipboard.js +1 -1
  43. package/utils/errors.d.ts +7 -0
  44. package/utils/errors.js +1 -0
  45. package/utils/file.d.ts +6 -0
  46. package/utils/file.js +1 -1
  47. package/utils/fonts.js +1 -1
  48. package/utils/image-dpi.js +1 -1
  49. package/utils/insert-file.d.ts +23 -0
  50. package/utils/insert-file.js +1 -0
  51. package/utils/l10n.d.ts +4 -0
  52. package/utils/l10n.js +1 -1
  53. package/utils/loader.d.ts +3 -2
  54. package/utils/loader.js +1 -1
  55. package/utils/mobx.d.ts +4 -0
  56. package/utils/mobx.js +1 -0
  57. package/utils/text-html.d.ts +1 -0
  58. package/utils/text-html.js +1 -1
  59. package/utils/text-types.d.ts +2 -0
  60. package/utils/text-types.js +1 -1
  61. package/utils/to-html.js +1 -1
  62. package/utils/to-svg.js +1 -1
  63. package/utils/validate-key.js +1 -1
  64. package/utils/video.js +1 -1
@@ -1 +1 @@
1
- const t=[112,72,89,115],e=(()=>{const t=new Uint32Array(256);for(let e=0;e<256;e++){let n=e;for(let t=0;t<8;t++){n=1&n?3988292384^n>>>1:n>>>1}t[e]=n>>>0}return t})(),n=()=>"undefined"!=typeof globalThis?globalThis.Buffer:void 0,r=(t,e,n)=>{t[e]=n>>>24&255,t[e+1]=n>>>16&255,t[e+2]=n>>>8&255,t[e+3]=255&n};export const addDpiMetadataToImage=(o,s,a)=>{const l=o.indexOf(","),i=(t=>{if("function"==typeof atob){const e=atob(t),n=new Uint8Array(e.length);for(let t=0;t<e.length;t++){n[t]=e.charCodeAt(t)}return n}const e=n();if(e){return new Uint8Array(e.from(t,"base64"))}throw new Error("No base64 decoder available")})(l>=0?o.slice(l+1):o),f="image/png"===s?((n,o)=>{const s=(n=>{const o=new Uint8Array(9),s=new DataView(o.buffer);s.setUint32(0,n,!1),s.setUint32(4,n,!1),o[8]=1;const a=new Uint8Array(8+o.length+4);r(a,0,o.length),a.set(t,4),a.set(o,8);const l=new Uint8Array(4+o.length);return l.set(t,0),l.set(o,4),r(a,8+o.length,(t=>{let n=4294967295;for(let r=0;r<t.length;r++){n=e[255&(n^t[r])]^n>>>8}return(4294967295^n)>>>0})(l)),a})(Math.round(o/.0254)),a=((t,e)=>{let n=8;for(;n+8<=t.length;){const r=t[n]<<24|t[n+1]<<16|t[n+2]<<8|t[n+3],o=n+4,s=t.subarray(o,o+4),a=8+r+4;if(e.every((t,e)=>s[e]===t)){return{offset:n,totalLength:a}}n+=a}return null})(n,t);if(a){const t=new Uint8Array(n.length-a.totalLength+s.length);return t.set(n.slice(0,a.offset),0),t.set(s,a.offset),t.set(n.slice(a.offset+a.totalLength),a.offset+s.length),t}const l=16+(n[8]<<24|n[9]<<16|n[10]<<8|n[11])+4;if(l>n.length){return n}const i=new Uint8Array(n.length+s.length);return i.set(n.slice(0,l),0),i.set(s,l),i.set(n.slice(l),l+s.length),i})(i,a):((t,e)=>{const n=(t=>{let e=2;for(;e+4<t.length;){if(255!==t[e]){return-1}const n=t[e+1];if(216===n||217===n){e+=2;continue}const r=t[e+2]<<8|t[e+3];if(r<2){return-1}if(224===n&&74===t[e+4]&&70===t[e+5]&&73===t[e+6]&&70===t[e+7]&&0===t[e+8]){return e}const o=e+2+r;if(o<=e||o>t.length){return-1}e=o}return-1})(t);if(n>=0){const r=new Uint8Array(t),o=n+11;return r[o]=1,r[o+1]=e>>8&255,r[o+2]=255&e,r[o+3]=e>>8&255,r[o+4]=255&e,r}const r=(t=>{const e=new Uint8Array(18);return e[0]=255,e[1]=224,e[2]=0,e[3]=16,e[4]=74,e[5]=70,e[6]=73,e[7]=70,e[8]=0,e[9]=1,e[10]=1,e[11]=1,e[12]=t>>8&255,e[13]=255&t,e[14]=t>>8&255,e[15]=255&t,e})(e),o=new Uint8Array(t.length+r.length);return o.set(t.subarray(0,2),0),o.set(r,2),o.set(t.subarray(2),2+r.length),o})(i,a);return`data:${s};base64,${(t=>{if("function"==typeof btoa){let e="";for(let n=0;n<t.length;n++){e+=String.fromCharCode(t[n])}return btoa(e)}const e=n();if(e){return e.from(t).toString("base64")}throw new Error("No base64 encoder available")})(f)}`};
1
+ import{decodeBase64 as t,encodeBase64 as e}from"./base64.js";const n=[112,72,89,115],r=(()=>{const t=new Uint32Array(256);for(let e=0;e<256;e++){let n=e;for(let t=0;t<8;t++){n=1&n?3988292384^n>>>1:n>>>1}t[e]=n>>>0}return t})(),s=(t,e,n)=>{t[e]=n>>>24&255,t[e+1]=n>>>16&255,t[e+2]=n>>>8&255,t[e+3]=255&n};export const addDpiMetadataToImage=(o,l,a)=>{const i=o.indexOf(","),f=i>=0?o.slice(i+1):o,c=t(f),g="image/png"===l?((t,e)=>{const o=(t=>{const e=new Uint8Array(9),o=new DataView(e.buffer);o.setUint32(0,t,!1),o.setUint32(4,t,!1),e[8]=1;const l=new Uint8Array(8+e.length+4);s(l,0,e.length),l.set(n,4),l.set(e,8);const a=new Uint8Array(4+e.length);return a.set(n,0),a.set(e,4),s(l,8+e.length,(t=>{let e=4294967295;for(let n=0;n<t.length;n++){e=r[255&(e^t[n])]^e>>>8}return(4294967295^e)>>>0})(a)),l})(Math.round(e/.0254)),l=((t,e)=>{let n=8;for(;n+8<=t.length;){const r=t[n]<<24|t[n+1]<<16|t[n+2]<<8|t[n+3],s=n+4,o=t.subarray(s,s+4),l=8+r+4;if(e.every((t,e)=>o[e]===t)){return{offset:n,totalLength:l}}n+=l}return null})(t,n);if(l){const e=new Uint8Array(t.length-l.totalLength+o.length);return e.set(t.slice(0,l.offset),0),e.set(o,l.offset),e.set(t.slice(l.offset+l.totalLength),l.offset+o.length),e}const a=16+(t[8]<<24|t[9]<<16|t[10]<<8|t[11])+4;if(a>t.length){return t}const i=new Uint8Array(t.length+o.length);return i.set(t.slice(0,a),0),i.set(o,a),i.set(t.slice(a),a+o.length),i})(c,a):((t,e)=>{const n=(t=>{let e=2;for(;e+4<t.length;){if(255!==t[e]){return-1}const n=t[e+1];if(216===n||217===n){e+=2;continue}const r=t[e+2]<<8|t[e+3];if(r<2){return-1}if(224===n&&74===t[e+4]&&70===t[e+5]&&73===t[e+6]&&70===t[e+7]&&0===t[e+8]){return e}const s=e+2+r;if(s<=e||s>t.length){return-1}e=s}return-1})(t);if(n>=0){const r=new Uint8Array(t),s=n+11;return r[s]=1,r[s+1]=e>>8&255,r[s+2]=255&e,r[s+3]=e>>8&255,r[s+4]=255&e,r}const r=(t=>{const e=new Uint8Array(18);return e[0]=255,e[1]=224,e[2]=0,e[3]=16,e[4]=74,e[5]=70,e[6]=73,e[7]=70,e[8]=0,e[9]=1,e[10]=1,e[11]=1,e[12]=t>>8&255,e[13]=255&t,e[14]=t>>8&255,e[15]=255&t,e})(e),s=new Uint8Array(t.length+r.length);return s.set(t.subarray(0,2),0),s.set(r,2),s.set(t.subarray(2),2+r.length),s})(c,a);return`data:${l};base64,${e(g)}`};
@@ -0,0 +1,23 @@
1
+ import type { StoreType, ShapeType } from '../ui-types.js';
2
+ import { MediaType } from './file.js';
3
+ type MediaProps = {
4
+ url: string;
5
+ type: MediaType;
6
+ store: StoreType;
7
+ droppedPos?: {
8
+ x: number;
9
+ y: number;
10
+ };
11
+ targetElement?: ShapeType;
12
+ };
13
+ export declare const insertMediaIntoPage: ({ url, type, store, droppedPos, targetElement, }: MediaProps) => Promise<void>;
14
+ type FileProps = {
15
+ file: File;
16
+ store: StoreType;
17
+ droppedPos?: {
18
+ x: number;
19
+ y: number;
20
+ };
21
+ };
22
+ export declare const insertFileIntoPage: ({ file, store, droppedPos }: FileProps) => Promise<void>;
23
+ export {};
@@ -0,0 +1 @@
1
+ import{getType as e,getUploadFunc as t}from"./file.js";import{selectImage as o}from"../side-panel/select-image.js";import{selectVideo as s}from"../side-panel/select-video.js";import{selectSvg as r}from"../side-panel/select-svg.js";import{selectGif as a}from"../side-panel/select-gif.js";export const insertMediaIntoPage=async({url:e,type:t,store:i,droppedPos:p,targetElement:d})=>{const n=e;"image"===t?await o({src:n,store:i,droppedPos:p,targetElement:d}):"svg"===t?await r({src:n,store:i,droppedPos:p,targetElement:d}):"gif"===t?await a({src:n,store:i,droppedPos:p,targetElement:d}):"video"===t?await s({src:n,store:i,droppedPos:p,targetElement:d}):"audio"===t&&i.addAudio({src:n})};export const insertFileIntoPage=async({file:o,store:s,droppedPos:r})=>{const a=await t()(o);await insertMediaIntoPage({url:a,type:e(o),store:s,droppedPos:r})};
package/utils/l10n.d.ts CHANGED
@@ -28,6 +28,10 @@ export declare const getTranslations: () => {
28
28
  natural: string;
29
29
  warm: string;
30
30
  textStroke: string;
31
+ strokeLineJoin: string;
32
+ joinRound: string;
33
+ joinMiter: string;
34
+ joinBevel: string;
31
35
  shadow: string;
32
36
  border: string;
33
37
  cornerRadius: string;
package/utils/l10n.js CHANGED
@@ -1 +1 @@
1
- import{observable as e,action as o,toJS as r}from"mobx";const a=e({toolbar:{duration:"Duration",opacity:"Opacity",effects:"Effects",blur:"Blur",curvedText:"Curved text",curvePower:"Power",temperature:"Temperature",saturation:"Saturation",contrast:"Contrast",shadows:"Shadows",white:"White",black:"Black",vibrance:"Vibrance",textBackground:"Background",backgroundCornerRadius:"Corner radius",backgroundOpacity:"Opacity",backgroundPadding:"Padding",brightness:"Brightness",filters:"Filters",sepia:"Sepia",grayscale:"Grayscale",cold:"Cold",natural:"Natural",warm:"Warm",textStroke:"Text Stroke",shadow:"Shadow",border:"Border",cornerRadius:"Corner Radius",copyStyle:"Copy style",uppercase:"Uppercase",position:"Position",layering:"Layering",toForward:"To Front",up:"Forward",down:"Backward",toBottom:"To back",alignLeft:"Align left",alignCenter:"Align center",alignRight:"Align right",alignTop:"Align top",alignMiddle:"Align middle",alignBottom:"Align bottom",flip:"Flip",flipHorizontally:"Flip horizontally",flipVertically:"Flip vertically",fitToBackground:"Fit to page",removeBackground:"Remove background",removeBackgroundTitle:"Remove background from image",cancelRemoveBackground:"Cancel",confirmRemoveBackground:"Confirm",crop:"Crop",cropDone:"Done",cropCancel:"Cancel",clip:"Apply mask",removeClip:"Remove mask",removeMask:"Remove mask",transparency:"Transparency",lockedDescription:"Object is locked. Unlock it to allow changes from canvas.",unlockedDescription:"Object is unlocked. Lock it to prevent changes from canvas.",removeElements:"Remove elements",duplicateElements:"Duplicate elements",download:"Download",saveAsImage:"Save as image",saveAsPDF:"Save as PDF",lineHeight:"Line height",letterSpacing:"Letter spacing",offsetX:"Offset X",offsetY:"Offset Y",color:"Color",selectable:"Selectable",draggable:"Draggable",removable:"Removable",resizable:"Resizable",contentEditable:"Can change content",styleEditable:"Can change style",alwaysOnTop:"Always on top",showInExport:"Show in export",ungroupElements:"Ungroup",groupElements:"Group",lineSize:"Line size",fade:"Fade",move:"Move",zoom:"Zoom",animate:"Animate",rotate:"Rotate",none:"None",bounce:"Bounce",blink:"Blink",strength:"Strength",spaceEvenly:"Space evenly",horizontalDistribution:"Horizontally",verticalDistribution:"Vertically",strokeWidth:"Stroke Width",strokeSettings:"Stroke settings",spacing:"Spacing",volume:"Volume",speed:"Speed",seconds:"sec",lineStyle:"Line style",lineStartHead:"Line start",lineEndHead:"Line end",textDirection:"Text direction",fontSize:"Font size",fontFamily:"Font family",fontFamilyMixed:"Mixed",fontsInSelection:"Fonts in selection",textAlign:"Text align",verticalAlign:"Vertical align",bold:"Bold",italic:"Italic",underline:"Underline",strikethrough:"Strikethrough",cellBackground:"Cell background",tableBorderSettings:"Border settings",tableBorderColor:"Border color",tableBorderWidth:"Border width",tableBorderStyle:"Border style",borderModeAll:"All borders",borderModeOuter:"Outer borders",borderModeInner:"Inner borders",borderModeBottomOnly:"Bottom only",borderModeTopOnly:"Top only",borderModeLeftOnly:"Left only",borderModeRightOnly:"Right only",borderModeInnerHorizontal:"Inner horizontal",borderModeInnerVertical:"Inner vertical",tableStructure:"Table structure",tableRows:"Rows",tableColumns:"Columns",insertRowAbove:"Insert row above",insertRowBelow:"Insert row below",deleteRow:"Delete row",insertColumnLeft:"Insert column left",insertColumnRight:"Insert column right",deleteColumn:"Delete column",deleteRows:"Delete rows",deleteColumns:"Delete columns",distributeRowsEvenly:"Distribute rows evenly",distributeColumnsEvenly:"Distribute columns evenly",cellPadding:"Cell padding",listFormat:"List",colorPicker:{solid:"Solid",linear:"Linear",angle:"Angle",colors:"Colors",resetColors:"Reset",recolorAll:"Recolor all"},aiText:{aiWrite:"AI write",rewrite:"Rewrite",shorten:"Shorten",continue:"Continue writing",proofread:"Proofread",tones:"Tones",friendly:"Friendly",professional:"Professional",humorous:"Humorous",formal:"Formal",customPrompt:"Custom prompt",generatedResult:"Generated result",cancel:"Cancel",generate:"Generate",back:"Back",tryAgain:"Try Again",insert:"Insert",promptPlaceholder:"Describe what you want to generate"}},workspace:{noPages:"There are no pages yet...",addPage:"Add page",removePage:"Remove page",duplicatePage:"Duplicate page",moveUp:"Move up",moveDown:"Move down",moveLeft:"Move left",moveRight:"Move right"},scale:{reset:"Reset"},error:{removeBackground:"Ops! Something went wrong. Background can not be removed."},sidePanel:{templates:"Templates",searchTemplatesWithSameSize:"Show templates with the same size",searchPlaceholder:"Search...",otherFormats:"Other formats",noResults:"No results",error:"Loading is failed...",text:"Text",uploadFont:"Upload font",myFonts:"My fonts",photos:"Photos",videos:"Videos",animations:"Animations",effects:"Effects",elements:"Elements",shapes:"Shapes",tables:"Tables",lines:"Lines",draw:"Draw",upload:"Upload",uploadImage:"Add file",uploadTip:"Upload your assets",background:"Background",resize:"Resize",layers:"Layers",animate:"Animate",layerTypes:{image:"Image",text:"Text",svg:"SVG",line:"Line",figure:"Figure",group:"Group"},layersTip:"Elements on your active page:",noLayers:"No elements on the page...",namePlaceholder:"Type element name...",useMagicResize:"Use magic resize",advanced:"Advanced",bleed:"Bleed",showBleed:"Show bleed",clipImage:"Mask image",width:"Width",height:"Height",units:"Units",magicResizeDescription:"Magic resize will automatically resize and move all elements on the canvas",headerText:"Header",createHeader:"Create header",subHeaderText:"Sub Header",createSubHeader:"Create sub header",bodyText:"Body text",createBody:"Create body text"},pagesTimeline:{pages:"Pages",removePage:"Remove page",addPage:"Add page",duplicatePage:"Duplicate page",removeAudio:"Remove audio",duplicateAudio:"Duplicate audio",muteAudio:"Mute",unmuteAudio:"Unmute",volume:"Volume",speed:"Speed",rewind:"Rewind to start",editAsVideo:"Edit as video",editAsVideoHint:"On: preview the frame at the playhead — timed elements hide outside their range. Off: show all elements while editing."},contextMenu:{duplicate:"Duplicate",split:"Split at playhead",remove:"Remove",lock:"Lock",unlock:"Unlock",copy:"Copy",paste:"Paste",copyStyle:"Copy style",moveUp:"Move up",moveDown:"Move down",moveBack:"Move back",moveForward:"Move forward"}}),n=e=>e&&"object"==typeof e;function i(e,o){Object.keys(o).forEach(r=>{const a=e[r],l=o[r];n(l)&&n(a)?i(a,l):e[r]=l})}function l(e,o,r=""){Object.keys(o).forEach(a=>{const i=o[a],s=r?`${r}.${a}`:a;n(i)?n(e[a])?l(e[a],i,s):console.warn(`Missing nested translation object at '${s}'`):void 0===e[a]&&console.warn(`Missing translation '${s}'`)})}export const setTranslations=o((e,{validate:o=!1}={})=>{o&&l(e,a),i(a,e)});export const getTranslations=()=>r(a);const s={};export const t=e=>{const o=function(e,o){var r,a=o.split("."),n=e;for(r=0;r<a.length;++r){if(null==n[a[r]]){return}n=n[a[r]]}return n}(a,e);if(void 0!==o){return o}s[e]||(s[e]=!0,console.warn(`Missing translation '${e}'`));const r=e.split("."),n=r[r.length-1]||" ";return n.charAt(0).toUpperCase()+n.slice(1)};
1
+ import{observable as e,action as o,toJS as r}from"mobx";const a=e({toolbar:{duration:"Duration",opacity:"Opacity",effects:"Effects",blur:"Blur",curvedText:"Curved text",curvePower:"Power",temperature:"Temperature",saturation:"Saturation",contrast:"Contrast",shadows:"Shadows",white:"White",black:"Black",vibrance:"Vibrance",textBackground:"Background",backgroundCornerRadius:"Corner radius",backgroundOpacity:"Opacity",backgroundPadding:"Padding",brightness:"Brightness",filters:"Filters",sepia:"Sepia",grayscale:"Grayscale",cold:"Cold",natural:"Natural",warm:"Warm",textStroke:"Text Stroke",strokeLineJoin:"Corners",joinRound:"Round",joinMiter:"Miter",joinBevel:"Bevel",shadow:"Shadow",border:"Border",cornerRadius:"Corner Radius",copyStyle:"Copy style",uppercase:"Uppercase",position:"Position",layering:"Layering",toForward:"To Front",up:"Forward",down:"Backward",toBottom:"To back",alignLeft:"Align left",alignCenter:"Align center",alignRight:"Align right",alignTop:"Align top",alignMiddle:"Align middle",alignBottom:"Align bottom",flip:"Flip",flipHorizontally:"Flip horizontally",flipVertically:"Flip vertically",fitToBackground:"Fit to page",removeBackground:"Remove background",removeBackgroundTitle:"Remove background from image",cancelRemoveBackground:"Cancel",confirmRemoveBackground:"Confirm",crop:"Crop",cropDone:"Done",cropCancel:"Cancel",clip:"Apply mask",removeClip:"Remove mask",removeMask:"Remove mask",transparency:"Transparency",lockedDescription:"Object is locked. Unlock it to allow changes from canvas.",unlockedDescription:"Object is unlocked. Lock it to prevent changes from canvas.",removeElements:"Remove elements",duplicateElements:"Duplicate elements",download:"Download",saveAsImage:"Save as image",saveAsPDF:"Save as PDF",lineHeight:"Line height",letterSpacing:"Letter spacing",offsetX:"Offset X",offsetY:"Offset Y",color:"Color",selectable:"Selectable",draggable:"Draggable",removable:"Removable",resizable:"Resizable",contentEditable:"Can change content",styleEditable:"Can change style",alwaysOnTop:"Always on top",showInExport:"Show in export",ungroupElements:"Ungroup",groupElements:"Group",lineSize:"Line size",fade:"Fade",move:"Move",zoom:"Zoom",animate:"Animate",rotate:"Rotate",none:"None",bounce:"Bounce",blink:"Blink",strength:"Strength",spaceEvenly:"Space evenly",horizontalDistribution:"Horizontally",verticalDistribution:"Vertically",strokeWidth:"Stroke Width",strokeSettings:"Stroke settings",spacing:"Spacing",volume:"Volume",speed:"Speed",seconds:"sec",lineStyle:"Line style",lineStartHead:"Line start",lineEndHead:"Line end",textDirection:"Text direction",fontSize:"Font size",fontFamily:"Font family",fontFamilyMixed:"Mixed",fontsInSelection:"Fonts in selection",textAlign:"Text align",verticalAlign:"Vertical align",bold:"Bold",italic:"Italic",underline:"Underline",strikethrough:"Strikethrough",cellBackground:"Cell background",tableBorderSettings:"Border settings",tableBorderColor:"Border color",tableBorderWidth:"Border width",tableBorderStyle:"Border style",borderModeAll:"All borders",borderModeOuter:"Outer borders",borderModeInner:"Inner borders",borderModeBottomOnly:"Bottom only",borderModeTopOnly:"Top only",borderModeLeftOnly:"Left only",borderModeRightOnly:"Right only",borderModeInnerHorizontal:"Inner horizontal",borderModeInnerVertical:"Inner vertical",tableStructure:"Table structure",tableRows:"Rows",tableColumns:"Columns",insertRowAbove:"Insert row above",insertRowBelow:"Insert row below",deleteRow:"Delete row",insertColumnLeft:"Insert column left",insertColumnRight:"Insert column right",deleteColumn:"Delete column",deleteRows:"Delete rows",deleteColumns:"Delete columns",distributeRowsEvenly:"Distribute rows evenly",distributeColumnsEvenly:"Distribute columns evenly",cellPadding:"Cell padding",listFormat:"List",colorPicker:{solid:"Solid",linear:"Linear",angle:"Angle",colors:"Colors",resetColors:"Reset",recolorAll:"Recolor all"},aiText:{aiWrite:"AI write",rewrite:"Rewrite",shorten:"Shorten",continue:"Continue writing",proofread:"Proofread",tones:"Tones",friendly:"Friendly",professional:"Professional",humorous:"Humorous",formal:"Formal",customPrompt:"Custom prompt",generatedResult:"Generated result",cancel:"Cancel",generate:"Generate",back:"Back",tryAgain:"Try Again",insert:"Insert",promptPlaceholder:"Describe what you want to generate"}},workspace:{noPages:"There are no pages yet...",addPage:"Add page",removePage:"Remove page",duplicatePage:"Duplicate page",moveUp:"Move up",moveDown:"Move down",moveLeft:"Move left",moveRight:"Move right"},scale:{reset:"Reset"},error:{removeBackground:"Ops! Something went wrong. Background can not be removed."},sidePanel:{templates:"Templates",searchTemplatesWithSameSize:"Show templates with the same size",searchPlaceholder:"Search...",otherFormats:"Other formats",noResults:"No results",error:"Loading is failed...",text:"Text",uploadFont:"Upload font",myFonts:"My fonts",photos:"Photos",videos:"Videos",animations:"Animations",effects:"Effects",elements:"Elements",shapes:"Shapes",tables:"Tables",lines:"Lines",draw:"Draw",upload:"Upload",uploadImage:"Add file",uploadTip:"Upload your assets",background:"Background",resize:"Resize",layers:"Layers",animate:"Animate",layerTypes:{image:"Image",text:"Text",svg:"SVG",line:"Line",figure:"Figure",group:"Group"},layersTip:"Elements on your active page:",noLayers:"No elements on the page...",namePlaceholder:"Type element name...",useMagicResize:"Use magic resize",advanced:"Advanced",bleed:"Bleed",showBleed:"Show bleed",clipImage:"Mask image",width:"Width",height:"Height",units:"Units",magicResizeDescription:"Magic resize will automatically resize and move all elements on the canvas",headerText:"Header",createHeader:"Create header",subHeaderText:"Sub Header",createSubHeader:"Create sub header",bodyText:"Body text",createBody:"Create body text"},pagesTimeline:{pages:"Pages",removePage:"Remove page",addPage:"Add page",duplicatePage:"Duplicate page",removeAudio:"Remove audio",duplicateAudio:"Duplicate audio",muteAudio:"Mute",unmuteAudio:"Unmute",volume:"Volume",speed:"Speed",rewind:"Rewind to start",editAsVideo:"Edit as video",editAsVideoHint:"On: preview the frame at the playhead — timed elements hide outside their range. Off: show all elements while editing."},contextMenu:{duplicate:"Duplicate",split:"Split at playhead",remove:"Remove",lock:"Lock",unlock:"Unlock",copy:"Copy",paste:"Paste",copyStyle:"Copy style",moveUp:"Move up",moveDown:"Move down",moveBack:"Move back",moveForward:"Move forward"}}),n=e=>e&&"object"==typeof e;function i(e,o){Object.keys(o).forEach(r=>{const a=e[r],l=o[r];n(l)&&n(a)?i(a,l):e[r]=l})}function l(e,o,r=""){Object.keys(o).forEach(a=>{const i=o[a],s=r?`${r}.${a}`:a;n(i)?n(e[a])?l(e[a],i,s):console.warn(`Missing nested translation object at '${s}'`):void 0===e[a]&&console.warn(`Missing translation '${s}'`)})}export const setTranslations=o((e,{validate:o=!1}={})=>{o&&l(e,a),i(a,e)});export const getTranslations=()=>r(a);const s={};export const t=e=>{const o=function(e,o){var r,a=o.split("."),n=e;for(r=0;r<a.length;++r){if(null==n[a[r]]){return}n=n[a[r]]}return n}(a,e);if(void 0!==o){return o}s[e]||(s[e]=!0,console.warn(`Missing translation '${e}'`));const r=e.split("."),n=r[r.length-1]||" ";return n.charAt(0).toUpperCase()+n.slice(1)};
package/utils/loader.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { PolotnoError } from './errors.js';
1
2
  export declare const setAssetLoadTimeout: (timeout: number) => void;
2
3
  export declare const getAssetLoadTimeout: () => number;
3
4
  export declare const setFontLoadTimeout: (timeout: number) => void;
@@ -5,5 +6,5 @@ export declare const getFontLoadTimeout: () => number;
5
6
  export declare function incrementLoader(id: any): () => void;
6
7
  export declare function decrementLoader(): void;
7
8
  export declare function whenLoaded(): Promise<unknown>;
8
- export declare function onLoadError(func: Function): void;
9
- export declare function triggerLoadError(error: string): void;
9
+ export declare function onLoadError(func: (error: PolotnoError) => void): void;
10
+ export declare function triggerLoadError(error: string | PolotnoError): void;
package/utils/loader.js CHANGED
@@ -1 +1 @@
1
- import{isAnimationUsed as e}from"../canvas/use-fadein.js";let o=0,t=[],r=3e4;export const setAssetLoadTimeout=e=>{r=e};export const getAssetLoadTimeout=()=>r;let n=6e3;export const setFontLoadTimeout=e=>{n=e};export const getFontLoadTimeout=()=>n;export function incrementLoader(e){o+=1;let t=!1,n=!1;const a=setTimeout(()=>{t||(triggerLoadError(`Timeout loading asset ${e}`),console.error("Timeout triggered for loader. Some assets may not have loaded.",e),t=!0,decrementLoader())},r);return()=>{n?console.error("Finish called twice! That is not expected. id: ",e):(n=!0,t||(clearTimeout(a),decrementLoader()))}}export function decrementLoader(){o-=1,0===o&&(t.forEach(e=>e()),t=[])}export function whenLoaded(){return new Promise(r=>{return n=()=>{e()?setTimeout(r,300):r(!0)},void(0===o?n():t.push(n));var n})}let a=[];export function onLoadError(e){a.push(e)}export function triggerLoadError(e){a.forEach(o=>o(e))}
1
+ import{isAnimationUsed as e}from"../canvas/use-fadein.js";import{polotnoError as t}from"./errors.js";let o=0,r=[],n=3e4;export const setAssetLoadTimeout=e=>{n=e};export const getAssetLoadTimeout=()=>n;let s=6e3;export const setFontLoadTimeout=e=>{s=e};export const getFontLoadTimeout=()=>s;export function incrementLoader(e){o+=1;let r=!1,s=!1;const i=setTimeout(()=>{if(r){return}const o=String(e),s=o.startsWith("image")?"IMAGE_FAILED":o.startsWith("video")||o.startsWith("mediabunny")?"VIDEO_FAILED":"UNKNOWN";triggerLoadError(t(s,`Timeout loading asset ${e}`,{reason:"timeout",label:o,timeoutMs:n})),console.error("Timeout triggered for loader. Some assets may not have loaded.",e),r=!0,decrementLoader()},n);return()=>{s?console.error("Finish called twice! That is not expected. id: ",e):(s=!0,r||(clearTimeout(i),decrementLoader()))}}export function decrementLoader(){o-=1,0===o&&(r.forEach(e=>e()),r=[])}export function whenLoaded(){return new Promise(t=>{return n=()=>{e()?setTimeout(t,300):t(!0)},void(0===o?n():r.push(n));var n})}let i=[];export function onLoadError(e){i.push(e)}export function triggerLoadError(e){const o="string"==typeof e?t("UNKNOWN",e):e;i.forEach(e=>e(o))}
@@ -0,0 +1,4 @@
1
+ import { IAutorunOptions, IReactionOptions, IReactionDisposer } from 'mobx';
2
+ import { IAnyStateTreeNode } from 'mobx-state-tree';
3
+ export declare function nodeAutorun(node: IAnyStateTreeNode, view: () => void, opts?: IAutorunOptions): IReactionDisposer;
4
+ export declare function nodeReaction<T>(node: IAnyStateTreeNode, expression: () => T, effect: (value: T | undefined, prev: T | undefined) => void, opts?: IReactionOptions<T | undefined, boolean>): IReactionDisposer;
package/utils/mobx.js ADDED
@@ -0,0 +1 @@
1
+ import{autorun as o,reaction as t}from"mobx";import{isAlive as r}from"mobx-state-tree";export function nodeAutorun(t,e,n){return o(()=>{r(t)&&e()},n)}export function nodeReaction(o,e,n,i){return t(()=>r(o)?e():void 0,(t,e)=>{r(o)&&n(t,e)},i)}
@@ -1,6 +1,7 @@
1
1
  import { StyledSegment } from './text.js';
2
2
  import { TextElementLike } from './text-types.js';
3
3
  export declare function getDir(string: string): "rtl" | "ltr";
4
+ export declare function normalizeStrokeLineJoin(join?: string): 'round' | 'miter' | 'bevel';
4
5
  export declare function getCurvePath(width: number, height: number, power: number, absLineHeight: number): string;
5
6
  export declare function createSVGGradientDef(gradientColor: string, id: string, width?: number, height?: number): string;
6
7
  export declare function getCurveTextDimensions(element: TextElementLike, precomputed?: {
@@ -1 +1 @@
1
- import t from"konva";import*as e from"./gradient.js";import{removeTags as n,sanitizeHtml as o,parseHtmlToSegments as i}from"./text.js";import{flags as r}from"./flags.js";import{xmlEscape as l}from"./xml.js";import{applyTextDefaults as a}from"./text-types.js";import{normalizeRichTextHtml as s}from"./rich-text-html.js";function f(t){var e="֑-߿‏‫‮יִ-﷽ﹰ-ﻼ";return new RegExp("^[^"+e+"]*?["+e+"]").test(t)}export function getDir(t){return function(t){t=t.replace(/\s/g,"");let e=0;for(var n=0;n<t.length;n++){f(t[n])&&(e+=1)}return e>t.length/2}(t)?"rtl":"ltr"}export function getCurvePath(t,e,n,o){const i=Math.max(-.9999,Math.min(.9999,n));if(Math.abs(i)<1e-4){return`M 0 ${e/2} L ${t} ${e/2}`}const r=5*o/(2*Math.abs(i))-o,l=t/2;if(i>0){const t=2*r+o/2;return[`M ${l} ${t}`,`A ${r} ${r} 0 1 1 ${l} ${t-2*r}`,`A ${r} ${r} 0 1 1 ${l} ${t}`].join(" ")}{const t=-(2*r-Math.round(e))-o/2;return[`M ${l} ${t}`,`A ${r} ${r} 0 1 0 ${l} ${t+2*r}`,`A ${r} ${r} 0 1 0 ${l} ${t}`].join(" ")}}export function createSVGGradientDef(t,n,o,i){if(!e.isGradient(t)){return""}const{stops:r,rotation:l}=e.parseColor(t),a=l*Math.PI/180;return`<linearGradient id="${n}" x1="${100*(.5-.5*Math.sin(a))}%" y1="${100*(.5+.5*Math.cos(a))}%" x2="${100*(.5+.5*Math.sin(a))}%" y2="${100*(.5-.5*Math.cos(a))}%">${r.map(({offset:t,color:e})=>`<stop offset="${100*t}%" stop-color="${e}" />`).join("")}</linearGradient>`}let c=null;function h(){return c||(c=document.createElement("canvas").getContext("2d")),c}export function getCurveTextDimensions(e,o){var r,l,f,c,$,d;const u=e.a?e.a:e,g=a(e),p=null!==(r=u.fontSize)&&void 0!==r?r:g.fontSize,m=null!==(l=null==o?void 0:o.normalizedText)&&void 0!==l?l:s(g.text,{fontSize:p,fontFamily:g.fontFamily}),x=null!==(f=null==o?void 0:o.segments)&&void 0!==f?f:i(m,{fontSize:p,fontFamily:g.fontFamily}),y=Math.max(p,...x.map(t=>{var e;return null!==(e=t.fontSize)&&void 0!==e?e:p})),v=n(m),k=function(t,e,n,o,i,r){if(!t.some(t=>t.fontFamily&&t.fontFamily!==n)||e.length<=1){return 0}const l=function(t,e,n,o,i){var r;const l=h();let a=0;for(const s of t){const t=s.fontFamily||e,f=s.bold?"bold":n,c=s.italic?"italic":o,h=null!==(r=s.fontSize)&&void 0!==r?r:i,$=t.replace(/'/g,"");l.font=`${c} ${f} ${h}px '${$}'`,a+=l.measureText(s.text).width}return a}(t,n,o,i,r),a=h();a.font=`${i} ${o} ${r}px '${n}'`;const s=l-a.measureText(e).width;return s<=0?0:s/(e.length-1)}(x,v,g.fontFamily,g.fontWeight||"normal",g.fontStyle||"normal",y),S=null!==(c=u.width)&&void 0!==c?c:g.width,w=new t.TextPath({data:getCurvePath(S,null!==(d=null!==($=u.height)&&void 0!==$?$:g.height)&&void 0!==d?d:0,g.curvePower,y),align:"center",textBaseline:"middle",text:v,fontSize:y,fontFamily:g.fontFamily,fontWeight:g.fontWeight,fontStyle:g.fontStyle,letterSpacing:g.letterSpacing*y+k,fill:g.fill}),b=w.getSelfRect();return w.destroy(),{width:b.width||S,height:b.height||y}}export function getCurveTextHeight(t){return getCurveTextDimensions(t).height}export function segmentsToTspans(t,e,n){return t.map(t=>{var o;const i=[];t.bold&&"bold"!==e.fontWeight&&i.push('font-weight="bold"'),t.italic&&"italic"!==e.fontStyle&&i.push('font-style="italic"');const r=[];t.underline&&r.push("underline"),t.strike&&r.push("line-through"),r.length&&i.push(`text-decoration="${r.join(" ")}"`),!(null==n?void 0:n.omitColors)&&t.color&&t.color!==e.fill&&i.push(`fill="${l(t.color)}"`);const a=t.fontFamily||e.fontFamily;a!==e.fontFamily&&i.push(`font-family="${l(a)}"`);const s=null!==(o=t.fontSize)&&void 0!==o?o:e.fontSize;s!==e.fontSize&&i.push(`font-size="${s}"`);const f=l(t.text);return 0===i.length?f:`<tspan ${i.join(" ")}>${f}</tspan>`}).join("")}export function getQuillEditorHtml(t,e){const n=a(t),i=e||n.fontFamily,r=s(n.text,{fontSize:n.fontSize,fontFamily:i});return o(r).replace(/\n/g,"<br/>")}export function getHtml(t,{fontFamily:f="",color:c="black",forEditor:h=!1}={}){const $=a(t),d=f||$.fontFamily,u=s($.text,{fontSize:$.fontSize,fontFamily:d}),g=e.isGradient($.fill),p=e.isGradient($.stroke)&&!!$.strokeWidth,m="ellipsis"===r.textOverflow&&!h&&!$.curveEnabled&&!!$.height,x=(()=>{if(!m){return[]}const t=Math.max(1,Math.round($.height)),e="number"==typeof $.lineHeight?$.lineHeight:1.2,n=Math.max(1,e*$.fontSize),o=Math.max(1,Math.floor(t/n));return[`max-height: ${t}px`,"overflow: hidden","display: -webkit-box","-webkit-box-orient: vertical",`-webkit-line-clamp: ${o}`,`line-clamp: ${o}`]})(),y=t=>`\n background-image: ${t};\n background-size: 100% 100%;\n background-repeat: repeat;\n -webkit-background-clip: text;\n -moz-background-clip: text;\n background-clip: text;\n -webkit-text-fill-color: transparent;\n color: transparent\n `.trim();let v=`color: ${c||$.fill}`,k="";p&&$.strokeWidth?(v=`color: ${c||$.fill}; ${y($.stroke)}`,k=`-webkit-text-stroke: ${$.strokeWidth}px transparent`):g&&(v=y($.fill));const S=["white-space: pre-wrap","overflow-wrap: break-word",`width: ${Math.round($.width||100)}px`,...x,v,`font-size: ${$.fontSize}px`,`font-family: '${d}'`,`text-align: ${$.align}`,`text-transform: ${$.textTransform}`,$.textDecoration?`text-decoration: ${$.textDecoration}; text-decoration-color: ${c||$.fill}; text-decoration-layer: over`:"",$.lineHeight?`line-height: ${$.lineHeight}`:"",$.letterSpacing?`letter-spacing: ${$.letterSpacing}em`:"",$.fontStyle?`font-style: ${$.fontStyle}`:"",$.fontWeight?`font-weight: ${$.fontWeight}`:"",k||($.strokeWidth?`-webkit-text-stroke: ${$.strokeWidth}px ${$.stroke}`:""),$.strokeWidth&&!p?"paint-order: stroke fill":""].filter(Boolean).join("; ");if($.curveEnabled&&!h){const e=i(u,{fontSize:$.fontSize,fontFamily:d}),n=getCurveTextDimensions(t,{normalizedText:u,segments:e}),o=Math.round(n.width),r=n.height,a=Math.max($.fontSize,...e.map(t=>{var e;return null!==(e=t.fontSize)&&void 0!==e?e:$.fontSize})),s=getCurvePath(o,r,$.curvePower,a),f={fontWeight:$.fontWeight||"normal",fontStyle:$.fontStyle||"normal",fill:c||$.fill||"black",fontFamily:d,fontSize:$.fontSize},h=segmentsToTspans(e,f),m=segmentsToTspans(e,f,{omitColors:!0}),x=l($.id||"temp"),y=`curve-${x}`,v=$.strokeWidth&&(p||g&&!p);let k=`<svg xmlns="http://www.w3.org/2000/svg" width="${o}" height="${r}" overflow="visible">\n <defs>\n <path id="${y}" d="${s}" fill="none" />`;if(g){const t=`curve-fill-grad-${x}`;k+=createSVGGradientDef($.fill,t,o,r)}if(p&&$.strokeWidth){const t=`curve-stroke-grad-${x}`;k+=createSVGGradientDef($.stroke,t,o,r)}k+="</defs>";const S=l(d),w=l($.fontWeight||"normal"),b=l($.fontStyle||"normal");if(v){const t=`\n font-family="'${S}'"\n font-size="${$.fontSize}"\n font-weight="${w}"\n font-style="${b}"\n text-anchor="middle"\n dominant-baseline="central"\n letter-spacing="${$.letterSpacing*a}"${$.textDecoration?` text-decoration="${$.textDecoration}"`:""}`,e=p?`url(#curve-stroke-grad-${x})`:$.stroke;k+=`\n <text ${t} fill="${e}" stroke="${e}" stroke-width="${$.strokeWidth}">\n <textPath href="#${y}" startOffset="50%">${m}</textPath>\n </text>`,k+=`\n <text ${t} fill="${g?`url(#curve-fill-grad-${x})`:c}">\n <textPath href="#${y}" startOffset="50%">${h}</textPath>\n </text>`}else{const t=g?`url(#curve-fill-grad-${x})`:c,e=p?`url(#curve-stroke-grad-${x})`:$.stroke;k+=`\n <text\n font-family="'${S}'"\n font-size="${$.fontSize}"\n font-weight="${w}"\n font-style="${b}"\n fill="${t}"\n text-anchor="middle"\n dominant-baseline="central"\n letter-spacing="${$.letterSpacing*a}"${$.textDecoration?` text-decoration="${$.textDecoration}"`:""}${$.strokeWidth?` stroke="${e}" stroke-width="${$.strokeWidth}" paint-order="stroke fill"`:""}>\n <textPath href="#${y}" startOffset="50%">${h}</textPath>\n </text>`}return k+="</svg>",k}if($.strokeWidth&&(p||g&&!p)&&!h){const t=o(u).replace(/\n/g,"<br/>"),e=Math.round($.width||100),i=["white-space: pre-wrap","overflow-wrap: break-word",`width: ${e}px`,...x,`font-size: ${$.fontSize}px`,`font-family: '${d}'`,`text-align: ${$.align}`,`text-transform: ${$.textTransform}`,$.textDecoration?`text-decoration: ${$.textDecoration}; text-decoration-color: ${c||$.fill}; text-decoration-layer: over`:"",$.lineHeight?`line-height: ${$.lineHeight}`:"",$.letterSpacing?`letter-spacing: ${$.letterSpacing}em`:"",$.fontStyle?`font-style: ${$.fontStyle}`:"",$.fontWeight?`font-weight: ${$.fontWeight}`:""].filter(Boolean).join("; ");let r;r=p?`${i}; ${y($.stroke)}; -webkit-text-stroke: ${$.strokeWidth}px transparent`:`${i}; color: transparent; -webkit-text-stroke: ${$.strokeWidth}px ${$.stroke}`;const l=`${i}; ${g?y($.fill):`color: ${c||$.fill}`}`;let a="";if(g||p){const t=[];p&&$.strokeWidth&&t.push(`.stroke-layer li, .stroke-layer li::before { ${y($.stroke)}; }`),g&&t.push(`.fill-layer li, .fill-layer li::before { ${y($.fill)}; }`),t.length&&(a=`<style>${t.join("\n")}</style>`)}return`\n <div style="position: relative; width: ${e}px;">\n <div class="stroke-layer" style="${r}; position: absolute; top: 0; left: 0; pointer-events: none;" aria-hidden="true">${t}</div>\n <div class="fill-layer" style="${l}; position: relative;" contentEditable dir="${getDir(n(u))}">${t}</div>\n </div>\n ${a}\n `}let w="";return g&&!p&&(w=`<style>\n li, li::before {\n ${y($.fill)};\n }\n </style>`),`<div style="${S}" contentEditable dir="${getDir(n(u))}">${o(u).replace(/\n/g,"<br/>")}</div>${w}`}export function resolveLineHeight({fontFamily:t,fontSize:e,lineHeight:n}){if("number"==typeof n){return n}const o=document.createElement("div");o.style.fontFamily=t,o.style.fontSize=e+"px",o.style.lineHeight=n,o.innerText="Test text",document.body.appendChild(o);try{return o.offsetHeight/e}finally{document.body.removeChild(o)}}
1
+ import t from"konva";import*as e from"./gradient.js";import{removeTags as n,sanitizeHtml as o,parseHtmlToSegments as i}from"./text.js";import{flags as r}from"./flags.js";import{xmlEscape as l}from"./xml.js";import{applyTextDefaults as a}from"./text-types.js";import{normalizeRichTextHtml as s}from"./rich-text-html.js";function f(t){var e="֑-߿‏‫‮יִ-﷽ﹰ-ﻼ";return new RegExp("^[^"+e+"]*?["+e+"]").test(t)}export function getDir(t){return function(t){t=t.replace(/\s/g,"");let e=0;for(var n=0;n<t.length;n++){f(t[n])&&(e+=1)}return e>t.length/2}(t)?"rtl":"ltr"}export function normalizeStrokeLineJoin(t){return"miter"===t||"bevel"===t?t:"round"}export function getCurvePath(t,e,n,o){const i=Math.max(-.9999,Math.min(.9999,n));if(Math.abs(i)<1e-4){return`M 0 ${e/2} L ${t} ${e/2}`}const r=5*o/(2*Math.abs(i))-o,l=t/2;if(i>0){const t=2*r+o/2;return[`M ${l} ${t}`,`A ${r} ${r} 0 1 1 ${l} ${t-2*r}`,`A ${r} ${r} 0 1 1 ${l} ${t}`].join(" ")}{const t=-(2*r-Math.round(e))-o/2;return[`M ${l} ${t}`,`A ${r} ${r} 0 1 0 ${l} ${t+2*r}`,`A ${r} ${r} 0 1 0 ${l} ${t}`].join(" ")}}export function createSVGGradientDef(t,n,o,i){if(!e.isGradient(t)){return""}const{stops:r,rotation:l}=e.parseColor(t),a=l*Math.PI/180;return`<linearGradient id="${n}" x1="${100*(.5-.5*Math.sin(a))}%" y1="${100*(.5+.5*Math.cos(a))}%" x2="${100*(.5+.5*Math.sin(a))}%" y2="${100*(.5-.5*Math.cos(a))}%">${r.map(({offset:t,color:e})=>`<stop offset="${100*t}%" stop-color="${e}" />`).join("")}</linearGradient>`}let c=null;function h(){return c||(c=document.createElement("canvas").getContext("2d")),c}export function getCurveTextDimensions(e,o){var r,l,f,c,$,d;const u=e.a?e.a:e,m=a(e),g=null!==(r=u.fontSize)&&void 0!==r?r:m.fontSize,p=null!==(l=null==o?void 0:o.normalizedText)&&void 0!==l?l:s(m.text,{fontSize:g,fontFamily:m.fontFamily}),x=null!==(f=null==o?void 0:o.segments)&&void 0!==f?f:i(p,{fontSize:g,fontFamily:m.fontFamily}),y=Math.max(g,...x.map(t=>{var e;return null!==(e=t.fontSize)&&void 0!==e?e:g})),k=n(p),v=function(t,e,n,o,i,r){if(!t.some(t=>t.fontFamily&&t.fontFamily!==n)||e.length<=1){return 0}const l=function(t,e,n,o,i){var r;const l=h();let a=0;for(const s of t){const t=s.fontFamily||e,f=s.bold?"bold":n,c=s.italic?"italic":o,h=null!==(r=s.fontSize)&&void 0!==r?r:i,$=t.replace(/'/g,"");l.font=`${c} ${f} ${h}px '${$}'`,a+=l.measureText(s.text).width}return a}(t,n,o,i,r),a=h();a.font=`${i} ${o} ${r}px '${n}'`;const s=l-a.measureText(e).width;return s<=0?0:s/(e.length-1)}(x,k,m.fontFamily,m.fontWeight||"normal",m.fontStyle||"normal",y),S=null!==(c=u.width)&&void 0!==c?c:m.width,w=new t.TextPath({data:getCurvePath(S,null!==(d=null!==($=u.height)&&void 0!==$?$:m.height)&&void 0!==d?d:0,m.curvePower,y),align:"center",textBaseline:"middle",text:k,fontSize:y,fontFamily:m.fontFamily,fontWeight:m.fontWeight,fontStyle:m.fontStyle,letterSpacing:m.letterSpacing*y+v,fill:m.fill}),b=w.getSelfRect();return w.destroy(),{width:b.width||S,height:b.height||y}}export function getCurveTextHeight(t){return getCurveTextDimensions(t).height}export function segmentsToTspans(t,e,n){return t.map(t=>{var o;const i=[];t.bold&&"bold"!==e.fontWeight&&i.push('font-weight="bold"'),t.italic&&"italic"!==e.fontStyle&&i.push('font-style="italic"');const r=[];t.underline&&r.push("underline"),t.strike&&r.push("line-through"),r.length&&i.push(`text-decoration="${r.join(" ")}"`),!(null==n?void 0:n.omitColors)&&t.color&&t.color!==e.fill&&i.push(`fill="${l(t.color)}"`);const a=t.fontFamily||e.fontFamily;a!==e.fontFamily&&i.push(`font-family="${l(a)}"`);const s=null!==(o=t.fontSize)&&void 0!==o?o:e.fontSize;s!==e.fontSize&&i.push(`font-size="${s}"`);const f=l(t.text);return 0===i.length?f:`<tspan ${i.join(" ")}>${f}</tspan>`}).join("")}export function getQuillEditorHtml(t,e){const n=a(t),i=e||n.fontFamily,r=s(n.text,{fontSize:n.fontSize,fontFamily:i});return o(r).replace(/\n/g,"<br/>")}export function getHtml(t,{fontFamily:f="",color:c="black",forEditor:h=!1}={}){const $=a(t),d=f||$.fontFamily,u=s($.text,{fontSize:$.fontSize,fontFamily:d}),m=e.isGradient($.fill),g=e.isGradient($.stroke)&&!!$.strokeWidth,p="ellipsis"===r.textOverflow&&!h&&!$.curveEnabled&&!!$.height,x=(()=>{if(!p){return[]}const t=Math.max(1,Math.round($.height)),e="number"==typeof $.lineHeight?$.lineHeight:1.2,n=Math.max(1,e*$.fontSize),o=Math.max(1,Math.floor(t/n));return[`max-height: ${t}px`,"overflow: hidden","display: -webkit-box","-webkit-box-orient: vertical",`-webkit-line-clamp: ${o}`,`line-clamp: ${o}`]})(),y=t=>`\n background-image: ${t};\n background-size: 100% 100%;\n background-repeat: repeat;\n -webkit-background-clip: text;\n -moz-background-clip: text;\n background-clip: text;\n -webkit-text-fill-color: transparent;\n color: transparent\n `.trim();let k=`color: ${c||$.fill}`,v="";g&&$.strokeWidth?(k=`color: ${c||$.fill}; ${y($.stroke)}`,v=`-webkit-text-stroke: ${$.strokeWidth}px transparent`):m&&(k=y($.fill));const S=["white-space: pre-wrap","overflow-wrap: break-word",`width: ${Math.round($.width||100)}px`,...x,k,`font-size: ${$.fontSize}px`,`font-family: '${d}'`,`text-align: ${$.align}`,`text-transform: ${$.textTransform}`,$.textDecoration?`text-decoration: ${$.textDecoration}; text-decoration-color: ${c||$.fill}; text-decoration-layer: over`:"",$.lineHeight?`line-height: ${$.lineHeight}`:"",$.letterSpacing?`letter-spacing: ${$.letterSpacing}em`:"",$.fontStyle?`font-style: ${$.fontStyle}`:"",$.fontWeight?`font-weight: ${$.fontWeight}`:"",v||($.strokeWidth?`-webkit-text-stroke: ${$.strokeWidth}px ${$.stroke}`:""),$.strokeWidth&&!g?"paint-order: stroke fill":"",$.strokeWidth?`stroke-linejoin: ${normalizeStrokeLineJoin($.strokeLineJoin)}`:""].filter(Boolean).join("; ");if($.curveEnabled&&!h){const e=i(u,{fontSize:$.fontSize,fontFamily:d}),n=getCurveTextDimensions(t,{normalizedText:u,segments:e}),o=Math.round(n.width),r=n.height,a=Math.max($.fontSize,...e.map(t=>{var e;return null!==(e=t.fontSize)&&void 0!==e?e:$.fontSize})),s=getCurvePath(o,r,$.curvePower,a),f={fontWeight:$.fontWeight||"normal",fontStyle:$.fontStyle||"normal",fill:c||$.fill||"black",fontFamily:d,fontSize:$.fontSize},h=segmentsToTspans(e,f),p=segmentsToTspans(e,f,{omitColors:!0}),x=l($.id||"temp"),y=`curve-${x}`,k=$.strokeWidth&&(g||m&&!g);let v=`<svg xmlns="http://www.w3.org/2000/svg" width="${o}" height="${r}" overflow="visible">\n <defs>\n <path id="${y}" d="${s}" fill="none" />`;if(m){const t=`curve-fill-grad-${x}`;v+=createSVGGradientDef($.fill,t,o,r)}if(g&&$.strokeWidth){const t=`curve-stroke-grad-${x}`;v+=createSVGGradientDef($.stroke,t,o,r)}v+="</defs>";const S=l(d),w=l($.fontWeight||"normal"),b=l($.fontStyle||"normal");if(k){const t=`\n font-family="'${S}'"\n font-size="${$.fontSize}"\n font-weight="${w}"\n font-style="${b}"\n text-anchor="middle"\n dominant-baseline="central"\n letter-spacing="${$.letterSpacing*a}"${$.textDecoration?` text-decoration="${$.textDecoration}"`:""}`,e=g?`url(#curve-stroke-grad-${x})`:$.stroke;v+=`\n <text ${t} fill="${e}" stroke="${e}" stroke-width="${$.strokeWidth}" stroke-linejoin="${normalizeStrokeLineJoin($.strokeLineJoin)}">\n <textPath href="#${y}" startOffset="50%">${p}</textPath>\n </text>`,v+=`\n <text ${t} fill="${m?`url(#curve-fill-grad-${x})`:c}">\n <textPath href="#${y}" startOffset="50%">${h}</textPath>\n </text>`}else{const t=m?`url(#curve-fill-grad-${x})`:c,e=g?`url(#curve-stroke-grad-${x})`:$.stroke;v+=`\n <text\n font-family="'${S}'"\n font-size="${$.fontSize}"\n font-weight="${w}"\n font-style="${b}"\n fill="${t}"\n text-anchor="middle"\n dominant-baseline="central"\n letter-spacing="${$.letterSpacing*a}"${$.textDecoration?` text-decoration="${$.textDecoration}"`:""}${$.strokeWidth?` stroke="${e}" stroke-width="${$.strokeWidth}" stroke-linejoin="${normalizeStrokeLineJoin($.strokeLineJoin)}" paint-order="stroke fill"`:""}>\n <textPath href="#${y}" startOffset="50%">${h}</textPath>\n </text>`}return v+="</svg>",v}if($.strokeWidth&&(g||m&&!g)&&!h){const t=o(u).replace(/\n/g,"<br/>"),e=Math.round($.width||100),i=["white-space: pre-wrap","overflow-wrap: break-word",`width: ${e}px`,...x,`font-size: ${$.fontSize}px`,`font-family: '${d}'`,`text-align: ${$.align}`,`text-transform: ${$.textTransform}`,$.textDecoration?`text-decoration: ${$.textDecoration}; text-decoration-color: ${c||$.fill}; text-decoration-layer: over`:"",$.lineHeight?`line-height: ${$.lineHeight}`:"",$.letterSpacing?`letter-spacing: ${$.letterSpacing}em`:"",$.fontStyle?`font-style: ${$.fontStyle}`:"",$.fontWeight?`font-weight: ${$.fontWeight}`:""].filter(Boolean).join("; ");let r;r=g?`${i}; ${y($.stroke)}; -webkit-text-stroke: ${$.strokeWidth}px transparent`:`${i}; color: transparent; -webkit-text-stroke: ${$.strokeWidth}px ${$.stroke}`;const l=`${i}; ${m?y($.fill):`color: ${c||$.fill}`}`;let a="";if(m||g){const t=[];g&&$.strokeWidth&&t.push(`.stroke-layer li, .stroke-layer li::before { ${y($.stroke)}; }`),m&&t.push(`.fill-layer li, .fill-layer li::before { ${y($.fill)}; }`),t.length&&(a=`<style>${t.join("\n")}</style>`)}return`\n <div style="position: relative; width: ${e}px;">\n <div class="stroke-layer" style="${r}; position: absolute; top: 0; left: 0; pointer-events: none;" aria-hidden="true">${t}</div>\n <div class="fill-layer" style="${l}; position: relative;" contentEditable dir="${getDir(n(u))}">${t}</div>\n </div>\n ${a}\n `}let w="";return m&&!g&&(w=`<style>\n li, li::before {\n ${y($.fill)};\n }\n </style>`),`<div style="${S}" contentEditable dir="${getDir(n(u))}">${o(u).replace(/\n/g,"<br/>")}</div>${w}`}export function resolveLineHeight({fontFamily:t,fontSize:e,lineHeight:n}){if("number"==typeof n){return n}const o=document.createElement("div");o.style.fontFamily=t,o.style.fontSize=e+"px",o.style.lineHeight=n,o.innerText="Test text",document.body.appendChild(o);try{return o.offsetHeight/e}finally{document.body.removeChild(o)}}
@@ -15,6 +15,7 @@ export interface TextElementLike {
15
15
  fill?: string;
16
16
  stroke?: string;
17
17
  strokeWidth?: number;
18
+ strokeLineJoin?: string;
18
19
  curveEnabled?: boolean;
19
20
  curvePower?: number;
20
21
  a?: {
@@ -40,6 +41,7 @@ export declare const TEXT_DEFAULTS: {
40
41
  readonly fill: "black";
41
42
  readonly stroke: "black";
42
43
  readonly strokeWidth: 0;
44
+ readonly strokeLineJoin: "round";
43
45
  readonly curveEnabled: false;
44
46
  readonly curvePower: 0.5;
45
47
  };
@@ -1 +1 @@
1
- export const TEXT_DEFAULTS={fontSize:14,fontFamily:"Roboto",fontWeight:"normal",fontStyle:"normal",lineHeight:1.2,letterSpacing:0,textTransform:"none",textDecoration:"",align:"center",fill:"black",stroke:"black",strokeWidth:0,curveEnabled:!1,curvePower:.5};export function applyTextDefaults(t){return Object.assign(Object.assign({},TEXT_DEFAULTS),t)}
1
+ export const TEXT_DEFAULTS={fontSize:14,fontFamily:"Roboto",fontWeight:"normal",fontStyle:"normal",lineHeight:1.2,letterSpacing:0,textTransform:"none",textDecoration:"",align:"center",fill:"black",stroke:"black",strokeWidth:0,strokeLineJoin:"round",curveEnabled:!1,curvePower:.5};export function applyTextDefaults(t){return Object.assign(Object.assign({},TEXT_DEFAULTS),t)}
package/utils/to-html.js CHANGED
@@ -1 +1 @@
1
- var t=this&&this.__rest||function(t,e){var o={};for(var i in t){Object.prototype.hasOwnProperty.call(t,i)&&e.indexOf(i)<0&&(o[i]=t[i])}if(null!=t&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(i=Object.getOwnPropertySymbols(t);n<i.length;n++){e.indexOf(i[n])<0&&Object.prototype.propertyIsEnumerable.call(t,i[n])&&(o[i[n]]=t[i[n]])}}return o};import{getCrop as e,loadImage as o}from"./image.js";import*as i from"./svg.js";import{figureToSvg as n}from"./figure-to-svg.js";import{resetStyleContent as r}from"./reset-style.js";import{Effects as a,shapeFilterToCSS as s}from"./filters.js";import{getVideoSize as l}from"./video.js";import{getGoogleFontsUrl as d}from"./fonts.js";import{forEveryNode as c}from"../model/group-model.js";import{getCurvePath as p}from"../canvas/text-element.js";import{removeTags as g,parseHtmlToSegments as f}from"./text.js";import b from"konva";import*as m from"./gradient.js";import{createSVGGradientDef as u,segmentsToTspans as y,getHtml as k}from"./text-html.js";import{generateBackgroundShapeFromRects as x}from"./background-shape.js";import{detectLineRects as w,detectSize as $}from"./html2canvas.js";import{normalizeRichTextHtml as v,extractFontFamiliesFromHtml as j}from"./rich-text-html.js";export const h=(t,e,...o)=>({type:t,props:e,children:o||[]});function S(t){return m.isGradient(t),t}export function fixRatio(t){var e=(new DOMParser).parseFromString(t,"image/svg+xml");return e.documentElement.setAttribute("preserveAspectRatio","none"),(new XMLSerializer).serializeToString(e)}const O=async({element:t,page:e,store:n})=>{let{src:r}=t;if("svg"===t.type){let e=await i.urlToString(r);e=fixRatio(e),r=Object.keys(t.colorsReplace).length?i.replaceColors(e,new Map(Object.entries(t.colorsReplace))):i.svgToURL(e)}let a="";t.flipX&&(a+="scaleX(-1)"),t.flipY&&(a+="scaleY(-1)"),a||(a="none");const s={};if("svg"===t.type&&t.maskSrc){const e=await i.urlToBase64(r);s["mask-image"]=`url(${e})`,s["mask-size"]="100% 100%",s["mask-position"]="0 0",s["mask-repeat"]="no-repeat",s["-webkit-mask-image"]=`url(${e})`,s["-webkit-mask-size"]="100% 100%",s["-webkit-mask-position"]="0 0",s["-webkit-mask-repeat"]="no-repeat",r=t.maskSrc}else if(t.clipSrc){const e=t.clipSrc,o=await i.urlToBase64(e);s["mask-image"]=`url(${o})`,s["mask-size"]="100% 100%",s["mask-position"]="0 0",s["mask-repeat"]="no-repeat",s["-webkit-mask-image"]=`url(${o})`,s["-webkit-mask-size"]="100% 100%",s["-webkit-mask-position"]="0 0",s["-webkit-mask-repeat"]="no-repeat"}const l=await o(r),d=l.width*t.cropWidth,c=l.height*t.cropHeight,p=t.width/t.height;let g,f;const b=d/c,u="svg"===t.type||t.stretchEnabled;u?(g=d,f=c):p>=b?(g=d,f=d/p):(g=c*p,f=c);const y=g/l.width,k=f/l.height,x=g/f>t.width/t.height?t.height/f:t.width/g,w=u?t.width/g:x,$=u?t.height/f:x,v=g*w/y,j=f*$/k;let O=t.cropX*w*l.width,z=t.cropY*$*l.height;t.flipX&&(O=(1-t.cropX-t.cropWidth)*w*l.width),t.flipY&&(z=(1-t.cropY-t.cropHeight)*$*l.height);const H=t.borderSize&&m.isGradient(t.borderColor),W=H?Math.max(0,t.cornerRadius-t.borderSize):t.cornerRadius,T=h("div",{style:Object.assign(Object.assign({},s),{width:"100%",height:"100%",borderRadius:W+"px",border:t.borderSize&&!H?`${t.borderSize}px solid ${t.borderColor}`:"none",backgroundRepeat:"no-repeat",backgroundImage:`url(${r})`,transform:a,backgroundSize:`${Math.round(v)}px ${Math.round(j)}px`,backgroundPositionX:-Math.round(O)+"px",backgroundPositionY:-Math.round(z)+"px"})});return H?h("div",{style:{width:"100%",height:"100%",borderRadius:t.cornerRadius+"px",background:S(t.borderColor),padding:t.borderSize+"px",boxSizing:"border-box"}},T):T},z=({element:t,type:e})=>{const o={"stroke-width":t.height,stroke:t.color,"stroke-linecap":"round","stroke-linejoin":"round",opacity:t.opacity},i=Object.assign(Object.assign({},o),{fill:t.color}),n=Object.assign(Object.assign({},o),{fill:"none"});return"arrow"===e?h("polyline",Object.assign({points:`${3*t.height},${2*-t.height} 0,0 ${3*t.height},${2*t.height}`},n)):"triangle"===e?h("polygon",Object.assign({points:`${3*t.height},${2*-t.height} 0,0 ${3*t.height},${2*t.height}`},i)):"bar"===e?h("polyline",Object.assign({points:`0,${2*-t.height} 0,${2*t.height}`},n)):"circle"===e?h("circle",Object.assign({cx:2*t.height,cy:0,r:2*t.height},i)):"square"===e?h("polygon",Object.assign({points:`0,${2*-t.height} ${4*t.height},${2*-t.height} ${4*t.height},${2*t.height} 0,${2*t.height}`},i)):null},H={image:O,svg:O,text:async({element:t,page:e,store:o})=>{const i=m.isGradient(t.fill),n=m.isGradient(t.stroke);if(t.curveEnabled){const e=v(t.text,{fontSize:t.fontSize,fontFamily:t.fontFamily}),o=f(e,{fontSize:t.fontSize,fontFamily:t.fontFamily}),r=Math.max(t.fontSize,...o.map(e=>{var o;return null!==(o=e.fontSize)&&void 0!==o?o:t.fontSize})),a=p(t.width,t.height,t.curvePower,r),s={fontWeight:t.fontWeight||"normal",fontStyle:t.fontStyle||"normal",fill:t.fill||"black",fontFamily:t.fontFamily,fontSize:t.fontSize},l=y(o,s);let d=`\n <svg xmlns="http://www.w3.org/2000/svg" width="${t.width}" height="${t.height}" style="display: block;">\n <defs>\n <path id="curve-${t.id}" d="${a}" fill="none" />`;if(i){const e=`curve-fill-grad-${t.id}`;d+=u(t.fill,e)}if(n&&t.strokeWidth){const e=`curve-stroke-grad-${t.id}`;d+=u(t.stroke,e)}d+=`</defs>\n <text\n font-family="'${t.fontFamily}'"\n font-size="${t.fontSize}"\n font-weight="${t.fontWeight}"\n font-style="${t.fontStyle}"\n fill="${i?`url(#curve-fill-grad-${t.id})`:t.fill}"\n text-anchor="middle"\n dominant-baseline="central"\n letter-spacing="${t.letterSpacing*r}"${t.textDecoration?` text-decoration="${t.textDecoration}"`:""}${t.strokeWidth?` stroke="${n?`url(#curve-stroke-grad-${t.id})`:t.stroke}" stroke-width="${t.strokeWidth}" paint-order="stroke fill"`:""}>\n <textPath href="#curve-${t.id}" startOffset="50%">${l}</textPath>\n </text>\n </svg>`;const c=t.backgroundPadding*(t.fontSize*t.lineHeight),g=t.backgroundEnabled&&h("div",{style:{position:"absolute",top:-c/2+"px",left:-c/2+"px",width:t.width+c+"px",height:t.height+c+"px",backgroundColor:t.backgroundColor,opacity:t.backgroundOpacity,borderRadius:t.backgroundCornerRadius*(t.fontSize*t.lineHeight*.5)+"px"}}),b=h("div",{style:{width:"100%",height:"100%",position:"absolute",top:0,left:0},innerHTML:d});return h("div",{style:{position:"relative",width:"100%",height:"100%"}},g,b)}const a=t=>({backgroundImage:t,backgroundSize:"100% 100%",backgroundRepeat:"repeat",WebkitBackgroundClip:"text",MozBackgroundClip:"text",backgroundClip:"text",WebkitTextFillColor:"transparent",MozTextFillColor:"transparent",color:"transparent"}),s="middle"===t.verticalAlign?{top:"50%",transform:"translateY(-50%)"}:"bottom"===t.verticalAlign?{bottom:0}:{top:0};let l=Object.assign(Object.assign({left:0},s),i?a(t.fill):{}),d=null;if(t.backgroundEnabled){if(t.legacyBackground){const e=t.backgroundPadding*(t.fontSize*t.lineHeight);d=h("div",{style:{position:"absolute",top:-e/2+"px",left:-e/2+"px",display:"block",width:t.width+e+"px",height:t.height+e+"px",backgroundColor:t.backgroundColor,opacity:t.backgroundOpacity,borderRadius:t.backgroundCornerRadius*(t.fontSize*t.lineHeight*.5)+"px"}})}else{const e=k(t);let o=[];try{o=w(e)}catch(H){o=[]}if(o.length){const i=t.backgroundPadding*(t.fontSize*t.lineHeight*.5),n=t.backgroundCornerRadius*(t.fontSize*t.lineHeight*.5),r=x({rects:o,padding:i,cornerRadius:n});if(r){let n=0;try{const{height:o}=$(e);"middle"===t.verticalAlign?n=(t.height-o)/2:"bottom"===t.verticalAlign&&(n=t.height-o)}catch(W){}const a=Math.min(...o.map(t=>t.top)),s=Math.max(...o.map(t=>t.bottom)),l=Math.min(...o.map(t=>t.left)),c=l-i,p=a-i,g=Math.max(...o.map(t=>t.right))-l+2*i,f=s-a+2*i;d=h("svg",{xmlns:"http://www.w3.org/2000/svg",width:g,height:f,viewBox:`${c} ${p} ${g} ${f}`,style:{position:"absolute",top:n+p+"px",left:c+"px",opacity:t.backgroundOpacity,pointerEvents:"none"},innerHTML:`<path d="${r}" fill="${t.backgroundColor}" />`})}}}}else{d=null}const c=/<[a-z][\s\S]*>/i.test(t.text),g=c?v(t.text,{fontSize:t.fontSize,fontFamily:t.fontFamily}):t.text.split("\n").join("<br />");if(t.strokeWidth&&(n||i&&!n)){const e={position:"absolute",width:t.width+"px",whiteSpace:"pre-wrap",overflowWrap:"break-word",fontSize:t.fontSize+"px",textAlign:t.align,fontFamily:`'${t.fontFamily}'`,textDecoration:t.textDecoration||"none",textDecorationColor:t.textDecoration?t.fill:void 0,textTransform:t.textTransform||"none",lineHeight:t.lineHeight,letterSpacing:t.letterSpacing*t.fontSize+"px",fontStyle:t.fontStyle,fontWeight:t.fontWeight},o=n?Object.assign(Object.assign(Object.assign({},e),a(t.stroke)),{WebkitTextStroke:`${t.strokeWidth}px transparent`}):Object.assign(Object.assign({},e),{color:"transparent",WebkitTextStroke:`${t.strokeWidth}px ${t.stroke}`}),l=i?Object.assign(Object.assign({},e),a(t.fill)):Object.assign(Object.assign({},e),{color:t.fill}),p="el-"+t.id,f=c?`<style>#${p} {${r}}</style>`:"",b=h("div",{style:Object.assign(Object.assign({},o),{position:"absolute",top:0,left:0,pointerEvents:"none"}),"aria-hidden":"true",innerHTML:c?`${f}${g}`:g}),m=h("div",Object.assign(Object.assign({style:Object.assign(Object.assign({},l),{position:"relative"})},c?{id:p}:{}),{innerHTML:c?`${f}${g}`:g}));return h("div",{style:{position:"relative",width:"100%",height:"100%"}},d,h("div",{style:Object.assign({position:"absolute",width:t.width+"px",left:0},s)},b,m))}const b=Object.assign(Object.assign({},l),{position:"absolute",width:t.width+"px",color:t.fill,whiteSpace:"pre-wrap",overflowWrap:"break-word",fontSize:t.fontSize+"px",textAlign:t.align,fontFamily:`'${t.fontFamily}'`,textDecoration:t.textDecoration||"none",textDecorationColor:t.textDecoration?t.fill:void 0,textTransform:t.textTransform||"none",lineHeight:t.lineHeight,letterSpacing:t.letterSpacing*t.fontSize+"px",fontStyle:t.fontStyle,fontWeight:t.fontWeight,WebkitTextStroke:t.strokeWidth?`${t.strokeWidth}px ${t.stroke}`:void 0,paintOrder:t.strokeWidth?"stroke fill":void 0}),j="el-"+t.id,S=c?{id:j}:{},O=`<style>#${j} {${r}}</style>`,z=h("div",Object.assign(Object.assign({style:b},S),{innerHTML:c?`${O}${g}`:g}));return h("div",{style:{position:"relative",width:"100%",height:"100%"}},d,z)},line:async({element:t,page:e,store:o})=>h("svg",{style:{width:"100%",height:"100%",contain:"layout style size",overflow:"visible"}},h("line",{x1:0,y1:t.height/2,x2:t.width,y2:t.height/2,stroke:t.color,"stroke-width":t.height,"stroke-dasharray":t.dash&&t.dash.length?t.dash.map(e=>e*t.height).join(" "):void 0}),h("g",{transform:`translate(0 ${t.height/2})`},z({element:t,type:t.startHead})),h("g",{transform:`translate(${t.width} ${t.height/2}) rotate(180)`},z({element:t,type:t.endHead}))),figure:async({element:t,page:e,store:o,elementHook:i})=>{let r=n(t);if(t.strokeWidth&&m.isGradient(t.stroke)){const e=`figure-stroke-grad-${t.id}`,o=u(t.stroke,e);r=r.replace(new RegExp(`stroke="${t.stroke.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}"`,"g"),`stroke="url(#${e})"`),r=r.replace("</defs>",`${o}</defs>`)}if(m.isGradient(t.fill)){const e=`figure-fill-grad-${t.id}`,o=u(t.fill,e);r=r.replace(new RegExp(`fill="${t.fill.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}"`,"g"),`fill="url(#${e})"`),r=r.replace("</defs>",`${o}</defs>`)}const a=h("div",{innerHTML:r});return i&&i({dom:a,element:t})||a},group:async({element:t,page:e,store:o,elementHook:i})=>{const n=await Promise.all(t.children.map(t=>W({element:t,page:e,store:o,elementHook:i}))),r=h("div",{style:{transformOrigin:"top left",opacity:t.opacity}},...n);return i&&i({dom:r,element:t})||r},video:async({element:t,page:e,store:o,elementHook:i})=>{const{cropX:n,cropY:r,cropWidth:a,cropHeight:s}=t,d=await l(t.src),c=d.width*a,p=d.height*s,g=t.width/t.height;let f,b;g>=c/p?(f=c,b=c/g):(f=p*g,b=p);const u=f/a,y=b/s,k=n*d.width,x=r*d.height,w=Math.max(t.width/d.width,t.height/d.height),$={position:"absolute",width:`${Math.round(u*w)}px`,height:`${Math.round(y*w)}px`,left:-Math.round(k*w)+"px",top:-Math.round(x*w)+"px",objectFit:"fill"},v=`video-${t.id}`,j=t.borderSize&&m.isGradient(t.borderColor),O=j?Math.max(0,t.cornerRadius-t.borderSize):t.cornerRadius,z=h("div",{style:{position:"relative",width:"100%",height:"100%",overflow:"hidden",borderRadius:O+"px",border:t.borderSize&&!j?`${t.borderSize}px solid ${t.borderColor}`:"none"}},h("video",{id:v,src:t.src,style:$,controls:!0,playsInline:!0,muted:!0,volume:t.volume}));if(j){const e=h("div",{style:{width:"100%",height:"100%",borderRadius:t.cornerRadius+"px",background:S(t.borderColor),padding:t.borderSize+"px",boxSizing:"border-box"}},z);return i&&i({dom:e,element:t})||e}return i&&i({dom:z,element:t})||z},gif:O,table:async({element:t})=>{const e=t.rows,o=t.cols,i=t.colWidths,n=t.rowHeights,r=["fontSize","fontFamily","fontWeight","fontStyle","textDecoration","textTransform","fill","align","verticalAlign","lineHeight","letterSpacing","strokeWidth","stroke","cellBackground","cellPadding"],a=(t.cells||[]).map(e=>{if(!e){return e}const o=Object.assign({},e);for(const i of r){void 0===o[i]&&(o[i]=t[i])}return o}),s=[];for(let d=0;d<e;d++){const e=[];for(let i=0;i<o;i++){const r=a[d*o+i];if(!r||r.mergedInto){continue}const s=r.cellPadding||4,l=r.colSpan||1,c=r.rowSpan||1,p=e=>{var o,i,n,a,s;const l=null===(o=r.borders)||void 0===o?void 0:o[e];return`${null!==(i=null==l?void 0:l.width)&&void 0!==i?i:t.borderWidth}px ${null!==(a=null!==(n=null==l?void 0:l.style)&&void 0!==n?n:t.borderStyle)&&void 0!==a?a:"solid"} ${null!==(s=null==l?void 0:l.color)&&void 0!==s?s:t.borderColor}`},f={style:{padding:s+"px",background:r.cellBackground||"transparent",fontSize:(r.fontSize||12)+"px",fontFamily:`'${r.fontFamily||"Roboto"}'`,fontWeight:r.fontWeight||"normal",fontStyle:r.fontStyle||"normal",color:r.fill||"black",textAlign:r.align||"left",verticalAlign:r.verticalAlign||"top",lineHeight:String(r.lineHeight||1.2),letterSpacing:r.letterSpacing?r.letterSpacing*(r.fontSize||12)+"px":void 0,textDecoration:r.textDecoration||"none",textTransform:r.textTransform||"none",borderTop:p("top"),borderRight:p("right"),borderBottom:p("bottom"),borderLeft:p("left"),overflow:"hidden",overflowWrap:"break-word",whiteSpace:"pre-wrap",height:n[d]*t.height+"px"}};l>1&&(f.colspan=String(l)),c>1&&(f.rowspan=String(c)),e.push(h("td",f,g(r.text||"")))}s.push(h("tr",{},...e))}const l=i.map(t=>h("col",{style:{width:100*t+"%"}}));return h("table",{style:{width:"100%",height:"100%",borderCollapse:"collapse",tableLayout:"fixed"}},h("colgroup",{},...l),h("tbody",{},...s))}};async function W({element:t,page:e,store:o,elementHook:i}){var n;let r=await H[t.type];if(r||(r=()=>h("div",{}),console.error(`HTML export does not support ${t.type} type...`)),!t.visible){return null}const l=await r({element:t,page:e,store:o}),d=[],c=[];if(t.blurEnabled&&d.push(`blur(${t.blurRadius/2}px)`),t.brightnessEnabled&&d.push(`brightness(${100*t.brightness+100}%)`),t.sepiaEnabled&&d.push("sepia()"),t.grayscaleEnabled&&d.push("grayscale()"),t.filters){for(const[g,f]of Object.entries(t.filters)){const t=s(a[g],f.intensity);t&&(d.push(t.filter),t.html&&c.push(t.html))}}if(t.shadowEnabled){const e=function(t,e){if(1===e){return t}const o=b.Util.colorToRGBA(t);return o?`rgba(${o.r}, ${o.g}, ${o.b}, ${o.a*e})`:t}(t.shadowColor,null!==(n=t.shadowOpacity)&&void 0!==n?n:1);d.push(`drop-shadow(${t.shadowOffsetX}px ${t.shadowOffsetY}px ${t.shadowBlur/2}px ${e})`)}const p=h("div",{id:t.id,style:{position:"absolute",left:t.x+"px",top:t.y+"px",width:t.width+"px",height:t.height+"px",transform:`rotate(${t.rotation}deg)`,transformOrigin:"top left",opacity:t.opacity,display:t.visible&&t.showInExport?"block":"none",filter:d.join(" ")||"none"}},l,...c);return i&&i({dom:p,element:t})||p}export async function jsonToDOM({json:t,elementHook:i}){const n=await Promise.all(t.pages.map(n=>async function({page:t,store:i,elementHook:n}){const r=[...t.children.filter(t=>!t.alwaysOnTop),...t.children.filter(t=>t.alwaysOnTop)],a=await Promise.all(r.map(e=>W({element:e,page:t,store:i,elementHook:n}))),s="auto"===t.width?i.width:t.width,l="auto"===t.height?i.height:t.height;let d={};if(t.background.indexOf("url")>=0||t.background.indexOf("http")>=0||t.background.indexOf(".jpg")>=0||t.background.indexOf(".png")>=0||t.background.indexOf(".jpeg")>=0){const{width:n,height:r}=await o(t.background),d=await O({element:Object.assign({x:0,y:0,width:s,height:l,src:t.background,cornerRadius:0},e({width:s,height:l},{width:n,height:r})),page:t,store:i});a.unshift(d)}else{d=m.isGradient(t.background)?Object.assign(Object.assign({},d),{backgroundImage:t.background}):Object.assign(Object.assign({},d),{backgroundColor:t.background})}return h("div",{className:"page",id:t.id,style:Object.assign(Object.assign({},d),{width:s+"px",height:l+"px",overflow:"hidden",position:"relative"})},...a)}({page:n,store:t,elementHook:i}))),r=[];c({children:t.pages},t=>{if(("text"===t.type||"tablecell"===t.type||"table"===t.type)&&(t.fontFamily&&-1===r.indexOf(t.fontFamily)&&r.push(t.fontFamily),t.text)){for(const e of j(t.text)){-1===r.indexOf(e)&&r.push(e)}}});const a=r.map(e=>{const o=t.fonts.find(t=>t.fontFamily===e);if(o){const t=(o.styles||(o.url?[{src:`url("${o.url}")`}]:[])).map(t=>`\n @font-face {\n font-family: '${o.fontFamily}';\n src: ${t.src};\n font-style: ${t.fontStyle||"normal"};\n font-weight: ${t.fontWeight||"normal"};\n font-display: swap;\n }`).join("\n");return h("style",{},t)}return h("link",{href:d(e),rel:"stylesheet"})});return h("div",{className:"design"},...a,...n)}const T=({dom:e})=>{if("string"==typeof e){return e}if(!e){return""}const o=e.props,{innerHTML:i}=o,n=t(o,["innerHTML"]),r=Object.keys(n).map(t=>"style"===t&&"object"==typeof n[t]?`style="${Object.keys(n[t]).filter(e=>null!=n[t][e]).map(e=>`${e.replace(/[A-Z]/g,t=>`-${t.toLowerCase()}`)}: ${n[t][e]}`).join("; ")}"`:((t,e)=>null==e||""===e?"":"object"==typeof e?`${t}="${Object.keys(e).map(t=>`${t.replace(/-([a-z])/g,t=>t[1].toUpperCase())}:${e[t]};`).join(" ")}"`:`${t}="${e}"`)(t,n[t])).filter(t=>t&&t.trim().length>0).join(" ");return`<${e.type} ${r}>${i||e.children.map(t=>T({dom:t})).join("")}</${e.type}>`};export async function jsonToHTML({json:t,elementHook:e}){const o=await jsonToDOM({json:t,elementHook:e});return T({dom:o})}
1
+ var t=this&&this.__rest||function(t,e){var o={};for(var i in t){Object.prototype.hasOwnProperty.call(t,i)&&e.indexOf(i)<0&&(o[i]=t[i])}if(null!=t&&"function"==typeof Object.getOwnPropertySymbols){var n=0;for(i=Object.getOwnPropertySymbols(t);n<i.length;n++){e.indexOf(i[n])<0&&Object.prototype.propertyIsEnumerable.call(t,i[n])&&(o[i[n]]=t[i[n]])}}return o};import{getCrop as e,loadImage as o}from"./image.js";import*as i from"./svg.js";import{figureToSvg as n}from"./figure-to-svg.js";import{resetStyleContent as r}from"./reset-style.js";import{Effects as a,shapeFilterToCSS as s}from"./filters.js";import{getElementBlurRadius as l}from"../canvas/apply-filters.js";import{getVideoSize as d}from"./video.js";import{getGoogleFontsUrl as c}from"./fonts.js";import{forEveryNode as p}from"../model/group-model.js";import{getCurvePath as g}from"../canvas/text-element.js";import{removeTags as f,parseHtmlToSegments as m}from"./text.js";import b from"konva";import*as u from"./gradient.js";import{createSVGGradientDef as y,segmentsToTspans as k,getHtml as x,normalizeStrokeLineJoin as w}from"./text-html.js";import{generateBackgroundShapeFromRects as $}from"./background-shape.js";import{detectLineRects as v,detectSize as j}from"./html2canvas.js";import{normalizeRichTextHtml as S,extractFontFamiliesFromHtml as O}from"./rich-text-html.js";export const h=(t,e,...o)=>({type:t,props:e,children:o||[]});function z(t){return u.isGradient(t),t}export function fixRatio(t){var e=(new DOMParser).parseFromString(t,"image/svg+xml");return e.documentElement.setAttribute("preserveAspectRatio","none"),(new XMLSerializer).serializeToString(e)}const H=async({element:t,page:e,store:n})=>{let{src:r}=t;if("svg"===t.type){let e=await i.urlToString(r);e=fixRatio(e),r=Object.keys(t.colorsReplace).length?i.replaceColors(e,new Map(Object.entries(t.colorsReplace))):i.svgToURL(e)}let a="";t.flipX&&(a+="scaleX(-1)"),t.flipY&&(a+="scaleY(-1)"),a||(a="none");const s={};if("svg"===t.type&&t.maskSrc){const e=await i.urlToBase64(r);s["mask-image"]=`url(${e})`,s["mask-size"]="100% 100%",s["mask-position"]="0 0",s["mask-repeat"]="no-repeat",s["-webkit-mask-image"]=`url(${e})`,s["-webkit-mask-size"]="100% 100%",s["-webkit-mask-position"]="0 0",s["-webkit-mask-repeat"]="no-repeat",r=t.maskSrc}else if(t.clipSrc){const e=t.clipSrc,o=await i.urlToBase64(e);s["mask-image"]=`url(${o})`,s["mask-size"]="100% 100%",s["mask-position"]="0 0",s["mask-repeat"]="no-repeat",s["-webkit-mask-image"]=`url(${o})`,s["-webkit-mask-size"]="100% 100%",s["-webkit-mask-position"]="0 0",s["-webkit-mask-repeat"]="no-repeat"}const l=await o(r),d=l.width*t.cropWidth,c=l.height*t.cropHeight,p=t.width/t.height;let g,f;const m=d/c,b="svg"===t.type||t.stretchEnabled;b?(g=d,f=c):p>=m?(g=d,f=d/p):(g=c*p,f=c);const y=g/l.width,k=f/l.height,x=g/f>t.width/t.height?t.height/f:t.width/g,w=b?t.width/g:x,$=b?t.height/f:x,v=g*w/y,j=f*$/k;let S=t.cropX*w*l.width,O=t.cropY*$*l.height;t.flipX&&(S=(1-t.cropX-t.cropWidth)*w*l.width),t.flipY&&(O=(1-t.cropY-t.cropHeight)*$*l.height);const H=t.borderSize&&u.isGradient(t.borderColor),W=H?Math.max(0,t.cornerRadius-t.borderSize):t.cornerRadius,T=h("div",{style:Object.assign(Object.assign({},s),{width:"100%",height:"100%",borderRadius:W+"px",border:t.borderSize&&!H?`${t.borderSize}px solid ${t.borderColor}`:"none",backgroundRepeat:"no-repeat",backgroundImage:`url(${r})`,transform:a,backgroundSize:`${Math.round(v)}px ${Math.round(j)}px`,backgroundPositionX:-Math.round(S)+"px",backgroundPositionY:-Math.round(O)+"px"})});return H?h("div",{style:{width:"100%",height:"100%",borderRadius:t.cornerRadius+"px",background:z(t.borderColor),padding:t.borderSize+"px",boxSizing:"border-box"}},T):T},W=({element:t,type:e})=>{const o={"stroke-width":t.height,stroke:t.color,"stroke-linecap":"round","stroke-linejoin":"round",opacity:t.opacity},i=Object.assign(Object.assign({},o),{fill:t.color}),n=Object.assign(Object.assign({},o),{fill:"none"});return"arrow"===e?h("polyline",Object.assign({points:`${3*t.height},${2*-t.height} 0,0 ${3*t.height},${2*t.height}`},n)):"triangle"===e?h("polygon",Object.assign({points:`${3*t.height},${2*-t.height} 0,0 ${3*t.height},${2*t.height}`},i)):"bar"===e?h("polyline",Object.assign({points:`0,${2*-t.height} 0,${2*t.height}`},n)):"circle"===e?h("circle",Object.assign({cx:2*t.height,cy:0,r:2*t.height},i)):"square"===e?h("polygon",Object.assign({points:`0,${2*-t.height} ${4*t.height},${2*-t.height} ${4*t.height},${2*t.height} 0,${2*t.height}`},i)):null},T={image:H,svg:H,text:async({element:t,page:e,store:o})=>{const i=u.isGradient(t.fill),n=u.isGradient(t.stroke);if(t.curveEnabled){const e=S(t.text,{fontSize:t.fontSize,fontFamily:t.fontFamily}),o=m(e,{fontSize:t.fontSize,fontFamily:t.fontFamily}),r=Math.max(t.fontSize,...o.map(e=>{var o;return null!==(o=e.fontSize)&&void 0!==o?o:t.fontSize})),a=g(t.width,t.height,t.curvePower,r),s={fontWeight:t.fontWeight||"normal",fontStyle:t.fontStyle||"normal",fill:t.fill||"black",fontFamily:t.fontFamily,fontSize:t.fontSize},l=k(o,s);let d=`\n <svg xmlns="http://www.w3.org/2000/svg" width="${t.width}" height="${t.height}" style="display: block;">\n <defs>\n <path id="curve-${t.id}" d="${a}" fill="none" />`;if(i){const e=`curve-fill-grad-${t.id}`;d+=y(t.fill,e)}if(n&&t.strokeWidth){const e=`curve-stroke-grad-${t.id}`;d+=y(t.stroke,e)}d+=`</defs>\n <text\n font-family="'${t.fontFamily}'"\n font-size="${t.fontSize}"\n font-weight="${t.fontWeight}"\n font-style="${t.fontStyle}"\n fill="${i?`url(#curve-fill-grad-${t.id})`:t.fill}"\n text-anchor="middle"\n dominant-baseline="central"\n letter-spacing="${t.letterSpacing*r}"${t.textDecoration?` text-decoration="${t.textDecoration}"`:""}${t.strokeWidth?` stroke="${n?`url(#curve-stroke-grad-${t.id})`:t.stroke}" stroke-width="${t.strokeWidth}" stroke-linejoin="${w(t.strokeLineJoin)}" paint-order="stroke fill"`:""}>\n <textPath href="#curve-${t.id}" startOffset="50%">${l}</textPath>\n </text>\n </svg>`;const c=t.backgroundPadding*(t.fontSize*t.lineHeight),p=t.backgroundEnabled&&h("div",{style:{position:"absolute",top:-c/2+"px",left:-c/2+"px",width:t.width+c+"px",height:t.height+c+"px",backgroundColor:t.backgroundColor,opacity:t.backgroundOpacity,borderRadius:t.backgroundCornerRadius*(t.fontSize*t.lineHeight*.5)+"px"}}),f=h("div",{style:{width:"100%",height:"100%",position:"absolute",top:0,left:0},innerHTML:d});return h("div",{style:{position:"relative",width:"100%",height:"100%"}},p,f)}const a=t=>({backgroundImage:t,backgroundSize:"100% 100%",backgroundRepeat:"repeat",WebkitBackgroundClip:"text",MozBackgroundClip:"text",backgroundClip:"text",WebkitTextFillColor:"transparent",MozTextFillColor:"transparent",color:"transparent"}),s="middle"===t.verticalAlign?{top:"50%",transform:"translateY(-50%)"}:"bottom"===t.verticalAlign?{bottom:0}:{top:0};let l=Object.assign(Object.assign({left:0},s),i?a(t.fill):{}),d=null;if(t.backgroundEnabled){if(t.legacyBackground){const e=t.backgroundPadding*(t.fontSize*t.lineHeight);d=h("div",{style:{position:"absolute",top:-e/2+"px",left:-e/2+"px",display:"block",width:t.width+e+"px",height:t.height+e+"px",backgroundColor:t.backgroundColor,opacity:t.backgroundOpacity,borderRadius:t.backgroundCornerRadius*(t.fontSize*t.lineHeight*.5)+"px"}})}else{const e=x(t);let o=[];try{o=v(e)}catch(W){o=[]}if(o.length){const i=t.backgroundPadding*(t.fontSize*t.lineHeight*.5),n=t.backgroundCornerRadius*(t.fontSize*t.lineHeight*.5),r=$({rects:o,padding:i,cornerRadius:n});if(r){let n=0;try{const{height:o}=j(e);"middle"===t.verticalAlign?n=(t.height-o)/2:"bottom"===t.verticalAlign&&(n=t.height-o)}catch(T){}const a=Math.min(...o.map(t=>t.top)),s=Math.max(...o.map(t=>t.bottom)),l=Math.min(...o.map(t=>t.left)),c=l-i,p=a-i,g=Math.max(...o.map(t=>t.right))-l+2*i,f=s-a+2*i;d=h("svg",{xmlns:"http://www.w3.org/2000/svg",width:g,height:f,viewBox:`${c} ${p} ${g} ${f}`,style:{position:"absolute",top:n+p+"px",left:c+"px",opacity:t.backgroundOpacity,pointerEvents:"none"},innerHTML:`<path d="${r}" fill="${t.backgroundColor}" />`})}}}}else{d=null}const c=/<[a-z][\s\S]*>/i.test(t.text),p=c?S(t.text,{fontSize:t.fontSize,fontFamily:t.fontFamily}):t.text.split("\n").join("<br />");if(t.strokeWidth&&(n||i&&!n)){const e={position:"absolute",width:t.width+"px",whiteSpace:"pre-wrap",overflowWrap:"break-word",fontSize:t.fontSize+"px",textAlign:t.align,fontFamily:`'${t.fontFamily}'`,textDecoration:t.textDecoration||"none",textDecorationColor:t.textDecoration?t.fill:void 0,textTransform:t.textTransform||"none",lineHeight:t.lineHeight,letterSpacing:t.letterSpacing*t.fontSize+"px",fontStyle:t.fontStyle,fontWeight:t.fontWeight},o=n?Object.assign(Object.assign(Object.assign({},e),a(t.stroke)),{WebkitTextStroke:`${t.strokeWidth}px transparent`}):Object.assign(Object.assign({},e),{color:"transparent",WebkitTextStroke:`${t.strokeWidth}px ${t.stroke}`}),l=i?Object.assign(Object.assign({},e),a(t.fill)):Object.assign(Object.assign({},e),{color:t.fill}),g="el-"+t.id,f=c?`<style>#${g} {${r}}</style>`:"",m=h("div",{style:Object.assign(Object.assign({},o),{position:"absolute",top:0,left:0,pointerEvents:"none"}),"aria-hidden":"true",innerHTML:c?`${f}${p}`:p}),b=h("div",Object.assign(Object.assign({style:Object.assign(Object.assign({},l),{position:"relative"})},c?{id:g}:{}),{innerHTML:c?`${f}${p}`:p}));return h("div",{style:{position:"relative",width:"100%",height:"100%"}},d,h("div",{style:Object.assign({position:"absolute",width:t.width+"px",left:0},s)},m,b))}const f=Object.assign(Object.assign({},l),{position:"absolute",width:t.width+"px",color:t.fill,whiteSpace:"pre-wrap",overflowWrap:"break-word",fontSize:t.fontSize+"px",textAlign:t.align,fontFamily:`'${t.fontFamily}'`,textDecoration:t.textDecoration||"none",textDecorationColor:t.textDecoration?t.fill:void 0,textTransform:t.textTransform||"none",lineHeight:t.lineHeight,letterSpacing:t.letterSpacing*t.fontSize+"px",fontStyle:t.fontStyle,fontWeight:t.fontWeight,WebkitTextStroke:t.strokeWidth?`${t.strokeWidth}px ${t.stroke}`:void 0,paintOrder:t.strokeWidth?"stroke fill":void 0}),b="el-"+t.id,O=c?{id:b}:{},z=`<style>#${b} {${r}}</style>`,H=h("div",Object.assign(Object.assign({style:f},O),{innerHTML:c?`${z}${p}`:p}));return h("div",{style:{position:"relative",width:"100%",height:"100%"}},d,H)},line:async({element:t,page:e,store:o})=>h("svg",{style:{width:"100%",height:"100%",contain:"layout style size",overflow:"visible"}},h("line",{x1:0,y1:t.height/2,x2:t.width,y2:t.height/2,stroke:t.color,"stroke-width":t.height,"stroke-dasharray":t.dash&&t.dash.length?t.dash.map(e=>e*t.height).join(" "):void 0}),h("g",{transform:`translate(0 ${t.height/2})`},W({element:t,type:t.startHead})),h("g",{transform:`translate(${t.width} ${t.height/2}) rotate(180)`},W({element:t,type:t.endHead}))),figure:async({element:t,page:e,store:o,elementHook:i})=>{let r=n(t);if(t.strokeWidth&&u.isGradient(t.stroke)){const e=`figure-stroke-grad-${t.id}`,o=y(t.stroke,e);r=r.replace(new RegExp(`stroke="${t.stroke.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}"`,"g"),`stroke="url(#${e})"`),r=r.replace("</defs>",`${o}</defs>`)}if(u.isGradient(t.fill)){const e=`figure-fill-grad-${t.id}`,o=y(t.fill,e);r=r.replace(new RegExp(`fill="${t.fill.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}"`,"g"),`fill="url(#${e})"`),r=r.replace("</defs>",`${o}</defs>`)}const a=h("div",{innerHTML:r});return i&&i({dom:a,element:t})||a},group:async({element:t,page:e,store:o,elementHook:i})=>{const n=await Promise.all(t.children.map(t=>M({element:t,page:e,store:o,elementHook:i}))),r=h("div",{style:{transformOrigin:"top left",opacity:t.opacity}},...n);return i&&i({dom:r,element:t})||r},video:async({element:t,page:e,store:o,elementHook:i})=>{const{cropX:n,cropY:r,cropWidth:a,cropHeight:s}=t,l=await d(t.src),c=l.width*a,p=l.height*s,g=t.width/t.height;let f,m;g>=c/p?(f=c,m=c/g):(f=p*g,m=p);const b=f/a,y=m/s,k=n*l.width,x=r*l.height,w=Math.max(t.width/l.width,t.height/l.height),$={position:"absolute",width:`${Math.round(b*w)}px`,height:`${Math.round(y*w)}px`,left:-Math.round(k*w)+"px",top:-Math.round(x*w)+"px",objectFit:"fill"},v=`video-${t.id}`,j=t.borderSize&&u.isGradient(t.borderColor),S=j?Math.max(0,t.cornerRadius-t.borderSize):t.cornerRadius,O=h("div",{style:{position:"relative",width:"100%",height:"100%",overflow:"hidden",borderRadius:S+"px",border:t.borderSize&&!j?`${t.borderSize}px solid ${t.borderColor}`:"none"}},h("video",{id:v,src:t.src,style:$,controls:!0,playsInline:!0,muted:!0,volume:t.volume}));if(j){const e=h("div",{style:{width:"100%",height:"100%",borderRadius:t.cornerRadius+"px",background:z(t.borderColor),padding:t.borderSize+"px",boxSizing:"border-box"}},O);return i&&i({dom:e,element:t})||e}return i&&i({dom:O,element:t})||O},gif:H,table:async({element:t})=>{const e=t.rows,o=t.cols,i=t.colWidths,n=t.rowHeights,r=["fontSize","fontFamily","fontWeight","fontStyle","textDecoration","textTransform","fill","align","verticalAlign","lineHeight","letterSpacing","strokeWidth","stroke","cellBackground","cellPadding"],a=(t.cells||[]).map(e=>{if(!e){return e}const o=Object.assign({},e);for(const i of r){void 0===o[i]&&(o[i]=t[i])}return o}),s=[];for(let d=0;d<e;d++){const e=[];for(let i=0;i<o;i++){const r=a[d*o+i];if(!r||r.mergedInto){continue}const s=r.cellPadding||4,l=r.colSpan||1,c=r.rowSpan||1,p=e=>{var o,i,n,a,s;const l=null===(o=r.borders)||void 0===o?void 0:o[e];return`${null!==(i=null==l?void 0:l.width)&&void 0!==i?i:t.borderWidth}px ${null!==(a=null!==(n=null==l?void 0:l.style)&&void 0!==n?n:t.borderStyle)&&void 0!==a?a:"solid"} ${null!==(s=null==l?void 0:l.color)&&void 0!==s?s:t.borderColor}`},g={style:{padding:s+"px",background:r.cellBackground||"transparent",fontSize:(r.fontSize||12)+"px",fontFamily:`'${r.fontFamily||"Roboto"}'`,fontWeight:r.fontWeight||"normal",fontStyle:r.fontStyle||"normal",color:r.fill||"black",textAlign:r.align||"left",verticalAlign:r.verticalAlign||"top",lineHeight:String(r.lineHeight||1.2),letterSpacing:r.letterSpacing?r.letterSpacing*(r.fontSize||12)+"px":void 0,textDecoration:r.textDecoration||"none",textTransform:r.textTransform||"none",borderTop:p("top"),borderRight:p("right"),borderBottom:p("bottom"),borderLeft:p("left"),overflow:"hidden",overflowWrap:"break-word",whiteSpace:"pre-wrap",height:n[d]*t.height+"px"}};l>1&&(g.colspan=String(l)),c>1&&(g.rowspan=String(c)),e.push(h("td",g,f(r.text||"")))}s.push(h("tr",{},...e))}const l=i.map(t=>h("col",{style:{width:100*t+"%"}}));return h("table",{style:{width:"100%",height:"100%",borderCollapse:"collapse",tableLayout:"fixed"}},h("colgroup",{},...l),h("tbody",{},...s))}};async function M({element:t,page:e,store:o,elementHook:i}){var n;let r=await T[t.type];if(r||(r=()=>h("div",{}),console.error(`HTML export does not support ${t.type} type...`)),!t.visible){return null}const d=await r({element:t,page:e,store:o}),c=[],p=[];if(t.blurEnabled&&c.push(`blur(${l(t)/2}px)`),t.brightnessEnabled&&c.push(`brightness(${100*t.brightness+100}%)`),t.sepiaEnabled&&c.push("sepia()"),t.grayscaleEnabled&&c.push("grayscale()"),t.filters){for(const[l,f]of Object.entries(t.filters)){const t=s(a[l],f.intensity);t&&(c.push(t.filter),t.html&&p.push(t.html))}}if(t.shadowEnabled){const e=function(t,e){if(1===e){return t}const o=b.Util.colorToRGBA(t);return o?`rgba(${o.r}, ${o.g}, ${o.b}, ${o.a*e})`:t}(t.shadowColor,null!==(n=t.shadowOpacity)&&void 0!==n?n:1);c.push(`drop-shadow(${t.shadowOffsetX}px ${t.shadowOffsetY}px ${t.shadowBlur/2}px ${e})`)}const g=h("div",{id:t.id,style:{position:"absolute",left:t.x+"px",top:t.y+"px",width:t.width+"px",height:t.height+"px",transform:`rotate(${t.rotation}deg)`,transformOrigin:"top left",opacity:t.opacity,display:t.visible&&t.showInExport?"block":"none",filter:c.join(" ")||"none"}},d,...p);return i&&i({dom:g,element:t})||g}export async function jsonToDOM({json:t,elementHook:i}){const n=await Promise.all(t.pages.map(n=>async function({page:t,store:i,elementHook:n}){const r=[...t.children.filter(t=>!t.alwaysOnTop),...t.children.filter(t=>t.alwaysOnTop)],a=await Promise.all(r.map(e=>M({element:e,page:t,store:i,elementHook:n}))),s="auto"===t.width?i.width:t.width,l="auto"===t.height?i.height:t.height;let d={};if(t.background.indexOf("url")>=0||t.background.indexOf("http")>=0||t.background.indexOf(".jpg")>=0||t.background.indexOf(".png")>=0||t.background.indexOf(".jpeg")>=0){const{width:n,height:r}=await o(t.background),d=await H({element:Object.assign({x:0,y:0,width:s,height:l,src:t.background,cornerRadius:0},e({width:s,height:l},{width:n,height:r})),page:t,store:i});a.unshift(d)}else{d=u.isGradient(t.background)?Object.assign(Object.assign({},d),{backgroundImage:t.background}):Object.assign(Object.assign({},d),{backgroundColor:t.background})}return h("div",{className:"page",id:t.id,style:Object.assign(Object.assign({},d),{width:s+"px",height:l+"px",overflow:"hidden",position:"relative"})},...a)}({page:n,store:t,elementHook:i}))),r=[];p({children:t.pages},t=>{if(("text"===t.type||"tablecell"===t.type||"table"===t.type)&&(t.fontFamily&&-1===r.indexOf(t.fontFamily)&&r.push(t.fontFamily),t.text)){for(const e of O(t.text)){-1===r.indexOf(e)&&r.push(e)}}});const a=r.map(e=>{const o=t.fonts.find(t=>t.fontFamily===e);if(o){const t=(o.styles||(o.url?[{src:`url("${o.url}")`}]:[])).map(t=>`\n @font-face {\n font-family: '${o.fontFamily}';\n src: ${t.src};\n font-style: ${t.fontStyle||"normal"};\n font-weight: ${t.fontWeight||"normal"};\n font-display: swap;\n }`).join("\n");return h("style",{},t)}return h("link",{href:c(e),rel:"stylesheet"})});return h("div",{className:"design"},...a,...n)}const R=({dom:e})=>{if("string"==typeof e){return e}if(!e){return""}const o=e.props,{innerHTML:i}=o,n=t(o,["innerHTML"]),r=Object.keys(n).map(t=>"style"===t&&"object"==typeof n[t]?`style="${Object.keys(n[t]).filter(e=>null!=n[t][e]).map(e=>`${e.replace(/[A-Z]/g,t=>`-${t.toLowerCase()}`)}: ${n[t][e]}`).join("; ")}"`:((t,e)=>null==e||""===e?"":"object"==typeof e?`${t}="${Object.keys(e).map(t=>`${t.replace(/-([a-z])/g,t=>t[1].toUpperCase())}:${e[t]};`).join(" ")}"`:`${t}="${e}"`)(t,n[t])).filter(t=>t&&t.trim().length>0).join(" ");return`<${e.type} ${r}>${i||e.children.map(t=>R({dom:t})).join("")}</${e.type}>`};export async function jsonToHTML({json:t,elementHook:e}){const o=await jsonToDOM({json:t,elementHook:e});return R({dom:o})}
package/utils/to-svg.js CHANGED
@@ -1 +1 @@
1
- var t=this&&this.__rest||function(t,e){var n={};for(var o in t){Object.prototype.hasOwnProperty.call(t,o)&&e.indexOf(o)<0&&(n[o]=t[o])}if(null!=t&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(o=Object.getOwnPropertySymbols(t);i<o.length;i++){e.indexOf(o[i])<0&&Object.prototype.propertyIsEnumerable.call(t,o[i])&&(n[o[i]]=t[o[i]])}}return n};import{cropImage as e,getCrop as n,loadImage as o}from"./image.js";import*as i from"./svg.js";import{figureToSvg as r}from"./figure-to-svg.js";import{Effects as l,shapeFilterToCSS as s}from"./filters.js";import{removeTags as a,parseHtmlToSegments as h}from"./text.js";import{segmentsToTspans as c}from"./text-html.js";import{xmlEscape as d}from"./xml.js";import{getCurvePath as f}from"../canvas/text-element.js";import*as g from"./gradient.js";import{normalizeRichTextHtml as p,extractFontFamiliesFromHtml as u}from"./rich-text-html.js";import{bulletMarkerPosition as m,numberMarkerPosition as y}from"./list-marker-geometry.js";import{generateBackgroundShapeFromRects as x,textLinesToRects as w}from"./background-shape.js";export const forEveryNode=(t,e)=>{if(t.children){for(const n of t.children){if(!0===e(n)){break}forEveryNode(n,e)}}if(t.cells){for(const n of t.cells){if(!0===e(n)){break}}}};const k=(t,e,...n)=>({type:t,props:e,children:n||[]});function b(t,e){if(!g.isGradient(t)){return null}const{stops:n,rotation:o}=g.parseColor(t),i=o*Math.PI/180,r=.5-.5*Math.sin(i),l=.5+.5*Math.cos(i),s=.5+.5*Math.sin(i),a=.5-.5*Math.cos(i),h=n.map(({offset:t,color:e})=>k("stop",{offset:100*t+"%","stop-color":e}));return k("linearGradient",{id:e,x1:100*r+"%",y1:100*l+"%",x2:100*s+"%",y2:100*a+"%"},...h)}export function fixRatio(t){var e=(new DOMParser).parseFromString(t,"image/svg+xml");return e.documentElement.setAttribute("preserveAspectRatio","none"),(new XMLSerializer).serializeToString(e)}const $=async t=>{try{const e=await fetch(t);if("undefined"!=typeof Buffer){const t=await e.arrayBuffer(),n=Buffer.from(t).toString("base64");return`data:${e.headers.get("content-type")||"image/png"};base64,${n}`}{const t=await e.blob();return new Promise((e,n)=>{const o=new FileReader;o.onloadend=()=>e(o.result),o.onerror=n,o.readAsDataURL(t)})}}catch(e){return console.error("Error converting URL to data URL:",e),t}},v=async({element:t,page:e,store:n})=>{let{src:r}=t;if("svg"===t.type){const e=await i.urlToString(r);r=i.replaceColors(e,new Map(Object.entries(t.colorsReplace)))}else{r=await $(r)}let l,s,a,h,c="";if(t.flipX||t.flipY){const e=t.flipX?-1:1,n=t.flipY?-1:1,o=t.width/2,i=t.height/2;c=`translate(${o}, ${i}) scale(${e}, ${n}) translate(${-o}, ${-i})`}t.clipSrc&&(l=`clip-img-mask-${t.id}`,s=await $(t.clipSrc)),t.maskSrc&&(a=`mask-img-${t.id}`,h=await $(t.maskSrc));const d=await o(r),f=d.width*t.cropWidth,p=d.height*t.cropHeight,u=t.width/t.height;let m,y;const x=f/p,w="boolean"==typeof t.stretchEnabled&&t.stretchEnabled||"svg"===t.type;w?(m=f,y=p):u>=x?(m=f,y=f/u):(m=p*u,y=p);const v=m/d.width,S=y/d.height,O=m/y>t.width/t.height?t.height/y:t.width/m,j=w?t.width/m:O,H=w?t.height/y:O,z=m*j/v,W=y*H/S;let M=t.cropX*d.width*j,E=t.cropY*d.height*H;t.flipX&&(M=(1-t.cropX-t.cropWidth)*d.width*j),t.flipY&&(E=(1-t.cropY-t.cropHeight)*d.height*H);const F=`clip-${t.id}`,T=t.cornerRadius||0,L=r.replace(/&/g,"&amp;"),C={x:-M,y:-E,width:z,height:W,preserveAspectRatio:"none","clip-path":`url(#${F})`},A=[k("clipPath",{id:F},k("rect",{x:0,y:0,width:t.width,height:t.height,rx:T||void 0,ry:T||void 0}))];l&&s&&A.push(k("mask",{id:l,maskUnits:"userSpaceOnUse","mask-type":"alpha"},k("image",{href:s.replace(/&/g,"&amp;"),x:0,y:0,width:t.width,height:t.height,preserveAspectRatio:"none"}))),a&&A.push(k("mask",{id:a,maskUnits:"userSpaceOnUse","mask-type":"alpha"},k("image",Object.assign({href:L},C))));let B=L;const R={};a&&h&&(B=h.replace(/&/g,"&amp;"),R.mask=`url(#${a})`);const P={};l&&(P.mask=`url(#${l})`);const D=t.borderSize||0,N=D>0&&g.isGradient(t.borderColor),U=N?`border-grad-${t.id}`:null;if(N){const e=b(t.borderColor,U);e&&A.push(e)}const G=D>0?k("rect",{x:D/2,y:D/2,width:Math.max(0,t.width-D),height:Math.max(0,t.height-D),fill:"none",stroke:N?`url(#${U})`:t.borderColor,"stroke-width":D,rx:Math.max(0,T-D)||void 0,ry:Math.max(0,T-D)||void 0}):null,I=k("g",{},k("defs",{},...A),k("image",Object.assign(Object.assign({href:B},C),R)),G);return k("g",P,c?k("g",{transform:c},I):I)},S=({element:t,type:e})=>{const n={"stroke-width":t.height,stroke:t.color,"stroke-linecap":"round","stroke-linejoin":"round"},o=Object.assign(Object.assign({},n),{fill:t.color}),i=Object.assign(Object.assign({},n),{fill:"none"});return"arrow"===e?k("polyline",Object.assign({points:`${3*t.height},${2*-t.height} 0,0 ${3*t.height},${2*t.height}`},i)):"triangle"===e?k("polygon",Object.assign({points:`${3*t.height},${2*-t.height} 0,0 ${3*t.height},${2*t.height}`},o)):"bar"===e?k("polyline",Object.assign({points:`0,${2*-t.height} 0,${2*t.height}`},i)):"circle"===e?k("circle",Object.assign({cx:2*t.height,cy:0,r:2*t.height},o)):"square"===e?k("polygon",Object.assign({points:`0,${2*-t.height} ${4*t.height},${2*-t.height} ${4*t.height},${2*t.height} 0,${2*t.height}`},o)):null},O={image:v,svg:v,text:async({element:t,page:e,store:n})=>{const o=g.isGradient(t.fill),i=g.isGradient(t.stroke);if(t.curveEnabled){const e=p(t.text,{fontSize:t.fontSize,fontFamily:t.fontFamily}),n=h(e,{fontSize:t.fontSize,fontFamily:t.fontFamily}),r=Math.max(t.fontSize,...n.map(e=>{var n;return null!==(n=e.fontSize)&&void 0!==n?n:t.fontSize})),l=f(t.width,t.height,t.curvePower,r),s=z(t.id||"temp"),a=`curve-path-${s}`,d={fontWeight:t.fontWeight||"normal",fontStyle:t.fontStyle||"normal",fill:t.fill||"black",fontFamily:t.fontFamily,fontSize:t.fontSize},g=c(n,d),u=c(n,d,{omitColors:!0}),m=t.backgroundPadding*(t.fontSize*t.lineHeight*.5),y=t.backgroundEnabled?k("rect",{x:-m,y:-m,width:t.width+2*m,height:t.height+2*m,fill:t.backgroundColor,opacity:t.backgroundOpacity,rx:t.backgroundCornerRadius*(t.fontSize*t.lineHeight*.5),ry:t.backgroundCornerRadius*(t.fontSize*t.lineHeight*.5)}):null,x=[k("path",{id:a,d:l,fill:"none"})],w=t.strokeWidth&&(i||o&&!i);if(o){const e=`curve-fill-grad-${s}`,n=b(t.fill,e);n&&x.push(n)}if(i&&t.strokeWidth){const e=`curve-stroke-grad-${s}`,n=b(t.stroke,e);n&&x.push(n)}if(w){const e={"font-size":t.fontSize+"px","text-anchor":"middle","dominant-baseline":"central","font-family":t.fontFamily,"font-style":t.fontStyle,"font-weight":t.fontWeight,"text-decoration":t.textDecoration||void 0,"letter-spacing":t.letterSpacing*r},n=i?`url(#curve-stroke-grad-${s})`:t.stroke,l=k("text",Object.assign(Object.assign({},e),{fill:n,"stroke-width":t.strokeWidth,stroke:n}),k("textPath",{href:`#${a}`,startOffset:"50%",innerHTML:u})),h=o?`url(#curve-fill-grad-${s})`:t.fill,c=k("text",Object.assign(Object.assign({},e),{fill:h}),k("textPath",{href:`#${a}`,startOffset:"50%",innerHTML:g}));return k("g",{},y,k("defs",{},...x),l,c)}return k("g",{},y,k("defs",{},...x),k("text",{fill:o?`url(#curve-fill-grad-${s})`:t.fill,"font-size":t.fontSize+"px","text-anchor":"middle","dominant-baseline":"central","font-family":t.fontFamily,"font-style":t.fontStyle,"font-weight":t.fontWeight,"text-decoration":t.textDecoration||void 0,"letter-spacing":t.letterSpacing*r,"stroke-width":t.strokeWidth||void 0,stroke:t.strokeWidth?i?`url(#curve-stroke-grad-${s})`:t.stroke:void 0,"paint-order":t.strokeWidth?"stroke fill":void 0},k("textPath",{href:`#${a}`,startOffset:"50%",innerHTML:g})))}let r=null;const l=()=>(r||(r=document.createElement("canvas").getContext("2d")),r),s=(t,e,n,o,i,r=0)=>{const s=l();return s.font=`${i} ${o} ${e}px ${n}`,s.measureText(t).width+Math.max(0,(t?t.length:0)-1)*r*e},a=(e,n,o)=>{let i=n;null!=e.fontSize&&e.fontSize!==t.fontSize&&t.fontSize>0&&(i=e.fontSize*(n/t.fontSize));const r=e.fontFamily||t.fontFamily,l=e.bold?"bold":t.fontWeight||"normal",a=e.italic?"italic":t.fontStyle||"normal";return s(e.text,i,r,l,a,o)},u=/<[a-z][\s\S]*>/i.test(t.text);let $=t.text;!u&&$.includes("\n")&&($=$.split("\n").map(t=>`<p>${t}</p>`).join(""));const v=p($,{fontSize:t.fontSize,fontFamily:t.fontFamily}),S={fontSize:t.fontSize,fontFamily:t.fontFamily},O=[],j=(new DOMParser).parseFromString(v,"text/html"),H=j.body.querySelectorAll("p");H.length>0?H.forEach((t,e)=>{const n=t.innerHTML,o=h(n,S);O.push(...o),e<H.length-1&&O.push({text:"\n"})}):O.push(...h(v,S)),"uppercase"===t.textTransform&&O.forEach(t=>{"\n"!==t.text&&(t.text=t.text.toUpperCase())});const W=t=>{const e=[];let n=[];for(const o of t){if("\n"===o.text){n.length>0&&(e.push(n),n=[]),e.push([Object.assign(Object.assign({},o),{text:"\n"})]);continue}const t=o.text.split(/( )/);for(const i of t){""!==i&&(" "===i?(n.length>0&&(e.push(n),n=[]),e.push([Object.assign(Object.assign({},o),{text:" "})])):n.push(Object.assign(Object.assign({},o),{text:i})))}}return n.length>0&&e.push(n),e},M=(t,e,n,o)=>{const i=[[]];let r=0;for(const l of t){if(1===l.length&&"\n"===l[0].text){i.push([]),r=0;continue}const t=l.reduce((t,e)=>t+a(e,n,o),0);1!==l.length||" "!==l[0].text?(r+t>e+.5&&i[i.length-1].length>0&&(i.push([]),r=0),i[i.length-1].push(...l),r+=t):r+t<=e+.5&&(i[i.length-1].push(...l),r+=t)}return i},E=(t,e,n)=>t.reduce((t,o)=>t+a(o,e,n),0),F=(t,e)=>1===e?t:t.map(t=>t.map(t=>t.fontSize?Object.assign(Object.assign({},t),{fontSize:Math.round(t.fontSize*e*1e3)/1e3}):t));if(j.body.querySelector("ul, ol")){const e=[],n=2.1,r=e=>{const n=e.cloneNode(!0);n.querySelectorAll("ul, ol").forEach(t=>t.remove());const o=h(n.innerHTML,S);return"uppercase"===t.textTransform&&o.forEach(t=>{"\n"!==t.text&&(t.text=t.text.toUpperCase())}),o},a=(t,n)=>{for(const o of Array.from(t.children)){const t=o.tagName.toLowerCase();if("ul"===t||"ol"===t){const i="ol"===t;let l=parseInt(o.getAttribute("start")||"1",10)||1;for(const t of Array.from(o.children)){if("li"!==t.tagName.toLowerCase()){continue}const o=t.getAttribute("value");o&&!Number.isNaN(parseInt(o,10))&&(l=parseInt(o,10));const s=i?{text:`${l}.`,isOrdered:!0}:{text:"•",isOrdered:!1};e.push({segments:r(t),depth:n+1,marker:s}),i&&(l+=1),a(t,n+1)}}else{"p"===t||"div"===t?e.push({segments:r(o),depth:0,marker:null}):e.push({segments:h(o.outerHTML,S),depth:0,marker:null})}}};a(j.body,0);const f=o=>{const i=[],r=[];for(const l of e){const e=l.depth*n*o,s=Math.max(1,t.width-e);(0===l.segments.length?[[]]:M(W(l.segments),s,o,t.letterSpacing)).forEach((t,n)=>{i.push(t),r.push({indent:e,marker:0===n?l.marker:null})})}return{L:i,M:r}};let g=t.fontSize,p=[],u=[];for(;;){const e=f(g);p=e.L,u=e.M;const n=Math.max(0,...p.map((e,n)=>u[n].indent+E(e,g,t.letterSpacing))),o=p.length*g*t.lineHeight;if(n<=t.width&&(!t.height||o<=t.height)){break}if(g-=1,g<4){break}}p=F(p,g/t.fontSize);const w=g*t.lineHeight,$=p.length*w;let v=0;"middle"===t.verticalAlign?v=(t.height-$)/2:"bottom"===t.verticalAlign&&(v=t.height-$);const O=g+v,H={fontWeight:t.fontWeight||"normal",fontStyle:t.fontStyle||"normal",fill:t.fill||"black",fontFamily:t.fontFamily,fontSize:g},z=t=>{let e=t.length;for(;e>0&&""===t[e-1].text.trim();){e--}return t.slice(0,e)},T=l(),L=t.fontWeight||"normal",C=t.fontStyle||"normal";T.font=`${C} ${L} ${g}px ${t.fontFamily}`;const A=T.measureText(" ").width,B=u.map((e,n)=>{var o,i,r,l,a;if(!e.marker){return null}const h=O+n*w;let c;if(e.marker.isOrdered){const n=s(e.marker.text,g,t.fontFamily,L,C,t.letterSpacing);c=y(e.indent,h,{markerWidth:n,spaceWidth:A})}else{const t=T.measureText(e.marker.text);c=m(e.indent,h,{ascent:null!==(i=null!==(o=t.fontBoundingBoxAscent)&&void 0!==o?o:t.actualBoundingBoxAscent)&&void 0!==i?i:.8*g,inkRight:null!==(r=t.actualBoundingBoxRight)&&void 0!==r?r:0,inkAscent:null!==(l=t.actualBoundingBoxAscent)&&void 0!==l?l:0,inkDescent:null!==(a=t.actualBoundingBoxDescent)&&void 0!==a?a:0})}return k("tspan",{x:c.x,y:c.y,"letter-spacing":e.marker.isOrdered?t.letterSpacing*g+"px":void 0,innerHTML:d(e.marker.text)})}),R=t=>{const e=[];return p.forEach((n,o)=>{const i=z(n);i.length>0&&e.push(k("tspan",{x:u[o].indent,y:O+o*w,innerHTML:c(i,H,{omitColors:t})})),B[o]&&e.push(B[o])}),e};let P=null;if(t.backgroundEnabled){const e=t.backgroundPadding*(g*t.lineHeight*.5),n=t.backgroundCornerRadius*(g*t.lineHeight*.5);if(t.legacyBackground){P=k("rect",{x:-e,y:-e,width:t.width+2*e,height:t.height+2*e,fill:t.backgroundColor,opacity:t.backgroundOpacity,rx:n,ry:n})}else{const o=p.map((e,n)=>{const o=e.length?E(e,g,t.letterSpacing):0,i=n*w;return{left:u[n].indent,right:u[n].indent+o,top:i,bottom:i+w}}).filter(t=>t.right>t.left),i=x({rects:o,padding:e,cornerRadius:n});i&&(P=k("path",{d:i,fill:t.backgroundColor,opacity:t.backgroundOpacity,transform:v?`translate(0,${v})`:void 0}))}}const D=[];if(o){const e=b(t.fill,`text-fill-grad-${t.id}`);e&&D.push(e)}if(i&&t.strokeWidth){const e=b(t.stroke,`text-stroke-grad-${t.id}`);e&&D.push(e)}const N=t.strokeWidth&&(i||o&&!i),U={"font-size":g+"px","text-anchor":"start","font-family":t.fontFamily,"font-style":t.fontStyle,"font-weight":t.fontWeight,"text-decoration":t.textDecoration,"letter-spacing":t.letterSpacing*g+"px"};if(N){const e=R(!0),n=i?`url(#text-stroke-grad-${t.id})`:t.stroke,r=k("text",Object.assign(Object.assign({},U),{fill:n,"stroke-width":t.strokeWidth,stroke:n}),...e.map(t=>k("tspan",t.props,t.props.innerHTML))),l=o?`url(#text-fill-grad-${t.id})`:t.fill,s=o?e:R(!1),a=k("text",Object.assign(Object.assign({},U),{fill:l}),...s.map(t=>k("tspan",t.props,t.props.innerHTML)));return k("g",{},P,D.length>0?k("defs",{},...D):null,r,a)}return k("g",{},P,D.length>0?k("defs",{},...D):null,k("text",Object.assign(Object.assign({},U),{fill:o?`url(#text-fill-grad-${t.id})`:t.fill,"stroke-width":t.strokeWidth||void 0,stroke:t.strokeWidth?t.stroke:void 0,"paint-order":t.strokeWidth?"stroke fill":void 0}),...R(!1)))}let T=t.fontSize;const L=W(O);let C=[];for(;;){C=M(L,t.width,T,t.letterSpacing);const e=Math.max(...C.map(e=>E(e,T,t.letterSpacing)),0),n=C.length*T*t.lineHeight;if(e<=t.width&&n<=t.height){break}if(T-=1,T<4){break}}C=F(C,T/t.fontSize);const A=T*t.lineHeight,B=C.length*A;let R=T;"middle"===t.verticalAlign?R=(t.height-B)/2+T:"bottom"===t.verticalAlign&&(R=t.height-B+T);const P="center"===t.align?"middle":"right"===t.align?"end":"start",D={fontWeight:t.fontWeight||"normal",fontStyle:t.fontStyle||"normal",fill:t.fill||"black",fontFamily:t.fontFamily,fontSize:T},N="center"===t.align?t.width/2:"right"===t.align?t.width:0,U=t=>{let e=t.length;for(;e>0&&""===t[e-1].text.trim();){e--}return t.slice(0,e)},G=C.map((t,e)=>{const n=U(t),o=0===n.length?"​":c(n,D);return k("tspan",{x:N,dy:0===e?0:A,innerHTML:o})}),I=t.backgroundPadding*(T*t.lineHeight*.5),X=t.backgroundCornerRadius*(T*t.lineHeight*.5);let Y=null;if(t.backgroundEnabled){if(t.legacyBackground){Y=k("rect",{x:-I,y:-I,width:t.width+2*I,height:t.height+2*I,fill:t.backgroundColor,opacity:t.backgroundOpacity,rx:X,ry:X})}else{const e=w({lines:C.map(e=>({width:0===e.length?0:E(e,T,t.letterSpacing)})),lineHeight:A,width:t.width,align:"justify"===t.align?"justify":t.align});let n=0;"middle"===t.verticalAlign?n=(t.height-C.length*A)/2:"bottom"===t.verticalAlign&&(n=t.height-C.length*A);const o=x({rects:e,padding:I,cornerRadius:X});o&&(Y=k("path",{d:o,fill:t.backgroundColor,opacity:t.backgroundOpacity,transform:n?`translate(0,${n})`:void 0}))}}const q=[],V=t.strokeWidth&&(i||o&&!i);if(o){const e=`text-fill-grad-${t.id}`,n=b(t.fill,e);n&&q.push(n)}if(i&&t.strokeWidth){const e=`text-stroke-grad-${t.id}`,n=b(t.stroke,e);n&&q.push(n)}if(V){const e=C.map((t,e)=>{const n=U(t),o=c(n,D,{omitColors:!0});return k("tspan",{x:N,dy:0===e?0:A,innerHTML:o})}),n={y:R,"font-size":T+"px","text-anchor":P,"font-family":t.fontFamily,"font-style":t.fontStyle,"font-weight":t.fontWeight,"text-decoration":t.textDecoration,"letter-spacing":t.letterSpacing*T+"px"},r=i?`url(#text-stroke-grad-${t.id})`:t.stroke,l=k("text",Object.assign(Object.assign({},n),{fill:r,"stroke-width":t.strokeWidth,stroke:r}),...e.map(t=>k("tspan",t.props,t.props.innerHTML))),s=o?`url(#text-fill-grad-${t.id})`:t.fill,a=o?e:G,h=k("text",Object.assign(Object.assign({},n),{fill:s}),...a.map(t=>k("tspan",t.props,t.props.innerHTML)));return k("g",{},Y,q.length>0?k("defs",{},...q):null,l,h)}return k("g",{},Y,q.length>0?k("defs",{},...q):null,k("text",{fill:o?`url(#text-fill-grad-${t.id})`:t.fill,y:R,"font-size":T+"px","text-anchor":P,"font-family":t.fontFamily,"font-style":t.fontStyle,"font-weight":t.fontWeight,"text-decoration":t.textDecoration,"letter-spacing":t.letterSpacing*T+"px","stroke-width":t.strokeWidth||void 0,stroke:t.strokeWidth?t.stroke:void 0,"paint-order":t.strokeWidth?"stroke fill":void 0},...G))},line:async({element:t,page:e,store:n})=>k("g",{},k("line",{x1:0,y1:t.height/2,x2:t.width,y2:t.height/2,stroke:t.color,"stroke-width":t.height,"stroke-dasharray":t.dash&&t.dash.length?t.dash.map(e=>e*t.height).join(" "):void 0}),k("g",{transform:`translate(0 ${t.height/2})`},S({element:t,type:t.startHead})),k("g",{transform:`translate(${t.width} ${t.height/2}) rotate(180)`},S({element:t,type:t.endHead}))),figure:async({element:t,page:e,store:n,elementHook:o})=>{let i=function(t){let e=t.replace(/<svg[^>]*>/,"");return e=e.replace(/<\/svg>/,""),e}(r(t));const l=[];if(t.strokeWidth&&g.isGradient(t.stroke)){const e=`figure-stroke-grad-${t.id}`,n=b(t.stroke,e);if(n){l.push(n);const o=t.stroke.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");i=i.replace(new RegExp(`stroke="${o}"`,"g"),`stroke="url(#${e})"`)}}if(g.isGradient(t.fill)){const e=`figure-fill-grad-${t.id}`,n=b(t.fill,e);if(n){l.push(n);const o=t.fill.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");i=i.replace(new RegExp(`fill="${o}"`,"g"),`fill="url(#${e})"`)}}if(l.length>0){const e=k("g",{},k("defs",{},...l),k("g",{innerHTML:i}));return o&&o({dom:e,element:t})||e}const s=k("g",{innerHTML:i});return o&&o({dom:s,element:t})||s},group:async({element:t,page:e,store:n,elementHook:o})=>{const i=await Promise.all(t.children.map(t=>j({element:t,page:e,store:n,elementHook:o}))),r=k("g",{style:{"transform-origin":"top left"}},...i);return o&&o({dom:r,element:t})||r},gif:v,table:async({element:t})=>{t.rows;const e=t.cols,n=t.colWidths,o=t.rowHeights,i=["fontSize","fontFamily","fontWeight","fontStyle","textDecoration","textTransform","fill","align","verticalAlign","lineHeight","letterSpacing","strokeWidth","stroke","cellBackground","cellPadding"],r=(t.cells||[]).map((n,o)=>{const r=Object.assign(Object.assign({},n),{row:Math.floor(o/e),col:o%e});for(const e of i){void 0===r[e]&&(r[e]=t[e])}return r}),l=[],s=(e,i,r,l)=>{let s=0;for(let o=0;o<i;o++){s+=n[o]*t.width}let a=0;for(let n=0;n<e;n++){a+=o[n]*t.height}let h=0;for(let o=i;o<i+l;o++){h+=(n[o]||0)*t.width}let c=0;for(let n=e;n<e+r;n++){c+=(o[n]||0)*t.height}return{x:s,y:a,width:h,height:c}};for(const a of r){if(!a.mergedInto&&a.cellBackground&&"transparent"!==a.cellBackground){s(a.row,a.col,a.colSpan||1,a.colSpan||1);const{x:t,y:e,width:n,height:o}=s(a.row,a.col,a.rowSpan||1,a.colSpan||1);l.push(k("rect",{x:t,y:e,width:n,height:o,fill:a.cellBackground}))}}const h=(t,e)=>"dashed"===t?`${4*e},${2*e}`:"dotted"===t?`${e},${e}`:void 0,c=(e,n)=>{var o,i,r,l,s;const a=null===(o=e.borders)||void 0===o?void 0:o[n];return{width:null!==(i=null==a?void 0:a.width)&&void 0!==i?i:t.borderWidth,style:null!==(l=null!==(r=null==a?void 0:a.style)&&void 0!==r?r:t.borderStyle)&&void 0!==l?l:"solid",color:null!==(s=null==a?void 0:a.color)&&void 0!==s?s:t.borderColor}};for(const a of r){if(a.mergedInto){continue}const t=s(a.row,a.col,a.rowSpan||1,a.colSpan||1);if(0===a.row){const e=c(a,"top");"none"!==e.style&&e.width>0&&l.push(k("line",{x1:t.x,y1:t.y+e.width/2,x2:t.x+t.width,y2:t.y+e.width/2,stroke:e.color,"stroke-width":e.width,"stroke-dasharray":h(e.style,e.width)}))}if(0===a.col){const e=c(a,"left");"none"!==e.style&&e.width>0&&l.push(k("line",{x1:t.x+e.width/2,y1:t.y,x2:t.x+e.width/2,y2:t.y+t.height,stroke:e.color,"stroke-width":e.width,"stroke-dasharray":h(e.style,e.width)}))}{const e=c(a,"bottom");"none"!==e.style&&e.width>0&&l.push(k("line",{x1:t.x,y1:t.y+t.height-e.width/2,x2:t.x+t.width,y2:t.y+t.height-e.width/2,stroke:e.color,"stroke-width":e.width,"stroke-dasharray":h(e.style,e.width)}))}{const e=c(a,"right");"none"!==e.style&&e.width>0&&l.push(k("line",{x1:t.x+t.width-e.width/2,y1:t.y,x2:t.x+t.width-e.width/2,y2:t.y+t.height,stroke:e.color,"stroke-width":e.width,"stroke-dasharray":h(e.style,e.width)}))}}for(const f of r){if(f.mergedInto){continue}let e=a(f.text||"");if(!e){continue}"uppercase"===f.textTransform&&(e=e.toUpperCase());const i=f.cellPadding||4;let r=0;for(let o=0;o<f.col;o++){r+=n[o]*t.width}let s=0;for(let n=0;n<f.row;n++){s+=o[n]*t.height}const h=n[f.col]*t.width,c=o[f.row]*t.height,g=f.fontSize||12,p=f.align||"left";let u=r+i,m="start";"center"===p?(u=r+h/2,m="middle"):"right"===p&&(u=r+h-i,m="end");let y=s+i+g;const x=f.verticalAlign||"top";"middle"===x?y=s+c/2+g/3:"bottom"===x&&(y=s+c-i),l.push(k("text",{x:u,y,"font-size":g,"font-family":f.fontFamily||"Roboto","font-weight":f.fontWeight||"normal","font-style":f.fontStyle||"normal",fill:f.fill||"black","text-anchor":m,"text-decoration":f.textDecoration||"none","letter-spacing":f.letterSpacing?f.letterSpacing*g+"px":void 0},d(e)))}return k("g",{},...l)}};async function j({element:t,page:e,store:n,elementHook:o}){var i;let r=await O[t.type];r||(r=()=>k("g",{}),console.error(`SVG export does not support ${t.type} type...`));const a=await r({element:t,page:e,store:n}),h=[],c=[];if(t.blurEnabled&&h.push(`blur(${t.blurRadius/2}px)`),t.brightnessEnabled&&h.push(`brightness(${100*t.brightness+100}%)`),t.sepiaEnabled&&h.push("sepia()"),t.grayscaleEnabled&&h.push("grayscale()"),t.shadowEnabled&&h.push(`drop-shadow(${t.shadowOffsetX}px ${t.shadowOffsetY}px ${t.shadowBlur}px ${t.shadowColor})`),t.filters){for(const[f,g]of Object.entries(t.filters)){const t=s(l[f],g.intensity);if(t&&(h.push(t.filter),t.html)){const e=t.html.replace(/<svg([^>]*)>/,"<g$1>").replace(/<\/svg>/,"</g>");c.push(e)}}}const d=k("g",{className:"element",id:t.id,transform:"group"!==t.type?`translate(${t.x}, ${t.y}) rotate(${t.rotation})`:void 0,display:null===(i=t.visible)||void 0===i||i?void 0:"none",opacity:t.opacity,style:{"transform-origin":"top left",filter:h.join(" ")}},a,...c);return o&&o({dom:d,element:t})||d}async function H(t){try{const e=await fetch(t),n=e.headers.get("content-type")||"font/ttf",o=await e.arrayBuffer();return`data:${n};base64,${"undefined"!=typeof Buffer?Buffer.from(o).toString("base64"):function(t){const e=new Uint8Array(t);let n="";for(let o=0;o<e.length;o+=32768){const t=e.subarray(o,o+32768);n+=String.fromCharCode(...t)}if("undefined"!=typeof btoa){return btoa(n)}if("undefined"!=typeof Buffer){return Buffer.from(e).toString("base64")}throw new Error("No base64 encoder available in this environment")}(o)}`}catch(e){return console.error("Error embedding font:",e),t}}export async function jsonToDOM({json:t,elementHook:i,fontEmbedding:r="inline"}){const l=[];forEveryNode({children:t.pages},t=>{if(("text"===t.type||"tablecell"===t.type||"table"===t.type)&&(t.fontFamily&&-1===l.indexOf(t.fontFamily)&&l.push(t.fontFamily),t.text)){for(const e of u(t.text)){-1===l.indexOf(e)&&l.push(e)}}});const s="inline"===r?await async function(t,e){return await Promise.all(t.map(async t=>{var n,o;if("Arial"===t){return null}const i=e.find(e=>e.fontFamily===t);if(i){const e=i.styles||(i.url?[{src:`url("${i.url}")`,fontStyle:"normal",fontWeight:"normal"}]:[]),n=await Promise.all(e.map(async e=>{var n,o;const r=(null===(o=null===(n=e.src)||void 0===n?void 0:n.match(/url\("?(.*?)"?\)/))||void 0===o?void 0:o[1])||i.url,l=await H(r);return`@font-face {\n font-family: '${t}';\n font-style: ${e.fontStyle||"normal"};\n font-weight: ${e.fontWeight||"normal"};\n src: url(${l});\n}`}));return k("style",{},n.join("\n"))}{const e=`https://fonts.googleapis.com/css?family=${encodeURIComponent(t)}:bi,normal,i,b`;try{const i=await fetch(e),r=await i.text(),l=null===(o=null===(n=r.match(/url\((.*?)\)/g))||void 0===n?void 0:n.map(t=>t.replace(/url\((.*?)\)/,"$1")))||void 0===o?void 0:o.filter(t=>t.startsWith("https"));if(!(null==l?void 0:l.length)){throw new Error("No font URLs found")}const s=await Promise.all(l.map(async e=>{const n=await H(e),o=(r.match(/@font-face\s*\{[^}]*?\}/g)||[]).find(t=>t.includes(e))||"",i=o.match(/font-style:\s*(.*?)[;\s}]/),l=o.match(/font-weight:\s*(.*?)[;\s}]/),s=i?i[1].trim():"normal",a=l?l[1].trim():"normal";return`@font-face {\n font-family: '${t}';\n font-style: ${s};\n font-weight: ${a};\n src: url(${n});\n}`}));return k("style",{},s.join("\n"))}catch(r){return console.error("Error embedding Google Font:",r),k("defs",{},k("style",{type:"text/css",innerHTML:`@import url('${e}');`.replace(/&/g,"&amp;")}))}}}))}(l,t.fonts):[],a=await Promise.all(t.pages.map(r=>async function({page:t,store:i,elementHook:r}){const l=[...t.children.filter(t=>!t.alwaysOnTop),...t.children.filter(t=>t.alwaysOnTop)],s=await Promise.all(l.map(e=>j({element:e,page:t,store:i,elementHook:r}))),a=t.background.indexOf("url")>=0||t.background.indexOf("http")>=0||t.background.indexOf(".jpg")>=0||t.background.indexOf(".png")>=0||t.background.indexOf(".jpeg")>=0;let h;if(a){const r=await o(t.background);h=await e(t.background,Object.assign({width:i.width,height:i.height,x:0,y:0},n({width:i.width,height:i.height},{width:r.width,height:r.height})))}return k("g",{className:"page",style:{}},a?k("image",{"xlink:href":h,x:0,y:0,width:i.width,height:i.height,preserveAspectRatio:"none"}):k("rect",{x:0,y:0,width:i.width,height:i.height,fill:a?void 0:t.background}),...s)}({page:r,store:t,elementHook:i})));return k("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:`0 0 ${t.width} ${t.height}`,width:t.width,height:t.height},...s,...a)}function z(t){return String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}const W=({dom:e,nestLevel:n=0})=>{if("string"==typeof e){return e}if(!e){return""}const o=e.props,{innerHTML:i}=o,r=t(o,["innerHTML"]),l=Object.keys(r).map(t=>((t,e)=>"object"==typeof e?`${t}="${Object.keys(e).map(t=>`${t}:${e[t]};`).join(" ")}"`:null==e||""===e?"":`${t}="${z(String(e))}"`)(t,r[t])).filter(t=>t&&t.trim().length>0).join(" "),s=" ".repeat(n);return`${s}<${e.type}${l?" "+l:""}>${i||"\n"+e.children.map(t=>W({dom:t,nestLevel:n+1})).join("")}${s}</${e.type}>\n`};export async function jsonToSVG({json:t,elementHook:e,fontEmbedding:n="inline"}){const o=await jsonToDOM({json:t,elementHook:e,fontEmbedding:n});return W({dom:o})}
1
+ var t=this&&this.__rest||function(t,e){var n={};for(var o in t){Object.prototype.hasOwnProperty.call(t,o)&&e.indexOf(o)<0&&(n[o]=t[o])}if(null!=t&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(o=Object.getOwnPropertySymbols(t);i<o.length;i++){e.indexOf(o[i])<0&&Object.prototype.propertyIsEnumerable.call(t,o[i])&&(n[o[i]]=t[o[i]])}}return n};import{cropImage as e,getCrop as n,loadImage as o}from"./image.js";import*as i from"./svg.js";import{figureToSvg as r}from"./figure-to-svg.js";import{Effects as l,shapeFilterToCSS as s}from"./filters.js";import{getElementBlurRadius as a}from"../canvas/apply-filters.js";import{removeTags as h,parseHtmlToSegments as c}from"./text.js";import{segmentsToTspans as d,normalizeStrokeLineJoin as f}from"./text-html.js";import{xmlEscape as g}from"./xml.js";import{getCurvePath as p}from"../canvas/text-element.js";import*as u from"./gradient.js";import{normalizeRichTextHtml as m,extractFontFamiliesFromHtml as y}from"./rich-text-html.js";import{bulletMarkerPosition as x,numberMarkerPosition as k}from"./list-marker-geometry.js";import{generateBackgroundShapeFromRects as w,textLinesToRects as b}from"./background-shape.js";export const forEveryNode=(t,e)=>{if(t.children){for(const n of t.children){if(!0===e(n)){break}forEveryNode(n,e)}}if(t.cells){for(const n of t.cells){if(!0===e(n)){break}}}};const $=(t,e,...n)=>({type:t,props:e,children:n||[]});function v(t,e){if(!u.isGradient(t)){return null}const{stops:n,rotation:o}=u.parseColor(t),i=o*Math.PI/180,r=.5-.5*Math.sin(i),l=.5+.5*Math.cos(i),s=.5+.5*Math.sin(i),a=.5-.5*Math.cos(i),h=n.map(({offset:t,color:e})=>$("stop",{offset:100*t+"%","stop-color":e}));return $("linearGradient",{id:e,x1:100*r+"%",y1:100*l+"%",x2:100*s+"%",y2:100*a+"%"},...h)}export function fixRatio(t){var e=(new DOMParser).parseFromString(t,"image/svg+xml");return e.documentElement.setAttribute("preserveAspectRatio","none"),(new XMLSerializer).serializeToString(e)}const S=async t=>{try{const e=await fetch(t);if("undefined"!=typeof Buffer){const t=await e.arrayBuffer(),n=Buffer.from(t).toString("base64");return`data:${e.headers.get("content-type")||"image/png"};base64,${n}`}{const t=await e.blob();return new Promise((e,n)=>{const o=new FileReader;o.onloadend=()=>e(o.result),o.onerror=n,o.readAsDataURL(t)})}}catch(e){return console.error("Error converting URL to data URL:",e),t}},j=async({element:t,page:e,store:n})=>{let{src:r}=t;if("svg"===t.type){const e=await i.urlToString(r);r=i.replaceColors(e,new Map(Object.entries(t.colorsReplace)))}else{r=await S(r)}let l,s,a,h,c="";if(t.flipX||t.flipY){const e=t.flipX?-1:1,n=t.flipY?-1:1,o=t.width/2,i=t.height/2;c=`translate(${o}, ${i}) scale(${e}, ${n}) translate(${-o}, ${-i})`}t.clipSrc&&(l=`clip-img-mask-${t.id}`,s=await S(t.clipSrc)),t.maskSrc&&(a=`mask-img-${t.id}`,h=await S(t.maskSrc));const d=await o(r),f=d.width*t.cropWidth,g=d.height*t.cropHeight,p=t.width/t.height;let m,y;const x=f/g,k="boolean"==typeof t.stretchEnabled&&t.stretchEnabled||"svg"===t.type;k?(m=f,y=g):p>=x?(m=f,y=f/p):(m=g*p,y=g);const w=m/d.width,b=y/d.height,j=m/y>t.width/t.height?t.height/y:t.width/m,O=k?t.width/m:j,H=k?t.height/y:j,W=m*O/w,z=y*H/b;let M=t.cropX*d.width*O,L=t.cropY*d.height*H;t.flipX&&(M=(1-t.cropX-t.cropWidth)*d.width*O),t.flipY&&(L=(1-t.cropY-t.cropHeight)*d.height*H);const E=`clip-${t.id}`,F=t.cornerRadius||0,T=r.replace(/&/g,"&amp;"),C={x:-M,y:-L,width:W,height:z,preserveAspectRatio:"none","clip-path":`url(#${E})`},A=[$("clipPath",{id:E},$("rect",{x:0,y:0,width:t.width,height:t.height,rx:F||void 0,ry:F||void 0}))];l&&s&&A.push($("mask",{id:l,maskUnits:"userSpaceOnUse","mask-type":"alpha"},$("image",{href:s.replace(/&/g,"&amp;"),x:0,y:0,width:t.width,height:t.height,preserveAspectRatio:"none"}))),a&&A.push($("mask",{id:a,maskUnits:"userSpaceOnUse","mask-type":"alpha"},$("image",Object.assign({href:T},C))));let B=T;const R={};a&&h&&(B=h.replace(/&/g,"&amp;"),R.mask=`url(#${a})`);const P={};l&&(P.mask=`url(#${l})`);const D=t.borderSize||0,N=D>0&&u.isGradient(t.borderColor),U=N?`border-grad-${t.id}`:null;if(N){const e=v(t.borderColor,U);e&&A.push(e)}const G=D>0?$("rect",{x:D/2,y:D/2,width:Math.max(0,t.width-D),height:Math.max(0,t.height-D),fill:"none",stroke:N?`url(#${U})`:t.borderColor,"stroke-width":D,rx:Math.max(0,F-D)||void 0,ry:Math.max(0,F-D)||void 0}):null,I=$("g",{},$("defs",{},...A),$("image",Object.assign(Object.assign({href:B},C),R)),G);return $("g",P,c?$("g",{transform:c},I):I)},O=({element:t,type:e})=>{const n={"stroke-width":t.height,stroke:t.color,"stroke-linecap":"round","stroke-linejoin":"round"},o=Object.assign(Object.assign({},n),{fill:t.color}),i=Object.assign(Object.assign({},n),{fill:"none"});return"arrow"===e?$("polyline",Object.assign({points:`${3*t.height},${2*-t.height} 0,0 ${3*t.height},${2*t.height}`},i)):"triangle"===e?$("polygon",Object.assign({points:`${3*t.height},${2*-t.height} 0,0 ${3*t.height},${2*t.height}`},o)):"bar"===e?$("polyline",Object.assign({points:`0,${2*-t.height} 0,${2*t.height}`},i)):"circle"===e?$("circle",Object.assign({cx:2*t.height,cy:0,r:2*t.height},o)):"square"===e?$("polygon",Object.assign({points:`0,${2*-t.height} ${4*t.height},${2*-t.height} ${4*t.height},${2*t.height} 0,${2*t.height}`},o)):null},H={image:j,svg:j,text:async({element:t,page:e,store:n})=>{const o=u.isGradient(t.fill),i=u.isGradient(t.stroke);if(t.curveEnabled){const e=m(t.text,{fontSize:t.fontSize,fontFamily:t.fontFamily}),n=c(e,{fontSize:t.fontSize,fontFamily:t.fontFamily}),r=Math.max(t.fontSize,...n.map(e=>{var n;return null!==(n=e.fontSize)&&void 0!==n?n:t.fontSize})),l=p(t.width,t.height,t.curvePower,r),s=M(t.id||"temp"),a=`curve-path-${s}`,h={fontWeight:t.fontWeight||"normal",fontStyle:t.fontStyle||"normal",fill:t.fill||"black",fontFamily:t.fontFamily,fontSize:t.fontSize},g=d(n,h),u=d(n,h,{omitColors:!0}),y=t.backgroundPadding*(t.fontSize*t.lineHeight*.5),x=t.backgroundEnabled?$("rect",{x:-y,y:-y,width:t.width+2*y,height:t.height+2*y,fill:t.backgroundColor,opacity:t.backgroundOpacity,rx:t.backgroundCornerRadius*(t.fontSize*t.lineHeight*.5),ry:t.backgroundCornerRadius*(t.fontSize*t.lineHeight*.5)}):null,k=[$("path",{id:a,d:l,fill:"none"})],w=t.strokeWidth&&(i||o&&!i);if(o){const e=`curve-fill-grad-${s}`,n=v(t.fill,e);n&&k.push(n)}if(i&&t.strokeWidth){const e=`curve-stroke-grad-${s}`,n=v(t.stroke,e);n&&k.push(n)}if(w){const e={"font-size":t.fontSize+"px","text-anchor":"middle","dominant-baseline":"central","font-family":t.fontFamily,"font-style":t.fontStyle,"font-weight":t.fontWeight,"text-decoration":t.textDecoration||void 0,"letter-spacing":t.letterSpacing*r},n=i?`url(#curve-stroke-grad-${s})`:t.stroke,l=$("text",Object.assign(Object.assign({},e),{fill:n,"stroke-width":t.strokeWidth,stroke:n,"stroke-linejoin":f(t.strokeLineJoin)}),$("textPath",{href:`#${a}`,startOffset:"50%",innerHTML:u})),h=o?`url(#curve-fill-grad-${s})`:t.fill,c=$("text",Object.assign(Object.assign({},e),{fill:h}),$("textPath",{href:`#${a}`,startOffset:"50%",innerHTML:g}));return $("g",{},x,$("defs",{},...k),l,c)}return $("g",{},x,$("defs",{},...k),$("text",{fill:o?`url(#curve-fill-grad-${s})`:t.fill,"font-size":t.fontSize+"px","text-anchor":"middle","dominant-baseline":"central","font-family":t.fontFamily,"font-style":t.fontStyle,"font-weight":t.fontWeight,"text-decoration":t.textDecoration||void 0,"letter-spacing":t.letterSpacing*r,"stroke-width":t.strokeWidth||void 0,stroke:t.strokeWidth?i?`url(#curve-stroke-grad-${s})`:t.stroke:void 0,"stroke-linejoin":t.strokeWidth?f(t.strokeLineJoin):void 0,"paint-order":t.strokeWidth?"stroke fill":void 0},$("textPath",{href:`#${a}`,startOffset:"50%",innerHTML:g})))}let r=null;const l=()=>(r||(r=document.createElement("canvas").getContext("2d")),r),s=(t,e,n,o,i,r=0)=>{const s=l();return s.font=`${i} ${o} ${e}px ${n}`,s.measureText(t).width+Math.max(0,(t?t.length:0)-1)*r*e},a=(e,n,o)=>{let i=n;null!=e.fontSize&&e.fontSize!==t.fontSize&&t.fontSize>0&&(i=e.fontSize*(n/t.fontSize));const r=e.fontFamily||t.fontFamily,l=e.bold?"bold":t.fontWeight||"normal",a=e.italic?"italic":t.fontStyle||"normal";return s(e.text,i,r,l,a,o)},h=/<[a-z][\s\S]*>/i.test(t.text);let y=t.text;!h&&y.includes("\n")&&(y=y.split("\n").map(t=>`<p>${t}</p>`).join(""));const S=m(y,{fontSize:t.fontSize,fontFamily:t.fontFamily}),j={fontSize:t.fontSize,fontFamily:t.fontFamily},O=[],H=(new DOMParser).parseFromString(S,"text/html"),W=H.body.querySelectorAll("p");W.length>0?W.forEach((t,e)=>{const n=t.innerHTML,o=c(n,j);O.push(...o),e<W.length-1&&O.push({text:"\n"})}):O.push(...c(S,j)),"uppercase"===t.textTransform&&O.forEach(t=>{"\n"!==t.text&&(t.text=t.text.toUpperCase())});const z=t=>{const e=[];let n=[];for(const o of t){if("\n"===o.text){n.length>0&&(e.push(n),n=[]),e.push([Object.assign(Object.assign({},o),{text:"\n"})]);continue}const t=o.text.split(/( )/);for(const i of t){""!==i&&(" "===i?(n.length>0&&(e.push(n),n=[]),e.push([Object.assign(Object.assign({},o),{text:" "})])):n.push(Object.assign(Object.assign({},o),{text:i})))}}return n.length>0&&e.push(n),e},L=(t,e,n,o)=>{const i=[[]];let r=0;for(const l of t){if(1===l.length&&"\n"===l[0].text){i.push([]),r=0;continue}const t=l.reduce((t,e)=>t+a(e,n,o),0);1!==l.length||" "!==l[0].text?(r+t>e+.5&&i[i.length-1].length>0&&(i.push([]),r=0),i[i.length-1].push(...l),r+=t):r+t<=e+.5&&(i[i.length-1].push(...l),r+=t)}return i},E=(t,e,n)=>t.reduce((t,o)=>t+a(o,e,n),0),F=(t,e)=>1===e?t:t.map(t=>t.map(t=>t.fontSize?Object.assign(Object.assign({},t),{fontSize:Math.round(t.fontSize*e*1e3)/1e3}):t));if(H.body.querySelector("ul, ol")){const e=[],n=2.1,r=e=>{const n=e.cloneNode(!0);n.querySelectorAll("ul, ol").forEach(t=>t.remove());const o=c(n.innerHTML,j);return"uppercase"===t.textTransform&&o.forEach(t=>{"\n"!==t.text&&(t.text=t.text.toUpperCase())}),o},a=(t,n)=>{for(const o of Array.from(t.children)){const t=o.tagName.toLowerCase();if("ul"===t||"ol"===t){const i="ol"===t;let l=parseInt(o.getAttribute("start")||"1",10)||1;for(const t of Array.from(o.children)){if("li"!==t.tagName.toLowerCase()){continue}const o=t.getAttribute("value");o&&!Number.isNaN(parseInt(o,10))&&(l=parseInt(o,10));const s=i?{text:`${l}.`,isOrdered:!0}:{text:"•",isOrdered:!1};e.push({segments:r(t),depth:n+1,marker:s}),i&&(l+=1),a(t,n+1)}}else{"p"===t||"div"===t?e.push({segments:r(o),depth:0,marker:null}):e.push({segments:c(o.outerHTML,j),depth:0,marker:null})}}};a(H.body,0);const h=o=>{const i=[],r=[];for(const l of e){const e=l.depth*n*o,s=Math.max(1,t.width-e);(0===l.segments.length?[[]]:L(z(l.segments),s,o,t.letterSpacing)).forEach((t,n)=>{i.push(t),r.push({indent:e,marker:0===n?l.marker:null})})}return{L:i,M:r}};let p=t.fontSize,u=[],m=[];for(;;){const e=h(p);u=e.L,m=e.M;const n=Math.max(0,...u.map((e,n)=>m[n].indent+E(e,p,t.letterSpacing))),o=u.length*p*t.lineHeight;if(n<=t.width&&(!t.height||o<=t.height)){break}if(p-=1,p<4){break}}u=F(u,p/t.fontSize);const y=p*t.lineHeight,b=u.length*y;let S=0;"middle"===t.verticalAlign?S=(t.height-b)/2:"bottom"===t.verticalAlign&&(S=t.height-b);const O=p+S,W={fontWeight:t.fontWeight||"normal",fontStyle:t.fontStyle||"normal",fill:t.fill||"black",fontFamily:t.fontFamily,fontSize:p},M=t=>{let e=t.length;for(;e>0&&""===t[e-1].text.trim();){e--}return t.slice(0,e)},T=l(),C=t.fontWeight||"normal",A=t.fontStyle||"normal";T.font=`${A} ${C} ${p}px ${t.fontFamily}`;const B=T.measureText(" ").width,R=m.map((e,n)=>{var o,i,r,l,a;if(!e.marker){return null}const h=O+n*y;let c;if(e.marker.isOrdered){const n=s(e.marker.text,p,t.fontFamily,C,A,t.letterSpacing);c=k(e.indent,h,{markerWidth:n,spaceWidth:B})}else{const t=T.measureText(e.marker.text);c=x(e.indent,h,{ascent:null!==(i=null!==(o=t.fontBoundingBoxAscent)&&void 0!==o?o:t.actualBoundingBoxAscent)&&void 0!==i?i:.8*p,inkRight:null!==(r=t.actualBoundingBoxRight)&&void 0!==r?r:0,inkAscent:null!==(l=t.actualBoundingBoxAscent)&&void 0!==l?l:0,inkDescent:null!==(a=t.actualBoundingBoxDescent)&&void 0!==a?a:0})}return $("tspan",{x:c.x,y:c.y,"letter-spacing":e.marker.isOrdered?t.letterSpacing*p+"px":void 0,innerHTML:g(e.marker.text)})}),P=t=>{const e=[];return u.forEach((n,o)=>{const i=M(n);i.length>0&&e.push($("tspan",{x:m[o].indent,y:O+o*y,innerHTML:d(i,W,{omitColors:t})})),R[o]&&e.push(R[o])}),e};let D=null;if(t.backgroundEnabled){const e=t.backgroundPadding*(p*t.lineHeight*.5),n=t.backgroundCornerRadius*(p*t.lineHeight*.5);if(t.legacyBackground){D=$("rect",{x:-e,y:-e,width:t.width+2*e,height:t.height+2*e,fill:t.backgroundColor,opacity:t.backgroundOpacity,rx:n,ry:n})}else{const o=u.map((e,n)=>{const o=e.length?E(e,p,t.letterSpacing):0,i=n*y;return{left:m[n].indent,right:m[n].indent+o,top:i,bottom:i+y}}).filter(t=>t.right>t.left),i=w({rects:o,padding:e,cornerRadius:n});i&&(D=$("path",{d:i,fill:t.backgroundColor,opacity:t.backgroundOpacity,transform:S?`translate(0,${S})`:void 0}))}}const N=[];if(o){const e=v(t.fill,`text-fill-grad-${t.id}`);e&&N.push(e)}if(i&&t.strokeWidth){const e=v(t.stroke,`text-stroke-grad-${t.id}`);e&&N.push(e)}const U=t.strokeWidth&&(i||o&&!i),G={"font-size":p+"px","text-anchor":"start","font-family":t.fontFamily,"font-style":t.fontStyle,"font-weight":t.fontWeight,"text-decoration":t.textDecoration,"letter-spacing":t.letterSpacing*p+"px"};if(U){const e=P(!0),n=i?`url(#text-stroke-grad-${t.id})`:t.stroke,r=$("text",Object.assign(Object.assign({},G),{fill:n,"stroke-width":t.strokeWidth,stroke:n,"stroke-linejoin":f(t.strokeLineJoin)}),...e.map(t=>$("tspan",t.props,t.props.innerHTML))),l=o?`url(#text-fill-grad-${t.id})`:t.fill,s=o?e:P(!1),a=$("text",Object.assign(Object.assign({},G),{fill:l}),...s.map(t=>$("tspan",t.props,t.props.innerHTML)));return $("g",{},D,N.length>0?$("defs",{},...N):null,r,a)}return $("g",{},D,N.length>0?$("defs",{},...N):null,$("text",Object.assign(Object.assign({},G),{fill:o?`url(#text-fill-grad-${t.id})`:t.fill,"stroke-width":t.strokeWidth||void 0,stroke:t.strokeWidth?t.stroke:void 0,"stroke-linejoin":t.strokeWidth?f(t.strokeLineJoin):void 0,"paint-order":t.strokeWidth?"stroke fill":void 0}),...P(!1)))}let T=t.fontSize;const C=z(O);let A=[];for(;;){A=L(C,t.width,T,t.letterSpacing);const e=Math.max(...A.map(e=>E(e,T,t.letterSpacing)),0),n=A.length*T*t.lineHeight;if(e<=t.width&&n<=t.height){break}if(T-=1,T<4){break}}A=F(A,T/t.fontSize);const B=T*t.lineHeight,R=A.length*B;let P=T;"middle"===t.verticalAlign?P=(t.height-R)/2+T:"bottom"===t.verticalAlign&&(P=t.height-R+T);const D="center"===t.align?"middle":"right"===t.align?"end":"start",N={fontWeight:t.fontWeight||"normal",fontStyle:t.fontStyle||"normal",fill:t.fill||"black",fontFamily:t.fontFamily,fontSize:T},U="center"===t.align?t.width/2:"right"===t.align?t.width:0,G=t=>{let e=t.length;for(;e>0&&""===t[e-1].text.trim();){e--}return t.slice(0,e)},I=A.map((t,e)=>{const n=G(t),o=0===n.length?"​":d(n,N);return $("tspan",{x:U,dy:0===e?0:B,innerHTML:o})}),X=t.backgroundPadding*(T*t.lineHeight*.5),J=t.backgroundCornerRadius*(T*t.lineHeight*.5);let Y=null;if(t.backgroundEnabled){if(t.legacyBackground){Y=$("rect",{x:-X,y:-X,width:t.width+2*X,height:t.height+2*X,fill:t.backgroundColor,opacity:t.backgroundOpacity,rx:J,ry:J})}else{const e=b({lines:A.map(e=>({width:0===e.length?0:E(e,T,t.letterSpacing)})),lineHeight:B,width:t.width,align:"justify"===t.align?"justify":t.align});let n=0;"middle"===t.verticalAlign?n=(t.height-A.length*B)/2:"bottom"===t.verticalAlign&&(n=t.height-A.length*B);const o=w({rects:e,padding:X,cornerRadius:J});o&&(Y=$("path",{d:o,fill:t.backgroundColor,opacity:t.backgroundOpacity,transform:n?`translate(0,${n})`:void 0}))}}const q=[],V=t.strokeWidth&&(i||o&&!i);if(o){const e=`text-fill-grad-${t.id}`,n=v(t.fill,e);n&&q.push(n)}if(i&&t.strokeWidth){const e=`text-stroke-grad-${t.id}`,n=v(t.stroke,e);n&&q.push(n)}if(V){const e=A.map((t,e)=>{const n=G(t),o=d(n,N,{omitColors:!0});return $("tspan",{x:U,dy:0===e?0:B,innerHTML:o})}),n={y:P,"font-size":T+"px","text-anchor":D,"font-family":t.fontFamily,"font-style":t.fontStyle,"font-weight":t.fontWeight,"text-decoration":t.textDecoration,"letter-spacing":t.letterSpacing*T+"px"},r=i?`url(#text-stroke-grad-${t.id})`:t.stroke,l=$("text",Object.assign(Object.assign({},n),{fill:r,"stroke-width":t.strokeWidth,stroke:r,"stroke-linejoin":f(t.strokeLineJoin)}),...e.map(t=>$("tspan",t.props,t.props.innerHTML))),s=o?`url(#text-fill-grad-${t.id})`:t.fill,a=o?e:I,h=$("text",Object.assign(Object.assign({},n),{fill:s}),...a.map(t=>$("tspan",t.props,t.props.innerHTML)));return $("g",{},Y,q.length>0?$("defs",{},...q):null,l,h)}return $("g",{},Y,q.length>0?$("defs",{},...q):null,$("text",{fill:o?`url(#text-fill-grad-${t.id})`:t.fill,y:P,"font-size":T+"px","text-anchor":D,"font-family":t.fontFamily,"font-style":t.fontStyle,"font-weight":t.fontWeight,"text-decoration":t.textDecoration,"letter-spacing":t.letterSpacing*T+"px","stroke-width":t.strokeWidth||void 0,stroke:t.strokeWidth?t.stroke:void 0,"stroke-linejoin":t.strokeWidth?f(t.strokeLineJoin):void 0,"paint-order":t.strokeWidth?"stroke fill":void 0},...I))},line:async({element:t,page:e,store:n})=>$("g",{},$("line",{x1:0,y1:t.height/2,x2:t.width,y2:t.height/2,stroke:t.color,"stroke-width":t.height,"stroke-dasharray":t.dash&&t.dash.length?t.dash.map(e=>e*t.height).join(" "):void 0}),$("g",{transform:`translate(0 ${t.height/2})`},O({element:t,type:t.startHead})),$("g",{transform:`translate(${t.width} ${t.height/2}) rotate(180)`},O({element:t,type:t.endHead}))),figure:async({element:t,page:e,store:n,elementHook:o})=>{let i=function(t){let e=t.replace(/<svg[^>]*>/,"");return e=e.replace(/<\/svg>/,""),e}(r(t));const l=[];if(t.strokeWidth&&u.isGradient(t.stroke)){const e=`figure-stroke-grad-${t.id}`,n=v(t.stroke,e);if(n){l.push(n);const o=t.stroke.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");i=i.replace(new RegExp(`stroke="${o}"`,"g"),`stroke="url(#${e})"`)}}if(u.isGradient(t.fill)){const e=`figure-fill-grad-${t.id}`,n=v(t.fill,e);if(n){l.push(n);const o=t.fill.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");i=i.replace(new RegExp(`fill="${o}"`,"g"),`fill="url(#${e})"`)}}if(l.length>0){const e=$("g",{},$("defs",{},...l),$("g",{innerHTML:i}));return o&&o({dom:e,element:t})||e}const s=$("g",{innerHTML:i});return o&&o({dom:s,element:t})||s},group:async({element:t,page:e,store:n,elementHook:o})=>{const i=await Promise.all(t.children.map(t=>W({element:t,page:e,store:n,elementHook:o}))),r=$("g",{style:{"transform-origin":"top left"}},...i);return o&&o({dom:r,element:t})||r},gif:j,table:async({element:t})=>{t.rows;const e=t.cols,n=t.colWidths,o=t.rowHeights,i=["fontSize","fontFamily","fontWeight","fontStyle","textDecoration","textTransform","fill","align","verticalAlign","lineHeight","letterSpacing","strokeWidth","stroke","cellBackground","cellPadding"],r=(t.cells||[]).map((n,o)=>{const r=Object.assign(Object.assign({},n),{row:Math.floor(o/e),col:o%e});for(const e of i){void 0===r[e]&&(r[e]=t[e])}return r}),l=[],s=(e,i,r,l)=>{let s=0;for(let o=0;o<i;o++){s+=n[o]*t.width}let a=0;for(let n=0;n<e;n++){a+=o[n]*t.height}let h=0;for(let o=i;o<i+l;o++){h+=(n[o]||0)*t.width}let c=0;for(let n=e;n<e+r;n++){c+=(o[n]||0)*t.height}return{x:s,y:a,width:h,height:c}};for(const h of r){if(!h.mergedInto&&h.cellBackground&&"transparent"!==h.cellBackground){s(h.row,h.col,h.colSpan||1,h.colSpan||1);const{x:t,y:e,width:n,height:o}=s(h.row,h.col,h.rowSpan||1,h.colSpan||1);l.push($("rect",{x:t,y:e,width:n,height:o,fill:h.cellBackground}))}}const a=(t,e)=>"dashed"===t?`${4*e},${2*e}`:"dotted"===t?`${e},${e}`:void 0,c=(e,n)=>{var o,i,r,l,s;const a=null===(o=e.borders)||void 0===o?void 0:o[n];return{width:null!==(i=null==a?void 0:a.width)&&void 0!==i?i:t.borderWidth,style:null!==(l=null!==(r=null==a?void 0:a.style)&&void 0!==r?r:t.borderStyle)&&void 0!==l?l:"solid",color:null!==(s=null==a?void 0:a.color)&&void 0!==s?s:t.borderColor}};for(const h of r){if(h.mergedInto){continue}const t=s(h.row,h.col,h.rowSpan||1,h.colSpan||1);if(0===h.row){const e=c(h,"top");"none"!==e.style&&e.width>0&&l.push($("line",{x1:t.x,y1:t.y+e.width/2,x2:t.x+t.width,y2:t.y+e.width/2,stroke:e.color,"stroke-width":e.width,"stroke-dasharray":a(e.style,e.width)}))}if(0===h.col){const e=c(h,"left");"none"!==e.style&&e.width>0&&l.push($("line",{x1:t.x+e.width/2,y1:t.y,x2:t.x+e.width/2,y2:t.y+t.height,stroke:e.color,"stroke-width":e.width,"stroke-dasharray":a(e.style,e.width)}))}{const e=c(h,"bottom");"none"!==e.style&&e.width>0&&l.push($("line",{x1:t.x,y1:t.y+t.height-e.width/2,x2:t.x+t.width,y2:t.y+t.height-e.width/2,stroke:e.color,"stroke-width":e.width,"stroke-dasharray":a(e.style,e.width)}))}{const e=c(h,"right");"none"!==e.style&&e.width>0&&l.push($("line",{x1:t.x+t.width-e.width/2,y1:t.y,x2:t.x+t.width-e.width/2,y2:t.y+t.height,stroke:e.color,"stroke-width":e.width,"stroke-dasharray":a(e.style,e.width)}))}}for(const d of r){if(d.mergedInto){continue}let e=h(d.text||"");if(!e){continue}"uppercase"===d.textTransform&&(e=e.toUpperCase());const i=d.cellPadding||4;let r=0;for(let o=0;o<d.col;o++){r+=n[o]*t.width}let s=0;for(let n=0;n<d.row;n++){s+=o[n]*t.height}const a=n[d.col]*t.width,c=o[d.row]*t.height,f=d.fontSize||12,p=d.align||"left";let u=r+i,m="start";"center"===p?(u=r+a/2,m="middle"):"right"===p&&(u=r+a-i,m="end");let y=s+i+f;const x=d.verticalAlign||"top";"middle"===x?y=s+c/2+f/3:"bottom"===x&&(y=s+c-i),l.push($("text",{x:u,y,"font-size":f,"font-family":d.fontFamily||"Roboto","font-weight":d.fontWeight||"normal","font-style":d.fontStyle||"normal",fill:d.fill||"black","text-anchor":m,"text-decoration":d.textDecoration||"none","letter-spacing":d.letterSpacing?d.letterSpacing*f+"px":void 0},g(e)))}return $("g",{},...l)}};async function W({element:t,page:e,store:n,elementHook:o}){var i;let r=await H[t.type];r||(r=()=>$("g",{}),console.error(`SVG export does not support ${t.type} type...`));const h=await r({element:t,page:e,store:n}),c=[],d=[];if(t.blurEnabled&&c.push(`blur(${a(t)/2}px)`),t.brightnessEnabled&&c.push(`brightness(${100*t.brightness+100}%)`),t.sepiaEnabled&&c.push("sepia()"),t.grayscaleEnabled&&c.push("grayscale()"),t.shadowEnabled&&c.push(`drop-shadow(${t.shadowOffsetX}px ${t.shadowOffsetY}px ${t.shadowBlur}px ${t.shadowColor})`),t.filters){for(const[a,g]of Object.entries(t.filters)){const t=s(l[a],g.intensity);if(t&&(c.push(t.filter),t.html)){const e=t.html.replace(/<svg([^>]*)>/,"<g$1>").replace(/<\/svg>/,"</g>");d.push(e)}}}const f=$("g",{className:"element",id:t.id,transform:"group"!==t.type?`translate(${t.x}, ${t.y}) rotate(${t.rotation})`:void 0,display:null===(i=t.visible)||void 0===i||i?void 0:"none",opacity:t.opacity,style:{"transform-origin":"top left",filter:c.join(" ")}},h,...d);return o&&o({dom:f,element:t})||f}async function z(t){try{const e=await fetch(t),n=e.headers.get("content-type")||"font/ttf",o=await e.arrayBuffer();return`data:${n};base64,${"undefined"!=typeof Buffer?Buffer.from(o).toString("base64"):function(t){const e=new Uint8Array(t);let n="";for(let o=0;o<e.length;o+=32768){const t=e.subarray(o,o+32768);n+=String.fromCharCode(...t)}if("undefined"!=typeof btoa){return btoa(n)}if("undefined"!=typeof Buffer){return Buffer.from(e).toString("base64")}throw new Error("No base64 encoder available in this environment")}(o)}`}catch(e){return console.error("Error embedding font:",e),t}}export async function jsonToDOM({json:t,elementHook:i,fontEmbedding:r="inline"}){const l=[];forEveryNode({children:t.pages},t=>{if(("text"===t.type||"tablecell"===t.type||"table"===t.type)&&(t.fontFamily&&-1===l.indexOf(t.fontFamily)&&l.push(t.fontFamily),t.text)){for(const e of y(t.text)){-1===l.indexOf(e)&&l.push(e)}}});const s="inline"===r?await async function(t,e){return await Promise.all(t.map(async t=>{var n,o;if("Arial"===t){return null}const i=e.find(e=>e.fontFamily===t);if(i){const e=i.styles||(i.url?[{src:`url("${i.url}")`,fontStyle:"normal",fontWeight:"normal"}]:[]),n=await Promise.all(e.map(async e=>{var n,o;const r=(null===(o=null===(n=e.src)||void 0===n?void 0:n.match(/url\("?(.*?)"?\)/))||void 0===o?void 0:o[1])||i.url,l=await z(r);return`@font-face {\n font-family: '${t}';\n font-style: ${e.fontStyle||"normal"};\n font-weight: ${e.fontWeight||"normal"};\n src: url(${l});\n}`}));return $("style",{},n.join("\n"))}{const e=`https://fonts.googleapis.com/css?family=${encodeURIComponent(t)}:bi,normal,i,b`;try{const i=await fetch(e),r=await i.text(),l=null===(o=null===(n=r.match(/url\((.*?)\)/g))||void 0===n?void 0:n.map(t=>t.replace(/url\((.*?)\)/,"$1")))||void 0===o?void 0:o.filter(t=>t.startsWith("https"));if(!(null==l?void 0:l.length)){throw new Error("No font URLs found")}const s=await Promise.all(l.map(async e=>{const n=await z(e),o=(r.match(/@font-face\s*\{[^}]*?\}/g)||[]).find(t=>t.includes(e))||"",i=o.match(/font-style:\s*(.*?)[;\s}]/),l=o.match(/font-weight:\s*(.*?)[;\s}]/),s=i?i[1].trim():"normal",a=l?l[1].trim():"normal";return`@font-face {\n font-family: '${t}';\n font-style: ${s};\n font-weight: ${a};\n src: url(${n});\n}`}));return $("style",{},s.join("\n"))}catch(r){return console.error("Error embedding Google Font:",r),$("defs",{},$("style",{type:"text/css",innerHTML:`@import url('${e}');`.replace(/&/g,"&amp;")}))}}}))}(l,t.fonts):[],a=await Promise.all(t.pages.map(r=>async function({page:t,store:i,elementHook:r}){const l=[...t.children.filter(t=>!t.alwaysOnTop),...t.children.filter(t=>t.alwaysOnTop)],s=await Promise.all(l.map(e=>W({element:e,page:t,store:i,elementHook:r}))),a=t.background.indexOf("url")>=0||t.background.indexOf("http")>=0||t.background.indexOf(".jpg")>=0||t.background.indexOf(".png")>=0||t.background.indexOf(".jpeg")>=0;let h;if(a){const r=await o(t.background);h=await e(t.background,Object.assign({width:i.width,height:i.height,x:0,y:0},n({width:i.width,height:i.height},{width:r.width,height:r.height})))}return $("g",{className:"page",style:{}},a?$("image",{"xlink:href":h,x:0,y:0,width:i.width,height:i.height,preserveAspectRatio:"none"}):$("rect",{x:0,y:0,width:i.width,height:i.height,fill:a?void 0:t.background}),...s)}({page:r,store:t,elementHook:i})));return $("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink",viewBox:`0 0 ${t.width} ${t.height}`,width:t.width,height:t.height},...s,...a)}function M(t){return String(t).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}const L=({dom:e,nestLevel:n=0})=>{if("string"==typeof e){return e}if(!e){return""}const o=e.props,{innerHTML:i}=o,r=t(o,["innerHTML"]),l=Object.keys(r).map(t=>((t,e)=>"object"==typeof e?`${t}="${Object.keys(e).map(t=>`${t}:${e[t]};`).join(" ")}"`:null==e||""===e?"":`${t}="${M(String(e))}"`)(t,r[t])).filter(t=>t&&t.trim().length>0).join(" "),s=" ".repeat(n);return`${s}<${e.type}${l?" "+l:""}>${i||"\n"+e.children.map(t=>L({dom:t,nestLevel:n+1})).join("")}${s}</${e.type}>\n`};export async function jsonToSVG({json:t,elementHook:e,fontEmbedding:n="inline"}){const o=await jsonToDOM({json:t,elementHook:e,fontEmbedding:n});return L({dom:o})}
@@ -1 +1 @@
1
- import*as e from"mobx";import{getAPI as o}from"./api.js";import{setRemoveBackgroundEnabled as t}from"./flags.js";const n=e.observable({value:!1}),a=e.observable({value:"v1"});export const ___=()=>a.value;const i=e.observable({value:0});export const ____=()=>i.value;export const isCreditVisible=()=>n.value;const r=e.action(()=>{n.value=!0});let s="";export const getKey=()=>s||"";export const setKey=e=>{s=e||""};let l="undefined"!=typeof window?window.location.origin:"";const c="undefined"!=typeof navigator&&navigator.userAgent.indexOf("Headless")>-1,d="undefined"!=typeof navigator&&navigator.userAgent.indexOf("Electron")>-1;"file://"===l&&c&&(l="headless"),"file://"===l&&d&&(l="electron");const p=`%cPolotno error! Current domain is not allowed. It may lead to unexpected behavior and stop working. Please add "${l}" here: https://polotno.com/cabinet`;let u=fetch;export const __=e=>{u=e};export async function isKeyPaid(n){for(let s=0;s<5;s++){try{const r=await u(o()+"/validate-key",{method:"POST",body:JSON.stringify({key:n,site:location.host,skdVersion:"4.2.1"})});if(e.runInAction(()=>{a.value=r.headers.get("x-api-version")||""}),!n){return console.error("Polotno API is initialized without API key. It may lead to unexpected behavior and stop working. Please create API key here: https://polotno.com/cabinet"),e.runInAction(()=>{i.value=1}),!1}if(200!==r.status){await new Promise(e=>setTimeout(e,3e3));continue}const s=await r.json();return s.is_valid||(console.error("Polotno API key is not valid. Please get new API key here: https://polotno.com/cabinet"),e.runInAction(()=>{i.value=1})),s.is_paid||(console.log("%cPolotno Free Version. For development usage only. https://polotno.com/","background: rgb(0, 161, 255); color: white; padding: 5px; margin: 5px;"),e.runInAction(()=>{0===i.value&&(i.value=2)})),s.is_domain_valid||console.log(p,"background: rgba(247, 101, 68, 1); color: white; padding: 5px; margin: 5px;"),t(s.remove_background_enabled),s.is_paid||!1}catch(r){await new Promise(e=>setTimeout(e,3e3))}}return console.error("Can not validate Polotno API key. Please report to anton@polotno.com immediately."),!0}export async function validateKey(e){await isKeyPaid(s)&&!e||r()}
1
+ import*as e from"mobx";import{getAPI as o}from"./api.js";import{setRemoveBackgroundEnabled as t}from"./flags.js";const n=e.observable({value:!1}),a=e.observable({value:"v1"});export const ___=()=>a.value;const i=e.observable({value:0});export const ____=()=>i.value;export const isCreditVisible=()=>n.value;const r=e.action(()=>{n.value=!0});let s="";export const getKey=()=>s||"";export const setKey=e=>{s=e||""};let l="undefined"!=typeof window?window.location.origin:"";const c="undefined"!=typeof navigator&&navigator.userAgent.indexOf("Headless")>-1,d="undefined"!=typeof navigator&&navigator.userAgent.indexOf("Electron")>-1;"file://"===l&&c&&(l="headless"),"file://"===l&&d&&(l="electron");const p=`%cPolotno error! Current domain is not allowed. It may lead to unexpected behavior and stop working. Please add "${l}" here: https://polotno.com/cabinet`;let u=fetch;export const __=e=>{u=e};export async function isKeyPaid(n){for(let s=0;s<5;s++){try{const r=await u(o()+"/validate-key",{method:"POST",body:JSON.stringify({key:n,site:location.host,skdVersion:"4.3.0"})});if(e.runInAction(()=>{a.value=r.headers.get("x-api-version")||""}),!n){return console.error("Polotno API is initialized without API key. It may lead to unexpected behavior and stop working. Please create API key here: https://polotno.com/cabinet"),e.runInAction(()=>{i.value=1}),!1}if(200!==r.status){await new Promise(e=>setTimeout(e,3e3));continue}const s=await r.json();return s.is_valid||(console.error("Polotno API key is not valid. Please get new API key here: https://polotno.com/cabinet"),e.runInAction(()=>{i.value=1})),s.is_paid||(console.log("%cPolotno Free Version. For development usage only. https://polotno.com/","background: rgb(0, 161, 255); color: white; padding: 5px; margin: 5px;"),e.runInAction(()=>{0===i.value&&(i.value=2)})),s.is_domain_valid||console.log(p,"background: rgba(247, 101, 68, 1); color: white; padding: 5px; margin: 5px;"),t(s.remove_background_enabled),s.is_paid||!1}catch(r){await new Promise(e=>setTimeout(e,3e3))}}return console.error("Can not validate Polotno API key. Please report to anton@polotno.com immediately."),!0}export async function validateKey(e){await isKeyPaid(s)&&!e||r()}
package/utils/video.js CHANGED
@@ -1 +1 @@
1
- export async function getVideoSize(e){return new Promise((t,n)=>{const r=document.createElement("video");r.crossOrigin="anonymous",r.src=e,r.addEventListener("loadedmetadata",()=>{const{videoWidth:e,videoHeight:n}=r;t({width:e,height:n})}),r.addEventListener("error",t=>{const r=e.slice(0,100);n(new Error(`Failed to load video: ${r}`))})})}export async function getVideoDuration(e){return new Promise(t=>{const n=document.createElement("video");n.crossOrigin="anonymous",n.src=e,n.addEventListener("loadedmetadata",()=>{const{duration:e}=n;t(e)})})}export async function getVideoPreview(e,t=5){return new Promise((n,r)=>{var o=document.createElement("video"),i=document.createElement("canvas");i.width=480,i.height=360;var d=i.getContext("2d");o.crossOrigin="anonymous",o.src=e,o.addEventListener("error",e=>{r(e)}),o.addEventListener("loadeddata",function(){const e=o.videoWidth/o.videoHeight;i.width=480,i.height=480/e,o.currentTime=t}),o.addEventListener("seeked",function(){d.drawImage(o,0,0,i.width,i.height);try{var e=i.toDataURL();n(e)}catch(t){r(t)}})})}export async function getVideoObjectPreview(e,t,n){return new Promise((r,o)=>{const i=t.getContext("2d"),d=()=>{try{i.drawImage(e,0,0,t.width,t.height);const n=t.toDataURL();r(n),e.removeEventListener("seeked",d)}catch(n){o(n),e.removeEventListener("seeked",d)}};e.addEventListener("seeked",d),e.currentTime=n})}
1
+ import{polotnoError as e}from"./errors.js";export async function getVideoSize(t){return new Promise((n,o)=>{const r=document.createElement("video");r.crossOrigin="anonymous",r.src=t,r.addEventListener("loadedmetadata",()=>{const{videoWidth:e,videoHeight:t}=r;n({width:e,height:t})}),r.addEventListener("error",n=>{const r=t.slice(0,100);o(e("VIDEO_FAILED",`Failed to load video: ${r}`,{src:r,reason:"load"}))})})}export async function getVideoDuration(e){return new Promise(t=>{const n=document.createElement("video");n.crossOrigin="anonymous",n.src=e,n.addEventListener("loadedmetadata",()=>{const{duration:e}=n;t(e)})})}export async function getVideoPreview(t,n=5){return new Promise((o,r)=>{var i=document.createElement("video"),d=document.createElement("canvas");d.width=480,d.height=360;var a=d.getContext("2d");i.crossOrigin="anonymous",i.src=t,i.addEventListener("error",n=>{const o=String(t).slice(0,100);r(e("VIDEO_FAILED",`Failed to load video: ${o}`,{src:o,reason:"load"},n))}),i.addEventListener("loadeddata",function(){const e=i.videoWidth/i.videoHeight;d.width=480,d.height=480/e,i.currentTime=n}),i.addEventListener("seeked",function(){a.drawImage(i,0,0,d.width,d.height);try{var e=d.toDataURL();o(e)}catch(t){r(t)}})})}export async function getVideoObjectPreview(e,t,n){return new Promise((o,r)=>{const i=t.getContext("2d"),d=()=>{try{i.drawImage(e,0,0,t.width,t.height);const n=t.toDataURL();o(n),e.removeEventListener("seeked",d)}catch(n){r(n),e.removeEventListener("seeked",d)}};e.addEventListener("seeked",d),e.currentTime=n})}