/**
 * Skipped minification because the original files appears to be already minified.
 * Original file: /npm/@yoopta/image@6.0.2/dist/index.js
 *
 * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
 */
import{jsx as e,jsxs as t}from"react/jsx-runtime";import{generateId as n,Blocks as r,Elements as o,YooptaPlugin as i}from"@yoopta/editor";import{useState as s,useRef as l,useCallback as a}from"react";const d={buildImageElements:(e,t={})=>{const r=Object.assign(Object.assign({},t.props),{nodeType:"void"});return{id:n(),type:"image",children:[{text:""}],props:r}},insertImage:(e,t={})=>{const{at:n,focus:o,props:i}=t,s=d.buildImageElements(e,{props:i}),l=r.buildBlockData({value:[s],type:"Image",meta:{align:"center",depth:0}});r.insertBlock(e,l.type,{focus:o,at:n,blockData:l})},deleteImage:(e,t)=>{r.deleteBlock(e,{blockId:t})},updateImage:(e,t,n)=>{o.updateElement(e,{blockId:t,type:"image",props:n})}},c=e=>e?"number"==typeof e?e:parseInt(e.replace(/[^\d]/g,""),10):0,u={left:"flex-start",center:"center",right:"flex-end"},p=new i({type:"Image",elements:e("image",{render:n=>{var r,o;return t("div",Object.assign({},n.attributes,{contentEditable:!1},{children:[e("img",{src:n.element.props.src,alt:n.element.props.alt,width:null===(r=n.element.props.sizes)||void 0===r?void 0:r.width,height:null===(o=n.element.props.sizes)||void 0===o?void 0:o.height,style:{objectFit:n.element.props.fit}}),n.children]}))},props:{id:null,src:null,alt:null,srcSet:null,bgColor:null,fit:null,sizes:{width:0,height:0}},nodeType:"void"}),commands:d,options:{display:{title:"Image",description:"Upload from device or insert with link"}},parsers:{html:{deserialize:{nodeNames:["IMG"],parse:(e,t)=>{var r,o,i;if("IMG"===e.nodeName){const s={width:e.getAttribute("width")?parseInt(e.getAttribute("width")||"650",10):650,height:e.getAttribute("height")?parseInt(e.getAttribute("height")||"500",10):500},l=null===(r=t.plugins.Image.options)||void 0===r?void 0:r.maxSizes,a=((e,t)=>{const n=c(e.width),r=c(e.height),o=c(null==t?void 0:t.width),i=c(null==t?void 0:t.height);if(n<=o&&r<=i)return{width:n,height:r};const s=n/o,l=r/i,a=Math.max(s,l),d=Math.round(n/a),u=Math.round(r/a);return{width:Math.min(d,o),height:Math.min(u,i)}})(s,{width:null!==(o=null==l?void 0:l.maxWidth)&&void 0!==o?o:0,height:null!==(i=null==l?void 0:l.maxHeight)&&void 0!==i?i:0}),d={id:n(),nodeType:"void",src:e.getAttribute("src")||"",alt:e.getAttribute("alt")||"",srcSet:e.getAttribute("srcset")||"",fit:e.getAttribute("objectFit")||"contain",sizes:a};return{id:n(),type:"image",children:[{text:""}],props:d}}}},serialize:(e,t,n)=>{const{align:r="center",depth:o=0}=n||{};return`<div style="margin-left: ${20*o}px; display: flex; width: 100%; justify-content: ${u[r]||"center"};">\n        <img data-meta-align="${r}" data-meta-depth="${o}" src="${e.props.src}" alt="${e.props.alt}" width="${e.props.sizes.width}" height="${e.props.sizes.height}" objectFit="${e.props.fit}"/>\n        </div>`}},markdown:{serialize:e=>`![${e.props.alt||e.id}](${e.props.src})\n`},email:{serialize:(e,t,n)=>{const{align:r="center",depth:o=0}=n||{};return`\n          <table style="width:100%;">\n            <tbody style="width:100%;">\n              <tr>\n                <td style="margin-left: ${20*o}px; display: flex; width: 100%; justify-content: ${u[r]||"center"}; margin-top: 1rem;">\n                    <img data-meta-align="${r}" style="margin: 0 auto; object-fit:${e.props.fit||"contain"};" data-meta-depth="${o}" src="${e.props.src}" alt="${e.props.alt}" width="${e.props.sizes.width}" height="${e.props.sizes.height}" />\n                </td>\n              </tr>\n            </tbody>\n          </table>\n        `}}}});function g(e,t,n,r){return new(n||(n=Promise))(function(o,i){function s(e){try{a(r.next(e))}catch(e){i(e)}}function l(e){try{a(r.throw(e))}catch(e){i(e)}}function a(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n(function(e){e(t)})).then(s,l)}a((r=r.apply(e,t||[])).next())})}"function"==typeof SuppressedError&&SuppressedError;const m=({onError:e,onSuccess:t,onProgress:n,accept:r,maxSize:o,method:i="POST",endpoint:d,headers:c})=>{const[u,p]=s({loading:!1,progress:null,error:null,result:null}),g=l(null),m=a(()=>{g.current&&(g.current.abort(),g.current=null)},[]),h=a(()=>{p({loading:!1,progress:null,error:null,result:null})},[]);return Object.assign(Object.assign({},u),{xhrFetch:s=>new Promise((l,a)=>{if(s instanceof File){const t=((e,t,n)=>{if(t&&!t.includes(e.type))return{message:`Invalid file type. Allowed types: ${t}`,code:"INVALID_TYPE"};if(n&&e.size>n)return{message:`File size exceeds ${(n/1024/1024).toFixed(2)}MB`,code:"FILE_TOO_LARGE"};return null})(s,r,o);if(t)return p(e=>Object.assign(Object.assign({},e),{error:t})),null==e||e(t),void a(t)}p({loading:!0,progress:{loaded:0,total:s instanceof File?s.size:0,percentage:0},error:null,result:null});const u=new XMLHttpRequest;g.current=u,u.upload.addEventListener("progress",e=>{if(e.lengthComputable){const t={loaded:e.loaded,total:e.total,percentage:Math.round(e.loaded/e.total*100)};p(e=>Object.assign(Object.assign({},e),{progress:t})),null==n||n(t)}}),u.addEventListener("load",()=>{if(u.status>=200&&u.status<300)try{const e=JSON.parse(u.responseText);p(t=>Object.assign(Object.assign({},t),{loading:!1,result:e})),null==t||t(e),l(e)}catch(t){const n={message:"Failed to parse server response",code:"PARSE_ERROR",status:u.status};p(e=>Object.assign(Object.assign({},e),{loading:!1,error:n})),null==e||e(n),a(n)}else{const t={message:`Upload failed with status ${u.status}`,code:"HTTP_ERROR",status:u.status};p(e=>Object.assign(Object.assign({},e),{loading:!1,error:t})),null==e||e(t),a(t)}}),u.addEventListener("error",()=>{const t={message:"Network error occurred",code:"NETWORK_ERROR"};p(e=>Object.assign(Object.assign({},e),{loading:!1,error:t})),null==e||e(t),a(t)}),u.addEventListener("abort",()=>{const e={message:"Upload cancelled",code:"ABORT"};p(t=>Object.assign(Object.assign({},t),{loading:!1,error:e})),a(e)}),u.addEventListener("timeout",()=>{const t={message:"Upload timeout",code:"TIMEOUT"};p(e=>Object.assign(Object.assign({},e),{loading:!1,error:t})),null==e||e(t),a(t)}),u.open(i,d),c&&Object.entries(c).forEach(([e,t])=>{u.setRequestHeader(e,t)}),u.timeout=3e4,u.send(s)}),cancel:m,reset:h})},h="https://docs.yoopta.dev/plugins/image",f=e=>{var t,n,r;const o=(e=>{if(null==e)return!1;if("function"!=typeof e&&"object"!=typeof e)throw new Error(`[Yoopta Image] Invalid delete options. Expected a function or endpoint configuration object.\n\nSee documentation: ${h}`);if("object"==typeof e&&!e.endpoint)throw new Error(`[Yoopta Image] Missing 'endpoint' in delete options. When using endpoint-based delete, you must provide an 'endpoint' URL.\n\nExample:\nImage.extend({\n  options: {\n    delete: {\n      endpoint: '/api/delete-image',\n    },\n  },\n})\n\nSee documentation: ${h}`);return!0})(e),i=o?e:null,l=!!i&&(e=>"function"==typeof e)(i),[d,c]=s({loading:!1,progress:null,error:null,result:null}),u=!i||l?{endpoint:""}:i,p=m({endpoint:u.endpoint,method:null!==(t=u.method)&&void 0!==t?t:"DELETE",headers:null!==(n=u.headers)&&void 0!==n?n:{},fieldName:null!==(r=u.fieldName)&&void 0!==r?r:"file",onSuccess:u.onSuccess,onError:u.onError,onProgress:u.onProgress}),f=a(e=>g(void 0,void 0,void 0,function*(){var t,n,r,o,s,a,d;if(!i){const i=null!==(n=null===(t=e.props)||void 0===t?void 0:t.src)&&void 0!==n?n:"";return{id:null!==(o=null===(r=e.props)||void 0===r?void 0:r.id)&&void 0!==o?o:"",url:i}}if(!l)throw new Error("Custom delete called but options is not a function");const u=null===(s=e.props)||void 0===s?void 0:s.src;if(!u)throw new Error("Image src is required");c(e=>Object.assign(Object.assign({},e),{loading:!0,error:null}));try{yield i(e);const t={id:null!==(d=null===(a=e.props)||void 0===a?void 0:a.id)&&void 0!==d?d:"",url:u};return c(e=>Object.assign(Object.assign({},e),{loading:!1,result:t})),t}catch(e){const t={message:e instanceof Error?e.message:"Delete failed",code:"CUSTOM_DELETE_ERROR"};throw c(e=>Object.assign(Object.assign({},e),{loading:!1,error:t})),t}}),[i,l]),b=a(()=>{c({loading:!1,progress:null,error:null,result:null})},[]),v=a(e=>{var t;const n=null===(t=e.props)||void 0===t?void 0:t.id;if(!n)throw new Error("FileId is required");return p.xhrFetch(JSON.stringify({fileId:n}))},[p]);return o?l?Object.assign(Object.assign({},d),{deleteImage:f,cancel:()=>{},reset:b}):{loading:p.loading,progress:p.progress,error:p.error,result:p.result,deleteImage:v,cancel:p.cancel,reset:p.reset}:Object.assign(Object.assign({},d),{deleteImage:f,cancel:()=>{},reset:b})},b=e=>{var t,n,r,o;(e=>{if(null==e)throw new Error(`[Yoopta Image] Upload options are not configured. Please provide 'upload' option when extending the Image plugin.\n\nExample:\nImage.extend({\n  options: {\n    upload: async (file) => {\n      // Upload file to your storage and return image props\n      return { id: '...', src: '...' };\n    },\n  },\n})\n\nSee documentation: ${h}`);if("function"!=typeof e&&"object"!=typeof e)throw new Error(`[Yoopta Image] Invalid upload options. Expected a function or endpoint configuration object.\n\nSee documentation: ${h}`);if("object"==typeof e&&!e.endpoint)throw new Error(`[Yoopta Image] Missing 'endpoint' in upload options. When using endpoint-based upload, you must provide an 'endpoint' URL.\n\nExample:\nImage.extend({\n  options: {\n    upload: {\n      endpoint: '/api/upload-image',\n    },\n  },\n})\n\nSee documentation: ${h}`)})(e);const i=e,l=(e=>"function"==typeof e)(i),[d,c]=s({loading:!1,progress:null,error:null,result:null}),u=l?{endpoint:""}:i,p=m({endpoint:u.endpoint,method:null!==(t=u.method)&&void 0!==t?t:"POST",headers:null!==(n=u.headers)&&void 0!==n?n:{},fieldName:null!==(r=u.fieldName)&&void 0!==r?r:"file",maxSize:u.maxSize,accept:null!==(o=u.accept)&&void 0!==o?o:"image/jpeg, image/jpg, image/png, image/gif, image/webp",onSuccess:u.onSuccess,onError:u.onError,onProgress:u.onProgress}),f=a(e=>g(void 0,void 0,void 0,function*(){var t,n,r,o;if(!l)throw new Error("Custom upload called but options is not a function");c(t=>Object.assign(Object.assign({},t),{loading:!0,progress:{loaded:0,total:e.size,percentage:0},error:null}));try{const s=e=>{c(t=>Object.assign(Object.assign({},t),{progress:e}))},l=yield i(e,s),a={id:null!==(t=l.id)&&void 0!==t?t:"",url:null!==(n=l.src)&&void 0!==n?n:"",width:"number"==typeof(null===(r=l.sizes)||void 0===r?void 0:r.width)?l.sizes.width:void 0,height:"number"==typeof(null===(o=l.sizes)||void 0===o?void 0:o.height)?l.sizes.height:void 0};return c(t=>Object.assign(Object.assign({},t),{loading:!1,progress:{loaded:e.size,total:e.size,percentage:100},result:a})),a}catch(e){const t={message:e instanceof Error?e.message:"Upload failed",code:"CUSTOM_UPLOAD_ERROR"};throw c(e=>Object.assign(Object.assign({},e),{loading:!1,error:t})),t}}),[i,l]),b=a(()=>{c({loading:!1,progress:null,error:null,result:null})},[]),v=a(e=>{var t;const n=new FormData;return n.append(null!==(t=u.fieldName)&&void 0!==t?t:"yoopta-image-file",e),p.xhrFetch(n)},[u.fieldName,p]);return l?Object.assign(Object.assign({},d),{upload:f,cancel:()=>{},reset:b}):{loading:p.loading,progress:p.progress,error:p.error,result:p.result,upload:v,cancel:p.cancel,reset:p.reset}},v=()=>({getDimensions:e=>new Promise((t,n)=>{const r=new Image,o=URL.createObjectURL(e);r.onload=()=>{URL.revokeObjectURL(o),t({width:r.naturalWidth,height:r.naturalHeight})},r.onerror=()=>{URL.revokeObjectURL(o),n(new Error("Failed to load image"))},r.src=o})}),O=()=>{const[e,t]=s(null),n=l(null);return{preview:e,generatePreview:e=>{n.current&&URL.revokeObjectURL(n.current.url);const r=URL.createObjectURL(e),o={url:r};return n.current=o,t(o),{url:r}},clearPreview:()=>{n.current&&(URL.revokeObjectURL(n.current.url),n.current=null,t(null))}}};export{d as ImageCommands,p as default,f as useImageDelete,v as useImageDimensions,O as useImagePreview,b as useImageUpload};
