ct-rich-text-editor 1.3.22 → 1.3.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/style.css +4 -0
- package/dist/{html2pdf.bundle-3699b235.js → html2pdf.bundle-33b132a6.js} +2 -2
- package/dist/{html2pdf.bundle-3699b235.js.map → html2pdf.bundle-33b132a6.js.map} +1 -1
- package/dist/{html2pdf.bundle.min-83517dc2.js → html2pdf.bundle.min-f3fd0aa5.js} +2 -2
- package/dist/{html2pdf.bundle.min-83517dc2.js.map → html2pdf.bundle.min-f3fd0aa5.js.map} +1 -1
- package/dist/{index-bf836d7a.js → index-b535466a.js} +2 -2
- package/dist/{index-bf836d7a.js.map → index-b535466a.js.map} +1 -1
- package/dist/{index-9a8a49b6.js → index-daaf2abc.js} +150 -83
- package/dist/index-daaf2abc.js.map +1 -0
- package/dist/{index-84187412.js → index-fbad5b49.js} +246 -204
- package/dist/index-fbad5b49.js.map +1 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/index-84187412.js.map +0 -1
- package/dist/index-9a8a49b6.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
3
3
|
import { $getNodeByKey } from "lexical";
|
|
4
|
-
import { a as createLucideIcon, D as Download, T as Trash2, $ as $isFileNode } from "./index-
|
|
4
|
+
import { a as createLucideIcon, D as Download, T as Trash2, $ as $isFileNode } from "./index-daaf2abc.js";
|
|
5
5
|
import "react";
|
|
6
6
|
import "axios";
|
|
7
7
|
import "@emotion/styled";
|
|
@@ -202,4 +202,4 @@ const FileView = ({ src, fileName, fileSize, nodeKey }) => {
|
|
|
202
202
|
export {
|
|
203
203
|
FileView as default
|
|
204
204
|
};
|
|
205
|
-
//# sourceMappingURL=index-
|
|
205
|
+
//# sourceMappingURL=index-b535466a.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-bf836d7a.js","sources":["../../../node_modules/lucide-react/dist/esm/icons/file-archive.js","../../../node_modules/lucide-react/dist/esm/icons/file-text.js","../../../node_modules/lucide-react/dist/esm/icons/file.js","../src/components/FileView/index.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.344.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FileArchive = createLucideIcon(\"FileArchive\", [\n [\"path\", { d: \"M16 22h2a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v18\", key: \"1oywqq\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }],\n [\"circle\", { cx: \"10\", cy: \"20\", r: \"2\", key: \"1xzdoj\" }],\n [\"path\", { d: \"M10 7V6\", key: \"dljcrl\" }],\n [\"path\", { d: \"M10 12v-1\", key: \"v7bkov\" }],\n [\"path\", { d: \"M10 18v-2\", key: \"1cjy8d\" }]\n]);\n\nexport { FileArchive as default };\n//# sourceMappingURL=file-archive.js.map\n","/**\n * @license lucide-react v0.344.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FileText = createLucideIcon(\"FileText\", [\n [\"path\", { d: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\", key: \"1rqfz7\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }],\n [\"path\", { d: \"M10 9H8\", key: \"b1mrlr\" }],\n [\"path\", { d: \"M16 13H8\", key: \"t4e002\" }],\n [\"path\", { d: \"M16 17H8\", key: \"z1uh3a\" }]\n]);\n\nexport { FileText as default };\n//# sourceMappingURL=file-text.js.map\n","/**\n * @license lucide-react v0.344.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst File = createLucideIcon(\"File\", [\n [\"path\", { d: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\", key: \"1rqfz7\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }]\n]);\n\nexport { File as default };\n//# sourceMappingURL=file.js.map\n","import { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { $getNodeByKey } from \"lexical\";\nimport { Download, File as FileIcon, FileArchive, FileText, Trash2 } from \"lucide-react\";\nimport React from \"react\";\nimport { $isFileNode } from \"src/nodes/FileNode\";\n\ninterface FileViewProps {\n src: string;\n fileName: string;\n fileSize?: number;\n nodeKey: string;\n}\n\n// Helper to format file size\nconst formatFileSize = (bytes?: number): string => {\n if (!bytes) return \"\";\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;\n};\n\n// Helper to get file extension\nconst getFileExtension = (fileName: string): string => {\n const parts = fileName.split(\".\");\n return parts.length > 1 ? parts[parts.length - 1].toLowerCase() : \"\";\n};\n\n// Helper to get icon based on file type\nconst getFileIcon = (fileName: string) => {\n const ext = getFileExtension(fileName);\n\n if ([\"pdf\", \"doc\", \"docx\", \"txt\", \"odt\"].includes(ext)) {\n return <FileText className=\"cteditor-w-8 cteditor-h-8 cteditor-text-blue-500\" />;\n }\n if ([\"zip\", \"rar\", \"7z\", \"tar\", \"gz\"].includes(ext)) {\n return <FileArchive className=\"cteditor-w-8 cteditor-h-8 cteditor-text-orange-500\" />;\n }\n return <FileIcon className=\"cteditor-w-8 cteditor-h-8 cteditor-text-gray-500\" />;\n};\n\nconst FileView: React.FC<FileViewProps> = ({ src, fileName, fileSize, nodeKey }) => {\n const [editor] = useLexicalComposerContext();\n\n // Validate props to prevent errors\n if (!src || !fileName) {\n console.error('FileView: Missing required props', { src, fileName, fileSize, nodeKey });\n return (\n <div className=\"cteditor-inline-flex cteditor-items-center cteditor-gap-3 cteditor-px-4 cteditor-py-3 cteditor-my-2 cteditor-border cteditor-border-destructive cteditor-rounded-lg cteditor-bg-destructive/10\">\n <div className=\"cteditor-text-sm cteditor-text-destructive\">\n Error loading file\n </div>\n </div>\n );\n }\n\n const handleDownload = (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n try {\n // Check if it's a data URL (base64)\n if (src.startsWith('data:')) {\n // Convert data URL to blob for proper download\n const arr = src.split(',');\n const mimeMatch = arr[0].match(/:(.*?);/);\n const mime = mimeMatch ? mimeMatch[1] : 'application/octet-stream';\n const bstr = atob(arr[1]);\n let n = bstr.length;\n const u8arr = new Uint8Array(n);\n\n while (n--) {\n u8arr[n] = bstr.charCodeAt(n);\n }\n\n const blob = new Blob([u8arr], { type: mime });\n const blobUrl = URL.createObjectURL(blob);\n\n const link = document.createElement(\"a\");\n link.href = blobUrl;\n link.download = fileName;\n link.style.display = \"none\";\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n\n // Clean up the blob URL after a delay\n setTimeout(() => URL.revokeObjectURL(blobUrl), 100);\n } else {\n // Regular URL - just download directly\n const link = document.createElement(\"a\");\n link.href = src;\n link.download = fileName;\n link.style.display = \"none\";\n link.target = \"_blank\";\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n }\n } catch (error) {\n console.error(\"Error downloading file:\", error);\n // Fallback: try to open in new tab\n window.open(src, '_blank');\n }\n };\n\n const handleDeleteFile = (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n editor.update(() => {\n const node = $getNodeByKey(nodeKey);\n if ($isFileNode(node)) {\n node.remove();\n }\n });\n };\n\n return (\n <div\n className=\"cteditor-inline-flex cteditor-items-center cteditor-gap-3 cteditor-py-1 cteditor-px-2 cteditor-my-2 cteditor-border cteditor-border-border cteditor-rounded-lg cteditor-bg-background hover:cteditor-bg-accent/50 cteditor-transition-colors cteditor-cursor-pointer cteditor-max-w-md\"\n onClick={handleDownload}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n handleDownload(e as any);\n }\n }}\n >\n {/* File Icon */}\n <div className=\"cteditor-flex-shrink-0 *:cteditor-size-5\">\n {getFileIcon(fileName)}\n </div>\n\n {/* File Info */}\n <div className=\"cteditor-flex-1 cteditor-min-w-0\">\n <div className=\"cteditor-font-medium cteditor-text-xs cteditor-text-foreground cteditor-truncate\">\n {fileName}\n </div>\n {fileSize && (\n <div className=\"cteditor-text-xs cteditor-text-muted-foreground\">\n {formatFileSize(fileSize)}\n </div>\n )}\n </div>\n\n {/* Action Buttons - Download and Delete */}\n <div className=\"cteditor-flex cteditor-gap-1 cteditor-flex-shrink-0\">\n <button\n onClick={handleDownload}\n className=\"cteditor-p-1 cteditor-rounded-md hover:cteditor-bg-accent cteditor-transition-colors\"\n aria-label=\"Download file\"\n title=\"Download file\"\n >\n <Download className=\"cteditor-w-4 cteditor-h-4 cteditor-text-muted-foreground\" />\n </button>\n <button\n onClick={handleDeleteFile}\n className=\"cteditor-p-1 cteditor-rounded-md hover:cteditor-bg-destructive hover:cteditor-text-destructive-foreground cteditor-transition-colors\"\n aria-label=\"Delete file\"\n title=\"Delete file\"\n >\n <Trash2 className=\"cteditor-w-4 cteditor-h-4 cteditor-text-muted-foreground\" />\n </button>\n </div>\n </div>\n );\n};\n\nexport default FileView;\n"],"names":["FileIcon"],"mappings":"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","x_google_ignoreList":[0,1,2]}
|
|
1
|
+
{"version":3,"file":"index-b535466a.js","sources":["../../../node_modules/lucide-react/dist/esm/icons/file-archive.js","../../../node_modules/lucide-react/dist/esm/icons/file-text.js","../../../node_modules/lucide-react/dist/esm/icons/file.js","../src/components/FileView/index.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.344.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FileArchive = createLucideIcon(\"FileArchive\", [\n [\"path\", { d: \"M16 22h2a2 2 0 0 0 2-2V7l-5-5H6a2 2 0 0 0-2 2v18\", key: \"1oywqq\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }],\n [\"circle\", { cx: \"10\", cy: \"20\", r: \"2\", key: \"1xzdoj\" }],\n [\"path\", { d: \"M10 7V6\", key: \"dljcrl\" }],\n [\"path\", { d: \"M10 12v-1\", key: \"v7bkov\" }],\n [\"path\", { d: \"M10 18v-2\", key: \"1cjy8d\" }]\n]);\n\nexport { FileArchive as default };\n//# sourceMappingURL=file-archive.js.map\n","/**\n * @license lucide-react v0.344.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst FileText = createLucideIcon(\"FileText\", [\n [\"path\", { d: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\", key: \"1rqfz7\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }],\n [\"path\", { d: \"M10 9H8\", key: \"b1mrlr\" }],\n [\"path\", { d: \"M16 13H8\", key: \"t4e002\" }],\n [\"path\", { d: \"M16 17H8\", key: \"z1uh3a\" }]\n]);\n\nexport { FileText as default };\n//# sourceMappingURL=file-text.js.map\n","/**\n * @license lucide-react v0.344.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst File = createLucideIcon(\"File\", [\n [\"path\", { d: \"M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z\", key: \"1rqfz7\" }],\n [\"path\", { d: \"M14 2v4a2 2 0 0 0 2 2h4\", key: \"tnqrlb\" }]\n]);\n\nexport { File as default };\n//# sourceMappingURL=file.js.map\n","import { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport { $getNodeByKey } from \"lexical\";\nimport { Download, File as FileIcon, FileArchive, FileText, Trash2 } from \"lucide-react\";\nimport React from \"react\";\nimport { $isFileNode } from \"src/nodes/FileNode\";\n\ninterface FileViewProps {\n src: string;\n fileName: string;\n fileSize?: number;\n nodeKey: string;\n}\n\n// Helper to format file size\nconst formatFileSize = (bytes?: number): string => {\n if (!bytes) return \"\";\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;\n};\n\n// Helper to get file extension\nconst getFileExtension = (fileName: string): string => {\n const parts = fileName.split(\".\");\n return parts.length > 1 ? parts[parts.length - 1].toLowerCase() : \"\";\n};\n\n// Helper to get icon based on file type\nconst getFileIcon = (fileName: string) => {\n const ext = getFileExtension(fileName);\n\n if ([\"pdf\", \"doc\", \"docx\", \"txt\", \"odt\"].includes(ext)) {\n return <FileText className=\"cteditor-w-8 cteditor-h-8 cteditor-text-blue-500\" />;\n }\n if ([\"zip\", \"rar\", \"7z\", \"tar\", \"gz\"].includes(ext)) {\n return <FileArchive className=\"cteditor-w-8 cteditor-h-8 cteditor-text-orange-500\" />;\n }\n return <FileIcon className=\"cteditor-w-8 cteditor-h-8 cteditor-text-gray-500\" />;\n};\n\nconst FileView: React.FC<FileViewProps> = ({ src, fileName, fileSize, nodeKey }) => {\n const [editor] = useLexicalComposerContext();\n\n // Validate props to prevent errors\n if (!src || !fileName) {\n console.error('FileView: Missing required props', { src, fileName, fileSize, nodeKey });\n return (\n <div className=\"cteditor-inline-flex cteditor-items-center cteditor-gap-3 cteditor-px-4 cteditor-py-3 cteditor-my-2 cteditor-border cteditor-border-destructive cteditor-rounded-lg cteditor-bg-destructive/10\">\n <div className=\"cteditor-text-sm cteditor-text-destructive\">\n Error loading file\n </div>\n </div>\n );\n }\n\n const handleDownload = (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n try {\n // Check if it's a data URL (base64)\n if (src.startsWith('data:')) {\n // Convert data URL to blob for proper download\n const arr = src.split(',');\n const mimeMatch = arr[0].match(/:(.*?);/);\n const mime = mimeMatch ? mimeMatch[1] : 'application/octet-stream';\n const bstr = atob(arr[1]);\n let n = bstr.length;\n const u8arr = new Uint8Array(n);\n\n while (n--) {\n u8arr[n] = bstr.charCodeAt(n);\n }\n\n const blob = new Blob([u8arr], { type: mime });\n const blobUrl = URL.createObjectURL(blob);\n\n const link = document.createElement(\"a\");\n link.href = blobUrl;\n link.download = fileName;\n link.style.display = \"none\";\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n\n // Clean up the blob URL after a delay\n setTimeout(() => URL.revokeObjectURL(blobUrl), 100);\n } else {\n // Regular URL - just download directly\n const link = document.createElement(\"a\");\n link.href = src;\n link.download = fileName;\n link.style.display = \"none\";\n link.target = \"_blank\";\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n }\n } catch (error) {\n console.error(\"Error downloading file:\", error);\n // Fallback: try to open in new tab\n window.open(src, '_blank');\n }\n };\n\n const handleDeleteFile = (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n editor.update(() => {\n const node = $getNodeByKey(nodeKey);\n if ($isFileNode(node)) {\n node.remove();\n }\n });\n };\n\n return (\n <div\n className=\"cteditor-inline-flex cteditor-items-center cteditor-gap-3 cteditor-py-1 cteditor-px-2 cteditor-my-2 cteditor-border cteditor-border-border cteditor-rounded-lg cteditor-bg-background hover:cteditor-bg-accent/50 cteditor-transition-colors cteditor-cursor-pointer cteditor-max-w-md\"\n onClick={handleDownload}\n role=\"button\"\n tabIndex={0}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n handleDownload(e as any);\n }\n }}\n >\n {/* File Icon */}\n <div className=\"cteditor-flex-shrink-0 *:cteditor-size-5\">\n {getFileIcon(fileName)}\n </div>\n\n {/* File Info */}\n <div className=\"cteditor-flex-1 cteditor-min-w-0\">\n <div className=\"cteditor-font-medium cteditor-text-xs cteditor-text-foreground cteditor-truncate\">\n {fileName}\n </div>\n {fileSize && (\n <div className=\"cteditor-text-xs cteditor-text-muted-foreground\">\n {formatFileSize(fileSize)}\n </div>\n )}\n </div>\n\n {/* Action Buttons - Download and Delete */}\n <div className=\"cteditor-flex cteditor-gap-1 cteditor-flex-shrink-0\">\n <button\n onClick={handleDownload}\n className=\"cteditor-p-1 cteditor-rounded-md hover:cteditor-bg-accent cteditor-transition-colors\"\n aria-label=\"Download file\"\n title=\"Download file\"\n >\n <Download className=\"cteditor-w-4 cteditor-h-4 cteditor-text-muted-foreground\" />\n </button>\n <button\n onClick={handleDeleteFile}\n className=\"cteditor-p-1 cteditor-rounded-md hover:cteditor-bg-destructive hover:cteditor-text-destructive-foreground cteditor-transition-colors\"\n aria-label=\"Delete file\"\n title=\"Delete file\"\n >\n <Trash2 className=\"cteditor-w-4 cteditor-h-4 cteditor-text-muted-foreground\" />\n </button>\n </div>\n </div>\n );\n};\n\nexport default FileView;\n"],"names":["FileIcon"],"mappings":"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","x_google_ignoreList":[0,1,2]}
|
|
@@ -83,6 +83,7 @@ const getApiEndpoint = () => {
|
|
|
83
83
|
return DEFAULT_API_ENDPOINT;
|
|
84
84
|
};
|
|
85
85
|
const verifyApiKey = async (apiKey) => {
|
|
86
|
+
var _a;
|
|
86
87
|
try {
|
|
87
88
|
const endpoint = getApiEndpoint();
|
|
88
89
|
const response = await axios.post(
|
|
@@ -96,6 +97,12 @@ const verifyApiKey = async (apiKey) => {
|
|
|
96
97
|
);
|
|
97
98
|
return response.data;
|
|
98
99
|
} catch (error) {
|
|
100
|
+
if ((_a = error.response) == null ? void 0 : _a.data) {
|
|
101
|
+
const customError = new Error(error.response.data.message || "Failed to verify API key");
|
|
102
|
+
customError.response = error.response;
|
|
103
|
+
customError.code = error.response.data.code;
|
|
104
|
+
throw customError;
|
|
105
|
+
}
|
|
99
106
|
throw new Error("Failed to verify API key");
|
|
100
107
|
}
|
|
101
108
|
};
|
|
@@ -1471,7 +1478,7 @@ const AiTextTransform = async ({ content, apiKey }) => {
|
|
|
1471
1478
|
const AI_ACTION_COMMAND = createCommand(
|
|
1472
1479
|
"AI_ACTION_COMMAND"
|
|
1473
1480
|
);
|
|
1474
|
-
const ImageView = React__default.lazy(() => import("./index-
|
|
1481
|
+
const ImageView = React__default.lazy(() => import("./index-fbad5b49.js"));
|
|
1475
1482
|
function isGoogleDocCheckboxImg(img) {
|
|
1476
1483
|
return img.parentElement != null && img.parentElement.tagName === "LI" && img.previousSibling === null && img.getAttribute("aria-roledescription") === "checkbox";
|
|
1477
1484
|
}
|
|
@@ -15363,7 +15370,7 @@ const EmbedComponent = ({ url, displayType, alignment, nodeKey }) => {
|
|
|
15363
15370
|
}
|
|
15364
15371
|
);
|
|
15365
15372
|
};
|
|
15366
|
-
const FileComponent = React$1.lazy(() => import("./index-
|
|
15373
|
+
const FileComponent = React$1.lazy(() => import("./index-b535466a.js"));
|
|
15367
15374
|
function convertFileElement(domNode) {
|
|
15368
15375
|
if (domNode instanceof HTMLDivElement) {
|
|
15369
15376
|
const dataUrl = domNode.getAttribute("data-lexical-file-src");
|
|
@@ -19158,6 +19165,7 @@ function AIChatDialog({
|
|
|
19158
19165
|
const [provider, setProvider] = useState$1("chatgpt");
|
|
19159
19166
|
const [costPerPrompt, setCostPerPrompt] = useState$1(1);
|
|
19160
19167
|
const [remainingCredits, setRemainingCredits] = useState$1(0);
|
|
19168
|
+
const [purchasedCredits, setPurchasedCredits] = useState$1(0);
|
|
19161
19169
|
useEffect$1(() => {
|
|
19162
19170
|
if (open && initialText) {
|
|
19163
19171
|
setInputValue(initialText);
|
|
@@ -19190,11 +19198,13 @@ function AIChatDialog({
|
|
|
19190
19198
|
if (isMounted && info) {
|
|
19191
19199
|
setCostPerPrompt(Number(info.costPerPrompt ?? 1));
|
|
19192
19200
|
setRemainingCredits(Number(info.remainingCredits ?? 0));
|
|
19201
|
+
setPurchasedCredits(Number(info.purchasedCredits ?? 0));
|
|
19193
19202
|
}
|
|
19194
19203
|
} catch (_) {
|
|
19195
19204
|
if (isMounted) {
|
|
19196
19205
|
setCostPerPrompt(1);
|
|
19197
19206
|
setRemainingCredits(0);
|
|
19207
|
+
setPurchasedCredits(0);
|
|
19198
19208
|
}
|
|
19199
19209
|
}
|
|
19200
19210
|
};
|
|
@@ -19203,24 +19213,58 @@ function AIChatDialog({
|
|
|
19203
19213
|
isMounted = false;
|
|
19204
19214
|
};
|
|
19205
19215
|
}, [apiKey]);
|
|
19216
|
+
const isImageGenerationRequest = (prompt) => {
|
|
19217
|
+
const lowerPrompt = prompt.toLowerCase();
|
|
19218
|
+
const imageKeywords = [
|
|
19219
|
+
"generate image",
|
|
19220
|
+
"generate an image",
|
|
19221
|
+
"create image",
|
|
19222
|
+
"create an image",
|
|
19223
|
+
"make image",
|
|
19224
|
+
"make an image",
|
|
19225
|
+
"draw",
|
|
19226
|
+
"illustration",
|
|
19227
|
+
"picture of",
|
|
19228
|
+
"image of",
|
|
19229
|
+
"photo of",
|
|
19230
|
+
"generate picture",
|
|
19231
|
+
"create picture",
|
|
19232
|
+
"visualize",
|
|
19233
|
+
"render image",
|
|
19234
|
+
"design image",
|
|
19235
|
+
"produce image"
|
|
19236
|
+
];
|
|
19237
|
+
return imageKeywords.some((keyword) => lowerPrompt.includes(keyword));
|
|
19238
|
+
};
|
|
19206
19239
|
const handleSubmit = async () => {
|
|
19207
19240
|
var _a, _b;
|
|
19208
19241
|
if (!inputValue.trim() || isLoading)
|
|
19209
19242
|
return;
|
|
19210
19243
|
setIsLoading(true);
|
|
19211
19244
|
setErrorMessage(null);
|
|
19245
|
+
const isImageRequest = isImageGenerationRequest(inputValue);
|
|
19212
19246
|
try {
|
|
19213
19247
|
const response = await AiEditorAction({ content: inputValue, provider, apiKey });
|
|
19214
19248
|
const htmlString = response.data;
|
|
19215
|
-
|
|
19216
|
-
|
|
19217
|
-
|
|
19218
|
-
|
|
19219
|
-
|
|
19220
|
-
|
|
19221
|
-
|
|
19222
|
-
|
|
19223
|
-
|
|
19249
|
+
const parser = new DOMParser();
|
|
19250
|
+
const dom = parser.parseFromString(htmlString.trim(), "text/html");
|
|
19251
|
+
const imgElement = dom.querySelector("img");
|
|
19252
|
+
if (isImageRequest && imgElement && imgElement.src) {
|
|
19253
|
+
editor.dispatchCommand(INSERT_IMAGE_COMMAND, {
|
|
19254
|
+
src: imgElement.src,
|
|
19255
|
+
altText: imgElement.alt || "AI generated image",
|
|
19256
|
+
originalPrompt: inputValue
|
|
19257
|
+
// Store the prompt for refinement
|
|
19258
|
+
});
|
|
19259
|
+
} else {
|
|
19260
|
+
editor.update(() => {
|
|
19261
|
+
const nodes = $generateNodesFromDOM(editor, dom);
|
|
19262
|
+
const currentSelection = $getSelection();
|
|
19263
|
+
if (currentSelection) {
|
|
19264
|
+
$insertNodes(nodes);
|
|
19265
|
+
}
|
|
19266
|
+
});
|
|
19267
|
+
}
|
|
19224
19268
|
handleClose();
|
|
19225
19269
|
setIsLoading(false);
|
|
19226
19270
|
} catch (error) {
|
|
@@ -19279,8 +19323,12 @@ function AIChatDialog({
|
|
|
19279
19323
|
] })
|
|
19280
19324
|
] }),
|
|
19281
19325
|
/* @__PURE__ */ jsxs("span", { className: "cteditor-inline-flex cteditor-items-center cteditor-gap-1 cteditor-rounded-md cteditor-bg-accent cteditor-px-2 cteditor-py-0.5", children: [
|
|
19282
|
-
/* @__PURE__ */ jsx("span", { className: "cteditor-opacity-70", children: "
|
|
19283
|
-
/* @__PURE__ */ jsx("span", { className: "cteditor-font-medium", children: remainingCredits })
|
|
19326
|
+
/* @__PURE__ */ jsx("span", { className: "cteditor-opacity-70", children: "Total" }),
|
|
19327
|
+
/* @__PURE__ */ jsx("span", { className: "cteditor-font-medium", children: remainingCredits + purchasedCredits })
|
|
19328
|
+
] }),
|
|
19329
|
+
purchasedCredits > 0 && /* @__PURE__ */ jsxs("span", { className: "cteditor-inline-flex cteditor-items-center cteditor-gap-1 cteditor-rounded-md cteditor-bg-green-500/10 cteditor-px-2 cteditor-py-0.5", children: [
|
|
19330
|
+
/* @__PURE__ */ jsx("span", { className: "cteditor-opacity-70", children: "Purchased" }),
|
|
19331
|
+
/* @__PURE__ */ jsx("span", { className: "cteditor-font-medium cteditor-text-green-600", children: purchasedCredits })
|
|
19284
19332
|
] })
|
|
19285
19333
|
] })
|
|
19286
19334
|
] }),
|
|
@@ -19460,6 +19508,7 @@ function InlineAIPrompt({
|
|
|
19460
19508
|
const [provider, setProvider] = useState$1(initialProvider);
|
|
19461
19509
|
const [inputValue, setInputValue] = useState$1("");
|
|
19462
19510
|
const [isLoading, setIsLoading] = useState$1(false);
|
|
19511
|
+
const [status, setStatus] = useState$1("idle");
|
|
19463
19512
|
const inputRef = useRef(null);
|
|
19464
19513
|
const [selectedText, setSelectedText] = useState$1(initialSelectedText);
|
|
19465
19514
|
useEffect$1(() => {
|
|
@@ -19470,6 +19519,7 @@ function InlineAIPrompt({
|
|
|
19470
19519
|
const newSelectedText = selection.getTextContent();
|
|
19471
19520
|
if (newSelectedText.trim() !== "") {
|
|
19472
19521
|
setSelectedText(newSelectedText);
|
|
19522
|
+
setStatus("idle");
|
|
19473
19523
|
}
|
|
19474
19524
|
}
|
|
19475
19525
|
});
|
|
@@ -19483,23 +19533,56 @@ function InlineAIPrompt({
|
|
|
19483
19533
|
inputRef.current.focus();
|
|
19484
19534
|
}
|
|
19485
19535
|
}, []);
|
|
19536
|
+
const isImageGenerationRequest = (prompt) => {
|
|
19537
|
+
const lowerPrompt = prompt.toLowerCase();
|
|
19538
|
+
const imageKeywords = [
|
|
19539
|
+
"generate image",
|
|
19540
|
+
"generate an image",
|
|
19541
|
+
"create image",
|
|
19542
|
+
"create an image",
|
|
19543
|
+
"make image",
|
|
19544
|
+
"make an image",
|
|
19545
|
+
"draw",
|
|
19546
|
+
"illustration",
|
|
19547
|
+
"picture of",
|
|
19548
|
+
"image of",
|
|
19549
|
+
"photo of",
|
|
19550
|
+
"generate picture",
|
|
19551
|
+
"create picture",
|
|
19552
|
+
"visualize",
|
|
19553
|
+
"render image",
|
|
19554
|
+
"design image",
|
|
19555
|
+
"produce image"
|
|
19556
|
+
];
|
|
19557
|
+
return imageKeywords.some((keyword) => lowerPrompt.includes(keyword));
|
|
19558
|
+
};
|
|
19486
19559
|
const handleSubmit = async () => {
|
|
19487
19560
|
var _a, _b;
|
|
19488
19561
|
if (!inputValue.trim() || isLoading)
|
|
19489
19562
|
return;
|
|
19490
|
-
|
|
19563
|
+
const isImageRequest = isImageGenerationRequest(inputValue) || selectedText && isImageGenerationRequest(selectedText);
|
|
19564
|
+
if (!isImageRequest && (!selectedText || selectedText.trim() === "")) {
|
|
19491
19565
|
toast.error("Please select some text first");
|
|
19492
19566
|
return;
|
|
19493
19567
|
}
|
|
19494
19568
|
setIsLoading(true);
|
|
19495
|
-
|
|
19569
|
+
let finalPrompt;
|
|
19570
|
+
if (isImageRequest) {
|
|
19571
|
+
if (selectedText && selectedText.trim()) {
|
|
19572
|
+
finalPrompt = `${inputValue}: ${selectedText}`;
|
|
19573
|
+
} else {
|
|
19574
|
+
finalPrompt = inputValue;
|
|
19575
|
+
}
|
|
19576
|
+
} else {
|
|
19577
|
+
finalPrompt = `${inputValue}
|
|
19496
19578
|
|
|
19497
19579
|
IMPORTANT: Return ONLY the modified/transformed text. Do NOT include any labels, prefixes, explanations, or formatting like "Simplified:", "Result:", "Here is", etc. Just return the pure result text.
|
|
19498
19580
|
|
|
19499
19581
|
Text to transform:
|
|
19500
19582
|
"${selectedText}"`;
|
|
19583
|
+
}
|
|
19501
19584
|
try {
|
|
19502
|
-
const response = await AiEditorAction({ content:
|
|
19585
|
+
const response = await AiEditorAction({ content: finalPrompt, provider, apiKey });
|
|
19503
19586
|
let htmlString = response.data;
|
|
19504
19587
|
if (typeof htmlString === "string") {
|
|
19505
19588
|
htmlString = htmlString.trim();
|
|
@@ -19507,22 +19590,34 @@ Text to transform:
|
|
|
19507
19590
|
htmlString = htmlString.slice(1, -1);
|
|
19508
19591
|
}
|
|
19509
19592
|
}
|
|
19510
|
-
|
|
19511
|
-
|
|
19512
|
-
|
|
19513
|
-
|
|
19514
|
-
|
|
19515
|
-
|
|
19516
|
-
|
|
19517
|
-
|
|
19518
|
-
|
|
19593
|
+
const parser = new DOMParser();
|
|
19594
|
+
const dom = parser.parseFromString(htmlString.trim(), "text/html");
|
|
19595
|
+
const imgElement = dom.querySelector("img");
|
|
19596
|
+
if (isImageRequest && imgElement && imgElement.src) {
|
|
19597
|
+
editor.dispatchCommand(INSERT_IMAGE_COMMAND, {
|
|
19598
|
+
src: imgElement.src,
|
|
19599
|
+
altText: imgElement.alt || "AI generated image",
|
|
19600
|
+
originalPrompt: finalPrompt
|
|
19601
|
+
// Store the prompt for refinement
|
|
19602
|
+
});
|
|
19603
|
+
} else {
|
|
19604
|
+
editor.update(() => {
|
|
19605
|
+
const nodes = $generateNodesFromDOM(editor, dom);
|
|
19606
|
+
const currentSelection = $getSelection();
|
|
19607
|
+
if (currentSelection) {
|
|
19608
|
+
$insertNodes(nodes);
|
|
19609
|
+
}
|
|
19610
|
+
});
|
|
19611
|
+
}
|
|
19519
19612
|
setInputValue("");
|
|
19520
19613
|
setSelectedText("");
|
|
19614
|
+
setStatus("success");
|
|
19521
19615
|
} catch (error) {
|
|
19522
19616
|
console.error("Error processing AI action:", error);
|
|
19523
19617
|
const apiMessage = ((_b = (_a = error == null ? void 0 : error.response) == null ? void 0 : _a.data) == null ? void 0 : _b.message) ?? (error instanceof Error ? error.message : null);
|
|
19524
19618
|
const safeMessage = apiMessage && !/^Request failed with status code \d+/.test(apiMessage) ? apiMessage : "Error processing your request. Please try again.";
|
|
19525
19619
|
toast.error(safeMessage);
|
|
19620
|
+
setStatus("error");
|
|
19526
19621
|
} finally {
|
|
19527
19622
|
setIsLoading(false);
|
|
19528
19623
|
}
|
|
@@ -19537,6 +19632,7 @@ Text to transform:
|
|
|
19537
19632
|
}
|
|
19538
19633
|
};
|
|
19539
19634
|
const hasSelectedText = selectedText && selectedText.trim() !== "";
|
|
19635
|
+
const isCurrentInputImageRequest = isImageGenerationRequest(inputValue);
|
|
19540
19636
|
const displayText = hasSelectedText ? selectedText.length > 50 ? selectedText.substring(0, 50) + "..." : selectedText : "";
|
|
19541
19637
|
return /* @__PURE__ */ jsxs(
|
|
19542
19638
|
"div",
|
|
@@ -19566,20 +19662,20 @@ Text to transform:
|
|
|
19566
19662
|
alignItems: "center",
|
|
19567
19663
|
gap: "8px",
|
|
19568
19664
|
padding: "6px 10px",
|
|
19569
|
-
backgroundColor: hasSelectedText ? "#2a2a2a" : "#3a2a2a",
|
|
19665
|
+
backgroundColor: status === "success" ? "#1a2e1a" : status === "error" ? "#2e1a1a" : hasSelectedText ? "#2a2a2a" : isCurrentInputImageRequest ? "#2a3a2a" : "#3a2a2a",
|
|
19570
19666
|
borderRadius: "6px",
|
|
19571
19667
|
fontSize: "12px",
|
|
19572
19668
|
color: "#999",
|
|
19573
|
-
border: hasSelectedText ? "none" : "1px solid #5a3a3a"
|
|
19669
|
+
border: status === "success" ? "1px solid #3a5a3a" : status === "error" ? "1px solid #5a3a3a" : hasSelectedText ? "none" : isCurrentInputImageRequest ? "1px solid #3a5a3a" : "1px solid #5a3a3a"
|
|
19574
19670
|
},
|
|
19575
|
-
children: hasSelectedText ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
19671
|
+
children: status === "success" ? /* @__PURE__ */ jsx("span", { style: { color: "#4ade80" }, children: "✓ Content inserted! Select new text or enter another prompt" }) : status === "error" ? /* @__PURE__ */ jsx("span", { style: { color: "#f87171" }, children: "✗ Request failed. Try again or select different text" }) : hasSelectedText ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
19576
19672
|
/* @__PURE__ */ jsx("span", { style: { color: "#666" }, children: "Selected:" }),
|
|
19577
19673
|
/* @__PURE__ */ jsxs("span", { style: { color: "#ccc", fontStyle: "italic" }, children: [
|
|
19578
19674
|
'"',
|
|
19579
19675
|
displayText,
|
|
19580
19676
|
'"'
|
|
19581
19677
|
] })
|
|
19582
|
-
] }) : /* @__PURE__ */ jsx("span", { style: { color: "#f87171" }, children: "⚠ Please select some text
|
|
19678
|
+
] }) : isCurrentInputImageRequest ? /* @__PURE__ */ jsx("span", { style: { color: "#4ade80" }, children: "🖼️ Image generation mode - no text selection required" }) : /* @__PURE__ */ jsx("span", { style: { color: "#f87171" }, children: "⚠ Please select some text or enter an image generation prompt" })
|
|
19583
19679
|
}
|
|
19584
19680
|
),
|
|
19585
19681
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "10px" }, children: [
|
|
@@ -19615,9 +19711,13 @@ Text to transform:
|
|
|
19615
19711
|
ref: inputRef,
|
|
19616
19712
|
type: "text",
|
|
19617
19713
|
value: inputValue,
|
|
19618
|
-
onChange: (e) =>
|
|
19714
|
+
onChange: (e) => {
|
|
19715
|
+
setInputValue(e.target.value);
|
|
19716
|
+
if (status !== "idle")
|
|
19717
|
+
setStatus("idle");
|
|
19718
|
+
},
|
|
19619
19719
|
onKeyDown: handleKeyDown,
|
|
19620
|
-
placeholder: hasSelectedText ? "What do you want to do with this text?" : "
|
|
19720
|
+
placeholder: hasSelectedText ? "What do you want to do with this text?" : "Generate image of... or select text",
|
|
19621
19721
|
disabled: isLoading,
|
|
19622
19722
|
style: {
|
|
19623
19723
|
width: "280px",
|
|
@@ -20386,10 +20486,10 @@ const PDF_CONFIG = {
|
|
|
20386
20486
|
};
|
|
20387
20487
|
const loadHtml2Pdf = async () => {
|
|
20388
20488
|
try {
|
|
20389
|
-
const mod = await import("./html2pdf.bundle.min-
|
|
20489
|
+
const mod = await import("./html2pdf.bundle.min-f3fd0aa5.js").then((n) => n.h);
|
|
20390
20490
|
return (mod == null ? void 0 : mod.default) || mod;
|
|
20391
20491
|
} catch {
|
|
20392
|
-
const mod2 = await import("./html2pdf.bundle-
|
|
20492
|
+
const mod2 = await import("./html2pdf.bundle-33b132a6.js").then((n) => n.h);
|
|
20393
20493
|
return (mod2 == null ? void 0 : mod2.default) || mod2;
|
|
20394
20494
|
}
|
|
20395
20495
|
};
|
|
@@ -29091,49 +29191,15 @@ const fileToDataURL = (file) => {
|
|
|
29091
29191
|
function DragDropPaste() {
|
|
29092
29192
|
const [editor] = useLexicalComposerContext();
|
|
29093
29193
|
const [isDragging, setIsDragging] = useState$1(false);
|
|
29194
|
+
const processedFilesRef = useRef(/* @__PURE__ */ new Set());
|
|
29094
29195
|
const { apiKey } = useEditor();
|
|
29095
29196
|
const { uploadFileToS3 } = useS3Uploader(apiKey || void 0);
|
|
29096
29197
|
useEffect$1(() => {
|
|
29097
|
-
const
|
|
29098
|
-
|
|
29099
|
-
|
|
29100
|
-
|
|
29101
|
-
|
|
29102
|
-
if (files && files.length > 0) {
|
|
29103
|
-
const imageFiles = Array.from(files).filter(
|
|
29104
|
-
(file) => ACCEPTABLE_IMAGE_TYPES.some((type) => file.type.startsWith(type.replace("/", "")) || file.type === type)
|
|
29105
|
-
);
|
|
29106
|
-
if (imageFiles.length > 0) {
|
|
29107
|
-
e.preventDefault();
|
|
29108
|
-
for (const file of imageFiles) {
|
|
29109
|
-
let fileUrl;
|
|
29110
|
-
try {
|
|
29111
|
-
if (apiKey) {
|
|
29112
|
-
fileUrl = await uploadFileToS3(file);
|
|
29113
|
-
} else {
|
|
29114
|
-
fileUrl = await fileToDataURL(file);
|
|
29115
|
-
}
|
|
29116
|
-
} catch (error) {
|
|
29117
|
-
console.error("Upload failed for pasted image:", error);
|
|
29118
|
-
fileUrl = await fileToDataURL(file);
|
|
29119
|
-
}
|
|
29120
|
-
editor.dispatchCommand(INSERT_IMAGE_COMMAND, {
|
|
29121
|
-
altText: file.name || "Pasted image",
|
|
29122
|
-
src: fileUrl
|
|
29123
|
-
});
|
|
29124
|
-
}
|
|
29125
|
-
return;
|
|
29126
|
-
}
|
|
29127
|
-
}
|
|
29128
|
-
};
|
|
29129
|
-
const editorElement = editor.getRootElement();
|
|
29130
|
-
if (editorElement) {
|
|
29131
|
-
editorElement.addEventListener("paste", handlePaste);
|
|
29132
|
-
return () => {
|
|
29133
|
-
editorElement.removeEventListener("paste", handlePaste);
|
|
29134
|
-
};
|
|
29135
|
-
}
|
|
29136
|
-
}, [editor, apiKey, uploadFileToS3]);
|
|
29198
|
+
const cleanup = setInterval(() => {
|
|
29199
|
+
processedFilesRef.current.clear();
|
|
29200
|
+
}, 1e3);
|
|
29201
|
+
return () => clearInterval(cleanup);
|
|
29202
|
+
}, []);
|
|
29137
29203
|
useEffect$1(() => {
|
|
29138
29204
|
const handleDragEnter = (e) => {
|
|
29139
29205
|
var _a, _b;
|
|
@@ -29241,14 +29307,18 @@ function DragDropPaste() {
|
|
|
29241
29307
|
...ACCEPTABLE_APPLICATION_TYPES
|
|
29242
29308
|
]);
|
|
29243
29309
|
for (const { file, result } of filesResult) {
|
|
29310
|
+
const fileKey = `${file.name}-${file.size}-${file.type}-${file.lastModified}`;
|
|
29311
|
+
if (processedFilesRef.current.has(fileKey)) {
|
|
29312
|
+
console.log("Skipping duplicate file:", file.name);
|
|
29313
|
+
continue;
|
|
29314
|
+
}
|
|
29315
|
+
processedFilesRef.current.add(fileKey);
|
|
29244
29316
|
let fileUrl;
|
|
29245
29317
|
try {
|
|
29246
29318
|
if (apiKey) {
|
|
29247
29319
|
fileUrl = await uploadFileToS3(file);
|
|
29248
|
-
console.log("File uploaded to S3:", fileUrl);
|
|
29249
29320
|
} else {
|
|
29250
29321
|
fileUrl = await fileToDataURL(file);
|
|
29251
|
-
console.log("Using local data URL (no S3 upload)");
|
|
29252
29322
|
}
|
|
29253
29323
|
} catch (error) {
|
|
29254
29324
|
console.error("Upload failed, using local data URL:", error);
|
|
@@ -29256,7 +29326,7 @@ function DragDropPaste() {
|
|
|
29256
29326
|
}
|
|
29257
29327
|
if (isMimeType(file, ACCEPTABLE_IMAGE_TYPES)) {
|
|
29258
29328
|
editor.dispatchCommand(INSERT_IMAGE_COMMAND, {
|
|
29259
|
-
altText: file.name,
|
|
29329
|
+
altText: file.name || "Pasted image",
|
|
29260
29330
|
src: fileUrl
|
|
29261
29331
|
});
|
|
29262
29332
|
} else if (isMimeType(file, ACCEPTABLE_APPLICATION_TYPES)) {
|
|
@@ -38517,10 +38587,7 @@ const ConfigurableEditorWithAuth = ({
|
|
|
38517
38587
|
return /* @__PURE__ */ jsx(ScopedEditorWrapper, { children: /* @__PURE__ */ jsx(LoadingMessage, { children: /* @__PURE__ */ jsx("span", { children: "Loading editor..." }) }) });
|
|
38518
38588
|
}
|
|
38519
38589
|
if (error) {
|
|
38520
|
-
return /* @__PURE__ */ jsx(ScopedEditorWrapper, { children: /* @__PURE__ */ jsx(ErrorMessage, { children: /* @__PURE__ */
|
|
38521
|
-
"Error: ",
|
|
38522
|
-
error
|
|
38523
|
-
] }) }) });
|
|
38590
|
+
return /* @__PURE__ */ jsx(ScopedEditorWrapper, { children: /* @__PURE__ */ jsx(ErrorMessage, { children: /* @__PURE__ */ jsx("span", { children: error }) }) });
|
|
38524
38591
|
}
|
|
38525
38592
|
if (!isAuthenticated || !editorConfig2) {
|
|
38526
38593
|
return /* @__PURE__ */ jsx(ScopedEditorWrapper, { children: /* @__PURE__ */ jsx(AuthMessage, { children: /* @__PURE__ */ jsx("span", { children: "Please provide a valid API key to access the editor" }) }) });
|
|
@@ -38560,8 +38627,8 @@ export {
|
|
|
38560
38627
|
DialogTitle as f,
|
|
38561
38628
|
getDefaultExportFromCjs as g,
|
|
38562
38629
|
DialogDescription as h,
|
|
38563
|
-
|
|
38564
|
-
|
|
38630
|
+
DialogFooter as i,
|
|
38631
|
+
initialConfig as j,
|
|
38565
38632
|
$isImageNode as k,
|
|
38566
38633
|
EditorProvider as l,
|
|
38567
38634
|
useEditor as m,
|
|
@@ -38571,4 +38638,4 @@ export {
|
|
|
38571
38638
|
useHtmlView as u,
|
|
38572
38639
|
verifyApiKey as v
|
|
38573
38640
|
};
|
|
38574
|
-
//# sourceMappingURL=index-
|
|
38641
|
+
//# sourceMappingURL=index-daaf2abc.js.map
|