tulih-editor 0.1.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 (122) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +331 -0
  3. package/dist/tulih-editor.css +1 -0
  4. package/dist/tulih-editor.es.js +3051 -0
  5. package/dist/tulih-editor.es.js.map +1 -0
  6. package/dist/tulih-editor.umd.js +8 -0
  7. package/dist/tulih-editor.umd.js.map +1 -0
  8. package/dist/types/core/Editor.d.ts +20 -0
  9. package/dist/types/core/PluginManager.d.ts +22 -0
  10. package/dist/types/core/helpers.d.ts +22 -0
  11. package/dist/types/index.d.ts +5 -0
  12. package/dist/types/plugins/align.d.ts +3 -0
  13. package/dist/types/plugins/autoLinkify.d.ts +3 -0
  14. package/dist/types/plugins/autosave.d.ts +3 -0
  15. package/dist/types/plugins/block.d.ts +3 -0
  16. package/dist/types/plugins/caseTransform.d.ts +3 -0
  17. package/dist/types/plugins/codeBlock.d.ts +3 -0
  18. package/dist/types/plugins/colors.d.ts +3 -0
  19. package/dist/types/plugins/darkMode.d.ts +3 -0
  20. package/dist/types/plugins/direction.d.ts +3 -0
  21. package/dist/types/plugins/dragDrop.d.ts +3 -0
  22. package/dist/types/plugins/emoji.d.ts +3 -0
  23. package/dist/types/plugins/emojiAutocomplete.d.ts +3 -0
  24. package/dist/types/plugins/findReplace.d.ts +3 -0
  25. package/dist/types/plugins/floatingToolbar.d.ts +3 -0
  26. package/dist/types/plugins/fontFamily.d.ts +3 -0
  27. package/dist/types/plugins/fontSize.d.ts +3 -0
  28. package/dist/types/plugins/fullscreen.d.ts +3 -0
  29. package/dist/types/plugins/history.d.ts +3 -0
  30. package/dist/types/plugins/hr.d.ts +3 -0
  31. package/dist/types/plugins/iframe.d.ts +3 -0
  32. package/dist/types/plugins/image.d.ts +3 -0
  33. package/dist/types/plugins/imageProps.d.ts +3 -0
  34. package/dist/types/plugins/imageTools.d.ts +3 -0
  35. package/dist/types/plugins/indent.d.ts +3 -0
  36. package/dist/types/plugins/index.d.ts +2 -0
  37. package/dist/types/plugins/inline.d.ts +3 -0
  38. package/dist/types/plugins/inlineCode.d.ts +3 -0
  39. package/dist/types/plugins/keyboardShortcuts.d.ts +3 -0
  40. package/dist/types/plugins/lineHeight.d.ts +3 -0
  41. package/dist/types/plugins/link.d.ts +3 -0
  42. package/dist/types/plugins/linkTooltip.d.ts +3 -0
  43. package/dist/types/plugins/list.d.ts +3 -0
  44. package/dist/types/plugins/markdown.d.ts +3 -0
  45. package/dist/types/plugins/mediaEmbed.d.ts +3 -0
  46. package/dist/types/plugins/pasteImage.d.ts +3 -0
  47. package/dist/types/plugins/pastePlain.d.ts +3 -0
  48. package/dist/types/plugins/pre.d.ts +3 -0
  49. package/dist/types/plugins/readOnly.d.ts +3 -0
  50. package/dist/types/plugins/shortcutCustomizer.d.ts +3 -0
  51. package/dist/types/plugins/shortcutsHelp.d.ts +3 -0
  52. package/dist/types/plugins/source.d.ts +3 -0
  53. package/dist/types/plugins/specialChars.d.ts +3 -0
  54. package/dist/types/plugins/statusBar.d.ts +3 -0
  55. package/dist/types/plugins/subSuper.d.ts +3 -0
  56. package/dist/types/plugins/table.d.ts +3 -0
  57. package/dist/types/plugins/tableBg.d.ts +3 -0
  58. package/dist/types/plugins/tableTools.d.ts +3 -0
  59. package/dist/types/plugins/toolbarCollapse.d.ts +3 -0
  60. package/dist/types/plugins/unlink.d.ts +3 -0
  61. package/dist/types/plugins/wordCount.d.ts +3 -0
  62. package/dist/types/types.d.ts +226 -0
  63. package/package.json +66 -0
  64. package/src/core/Editor.ts +460 -0
  65. package/src/core/PluginManager.ts +140 -0
  66. package/src/core/helpers.ts +209 -0
  67. package/src/css.d.ts +2 -0
  68. package/src/index.ts +87 -0
  69. package/src/plugins/align.ts +72 -0
  70. package/src/plugins/autoLinkify.ts +34 -0
  71. package/src/plugins/autosave.ts +69 -0
  72. package/src/plugins/block.ts +32 -0
  73. package/src/plugins/caseTransform.ts +54 -0
  74. package/src/plugins/codeBlock.ts +93 -0
  75. package/src/plugins/colors.ts +68 -0
  76. package/src/plugins/darkMode.ts +123 -0
  77. package/src/plugins/direction.ts +30 -0
  78. package/src/plugins/dragDrop.ts +68 -0
  79. package/src/plugins/emoji.ts +188 -0
  80. package/src/plugins/emojiAutocomplete.ts +183 -0
  81. package/src/plugins/findReplace.ts +229 -0
  82. package/src/plugins/floatingToolbar.ts +258 -0
  83. package/src/plugins/fontFamily.ts +41 -0
  84. package/src/plugins/fontSize.ts +32 -0
  85. package/src/plugins/fullscreen.ts +36 -0
  86. package/src/plugins/history.ts +14 -0
  87. package/src/plugins/hr.ts +118 -0
  88. package/src/plugins/iframe.ts +88 -0
  89. package/src/plugins/image.ts +107 -0
  90. package/src/plugins/imageProps.ts +119 -0
  91. package/src/plugins/imageTools.ts +344 -0
  92. package/src/plugins/indent.ts +29 -0
  93. package/src/plugins/index.ts +101 -0
  94. package/src/plugins/inline.ts +17 -0
  95. package/src/plugins/inlineCode.ts +21 -0
  96. package/src/plugins/keyboardShortcuts.ts +92 -0
  97. package/src/plugins/lineHeight.ts +40 -0
  98. package/src/plugins/link.ts +344 -0
  99. package/src/plugins/linkTooltip.ts +63 -0
  100. package/src/plugins/list.ts +141 -0
  101. package/src/plugins/markdown.ts +61 -0
  102. package/src/plugins/mediaEmbed.ts +44 -0
  103. package/src/plugins/pasteImage.ts +61 -0
  104. package/src/plugins/pastePlain.ts +43 -0
  105. package/src/plugins/pre.ts +11 -0
  106. package/src/plugins/readOnly.ts +46 -0
  107. package/src/plugins/shortcutCustomizer.ts +125 -0
  108. package/src/plugins/shortcutsHelp.ts +51 -0
  109. package/src/plugins/source.ts +77 -0
  110. package/src/plugins/specialChars.ts +64 -0
  111. package/src/plugins/statusBar.ts +85 -0
  112. package/src/plugins/subSuper.ts +20 -0
  113. package/src/plugins/table.ts +166 -0
  114. package/src/plugins/tableBg.ts +11 -0
  115. package/src/plugins/tableTools.ts +475 -0
  116. package/src/plugins/toolbarCollapse.ts +14 -0
  117. package/src/plugins/unlink.ts +29 -0
  118. package/src/plugins/wordCount.ts +34 -0
  119. package/src/styles/base.css +258 -0
  120. package/src/styles/editor.css +309 -0
  121. package/src/styles/index.css +6 -0
  122. package/src/types.ts +278 -0
@@ -0,0 +1,3051 @@
1
+ class xe {
2
+ constructor() {
3
+ this._plugins = [], this._map = {}, this._injectedCSS = /* @__PURE__ */ new Set(), this._cssInjected = !1;
4
+ }
5
+ register(t, o) {
6
+ if (this._map[t])
7
+ throw new Error('Plugin "' + t + '" is already registered');
8
+ return o.name = t, o.deps = o.deps || [], o.order = o.order || 100, this._plugins.push(o), this._map[t] = o, this;
9
+ }
10
+ unregister(t) {
11
+ const o = this._map[t];
12
+ if (!o) return;
13
+ o.destroy && o.destroy(void 0);
14
+ const r = this._plugins.indexOf(o);
15
+ r !== -1 && this._plugins.splice(r, 1), delete this._map[t];
16
+ }
17
+ get(t) {
18
+ return this._map[t] || null;
19
+ }
20
+ has(t) {
21
+ return !!this._map[t];
22
+ }
23
+ getNames() {
24
+ return Object.keys(this._map);
25
+ }
26
+ _resolveOrder() {
27
+ const t = [], o = {}, r = {}, n = this._map;
28
+ function a(c) {
29
+ if (o[c]) return;
30
+ if (r[c]) throw new Error("Circular dependency: " + c);
31
+ r[c] = !0;
32
+ const d = n[c];
33
+ d && d.deps && d.deps.forEach((p) => {
34
+ if (!n[p]) throw new Error('Plugin "' + c + '" depends on "' + p + '" but not registered');
35
+ a(p);
36
+ }), r[c] = !1, o[c] = !0, t.push(n[c]);
37
+ }
38
+ return this._plugins.slice().sort((c, d) => (c.order || 0) - (d.order || 0)).forEach((c) => a(c.name)), t;
39
+ }
40
+ initAll(t) {
41
+ this._resolveOrder().forEach((o) => {
42
+ o.init && o.init(t);
43
+ });
44
+ }
45
+ destroyAll(t) {
46
+ this._plugins.slice().reverse().forEach((r) => {
47
+ r.destroy && r.destroy(t);
48
+ });
49
+ }
50
+ getToolbarHTML(t, o) {
51
+ if (o && Array.isArray(o)) {
52
+ const i = [];
53
+ return o.forEach((c, d) => {
54
+ d > 0 && i.push('<div class="te-divider"></div>'), c.forEach((p) => {
55
+ const s = this._map[p];
56
+ if (!s || t[p] === !1) return;
57
+ const u = typeof s.toolbarHTML == "function" ? s.toolbarHTML(t) : s.toolbarHTML;
58
+ u && i.push(u);
59
+ });
60
+ }), i.join(`
61
+ `);
62
+ }
63
+ const r = this._resolveOrder().filter((i) => t[i.name] !== !1 && i.toolbarHTML), n = [];
64
+ let a = -1;
65
+ return r.forEach((i) => {
66
+ const c = typeof i.toolbarHTML == "function" ? i.toolbarHTML(t) : i.toolbarHTML;
67
+ if (!c) return;
68
+ const d = Math.floor((i.order || 0) / 10);
69
+ a !== -1 && d !== a && n.push('<div class="te-divider"></div>'), n.push(c), a = d;
70
+ }), n.join(`
71
+ `);
72
+ }
73
+ getModalHTML(t) {
74
+ return this._resolveOrder().filter((r) => t[r.name] !== !1 && r.modalHTML).map((r) => typeof r.modalHTML == "function" ? r.modalHTML(t) : r.modalHTML).filter(Boolean).join(`
75
+ `);
76
+ }
77
+ injectAllCSS() {
78
+ this._cssInjected || (this._cssInjected = !0, this._resolveOrder().forEach((t) => {
79
+ if (!t.css || this._injectedCSS.has(t.name)) return;
80
+ this._injectedCSS.add(t.name);
81
+ const o = typeof t.css == "function" ? t.css({}) : t.css;
82
+ if (!o) return;
83
+ const r = document.createElement("style");
84
+ r.setAttribute("data-te-css", t.name), r.textContent = o, document.head.appendChild(r);
85
+ }));
86
+ }
87
+ }
88
+ const Ce = "p,h1,h2,h3,blockquote,pre,ul,ol,li,table,hr,iframe,.te-embed", Ae = ["A", "B", "I", "U", "S", "STRONG", "EM", "SPAN", "SMALL", "MARK", "CODE", "KBD", "SUB", "SUP"];
89
+ function qe(e) {
90
+ return !!e.querySelector(Ce);
91
+ }
92
+ function He(e) {
93
+ if (e.nodeType !== 1) return !1;
94
+ const t = e.tagName;
95
+ return t === "IMG" || t === "BR" || t === "IFRAME" ? !0 : Ae.indexOf(t) !== -1;
96
+ }
97
+ function ue(e) {
98
+ const t = document.createElement("p");
99
+ return e.parentNode.insertBefore(t, e), t.appendChild(e), t;
100
+ }
101
+ function Me(e) {
102
+ if (!e || e.tagName !== "IFRAME") return;
103
+ const t = document.createElement("div");
104
+ return t.className = "te-embed", t.setAttribute("contenteditable", "false"), e.setAttribute("contenteditable", "false"), e.setAttribute("draggable", "false"), e.setAttribute("tabindex", "-1"), e.parentNode.insertBefore(t, e), t.appendChild(e), t;
105
+ }
106
+ function V(e) {
107
+ if (!e) return;
108
+ let t = e.firstChild;
109
+ for (; t; ) {
110
+ const o = t.nextSibling;
111
+ if (t.nodeType === 3)
112
+ (t.textContent || "").trim() === "" ? e.removeChild(t) : ue(t);
113
+ else if (t.nodeType === 1) {
114
+ const r = t, n = r.tagName;
115
+ if (n === "DIV") {
116
+ if (!(r.classList.contains("te-embed") || r.querySelector("iframe,video,audio,.te-embed"))) {
117
+ if (!qe(r)) {
118
+ const a = document.createElement("p");
119
+ for (; r.firstChild; )
120
+ a.appendChild(r.firstChild);
121
+ e.replaceChild(a, r);
122
+ }
123
+ }
124
+ } else n === "IFRAME" ? Me(r) : He(r) && ue(r);
125
+ }
126
+ t = o;
127
+ }
128
+ }
129
+ function J(e) {
130
+ if (!e || e.querySelector(Ce)) return;
131
+ if (!e.firstChild) {
132
+ const o = document.createElement("p");
133
+ o.innerHTML = "<br>", e.appendChild(o);
134
+ return;
135
+ }
136
+ const t = document.createElement("p");
137
+ for (; e.firstChild; )
138
+ t.appendChild(e.firstChild);
139
+ e.appendChild(t);
140
+ }
141
+ function ie(e) {
142
+ return String(e).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
143
+ }
144
+ function Re(e, t) {
145
+ return '<div class="te-container"> <div class="te-toolbar mb-0">' + e + ' </div> <div class="te-editor" contenteditable="true" placeholder="Start typing..."></div>' + t + "</div>";
146
+ }
147
+ const pe = {
148
+ block: !1,
149
+ inline: !1,
150
+ inlineCode: !1,
151
+ subSuper: !1,
152
+ removeFormat: !1,
153
+ codeBlock: !1,
154
+ mediaEmbed: !1,
155
+ dragDrop: !1,
156
+ readOnly: !1,
157
+ linkTooltip: !1,
158
+ emojiAutocomplete: !1,
159
+ statusBar: !1,
160
+ pastePlain: !1,
161
+ findReplace: !1,
162
+ indent: !1,
163
+ list: !1,
164
+ autoLinkify: !1,
165
+ caseTransform: !1,
166
+ shortcutsHelp: !1,
167
+ lineHeight: !1,
168
+ fontSize: !1,
169
+ fontFamily: !1,
170
+ specialChars: !1,
171
+ colors: !1,
172
+ tableBg: !1,
173
+ align: !1,
174
+ markdown: !1,
175
+ link: !1,
176
+ image: !1,
177
+ imageProps: !1,
178
+ imageTools: !1,
179
+ iframe: !1,
180
+ table: !1,
181
+ tableTools: !1,
182
+ hr: !1,
183
+ unlink: !1,
184
+ emoji: !1,
185
+ direction: !1,
186
+ source: !1,
187
+ history: !1,
188
+ fullscreen: !1,
189
+ toolbarCollapse: !1,
190
+ autosave: !1,
191
+ floatingToolbar: !1,
192
+ darkMode: !1,
193
+ shortcutCustomizer: !1,
194
+ minimal: !1
195
+ }, Ne = {
196
+ allowedTags: ["p", "h1", "h2", "h3", "h4", "h5", "h6", "blockquote", "pre", "code", "strong", "em", "u", "s", "span", "a", "img", "iframe", "ul", "ol", "li", "table", "thead", "tbody", "tfoot", "tr", "th", "td", "br", "hr"],
197
+ allowedAttributes: ["href", "src", "alt", "title", "width", "height", "class", "id", "style", "target", "rel", "allow", "allowfullscreen", "frameborder"]
198
+ }, Be = ["http", "https", "mailto", "tel"], ze = ["http", "https", "data"], Ie = ["youtube.com", "www.youtube.com", "youtu.be", "player.vimeo.com", "vimeo.com"], _e = "allow-scripts allow-same-origin allow-presentation", De = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share";
199
+ class Ee {
200
+ constructor(t, o, r) {
201
+ this.container = null, this.editor = null, this.toolbar = null, this._ctx = null;
202
+ const n = typeof t == "string" ? document.querySelector(t) : t;
203
+ if (!n) return;
204
+ const a = String(n.tagName).toUpperCase() === "TEXTAREA", i = n.matches && n.matches("textarea[data-tulih-editor]");
205
+ if (!a && !i) return;
206
+ const c = n.nextElementSibling;
207
+ if (c && c.querySelector && c.querySelector(".te-editor")) return;
208
+ const d = o || {}, p = n, s = d.minimal || d.features && d.features.minimal;
209
+ if (s)
210
+ this.features = Object.assign({}, pe, { floatingToolbar: !0, link: !0, linkTooltip: !0 }, d.features || {});
211
+ else {
212
+ const w = {};
213
+ Object.keys(pe).forEach((g) => {
214
+ g !== "minimal" && (w[g] = !0);
215
+ }), this.features = Object.assign({}, w, d.features || {});
216
+ }
217
+ this.options = {
218
+ sanitize: Object.assign({}, Ne, d.sanitize || {}),
219
+ urlSchemes: Array.isArray(d.allowedUrlSchemes) ? d.allowedUrlSchemes : Be,
220
+ imageSchemes: Array.isArray(d.allowedImageSchemes) ? d.allowedImageSchemes : ze,
221
+ iframeAllowlist: Array.isArray(d.iframeAllowlist) ? d.iframeAllowlist : Ie,
222
+ iframeSandbox: typeof d.iframeSandbox == "string" ? d.iframeSandbox : _e,
223
+ iframeAllow: typeof d.iframeAllow == "string" ? d.iframeAllow : De,
224
+ readOnly: !!d.readOnly
225
+ };
226
+ const u = this;
227
+ function b(w, g) {
228
+ const M = new Set(g && g.allowedTags || []), y = new Set(g && g.allowedAttributes || []), h = document.createElement("div");
229
+ h.innerHTML = String(w || "");
230
+ const L = document.createTreeWalker(h, NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT, null), N = [], A = [];
231
+ for (; L.nextNode(); ) {
232
+ const C = L.currentNode;
233
+ if (C.nodeType === 8) {
234
+ A.push(C);
235
+ continue;
236
+ }
237
+ const I = C.tagName ? C.tagName.toLowerCase() : "";
238
+ if (I && !M.has(I)) {
239
+ N.push(C);
240
+ continue;
241
+ }
242
+ if (C.attributes && Array.prototype.slice.call(C.attributes).forEach((D) => {
243
+ const U = D.name.toLowerCase();
244
+ if (U.startsWith("on")) {
245
+ C.removeAttribute(D.name);
246
+ return;
247
+ }
248
+ if (!y.has(U)) {
249
+ C.removeAttribute(D.name);
250
+ return;
251
+ }
252
+ U === "href" && D.value && (k(D.value, u.options.urlSchemes) || C.removeAttribute(D.name)), U === "src" && D.value && I === "img" && (k(D.value, u.options.imageSchemes) || C.removeAttribute(D.name));
253
+ }), I === "iframe") {
254
+ const z = C.getAttribute("src") || "";
255
+ T(z) ? (u.options.iframeSandbox && C.setAttribute("sandbox", u.options.iframeSandbox), u.options.iframeAllow && C.setAttribute("allow", u.options.iframeAllow), C.setAttribute("frameborder", "0"), C.style.maxWidth = "100%", C.style.border = "0") : N.push(C);
256
+ }
257
+ }
258
+ return A.forEach((C) => {
259
+ C.parentNode && C.parentNode.removeChild(C);
260
+ }), N.forEach((C) => {
261
+ if (C.parentNode) {
262
+ for (; C.firstChild; )
263
+ C.parentNode.insertBefore(C.firstChild, C);
264
+ C.parentNode.removeChild(C);
265
+ }
266
+ }), h.innerHTML;
267
+ }
268
+ function k(w, g) {
269
+ try {
270
+ const M = new URL(w, window.location.origin);
271
+ return g.indexOf(M.protocol.replace(":", "")) !== -1;
272
+ } catch {
273
+ return !1;
274
+ }
275
+ }
276
+ function T(w) {
277
+ try {
278
+ const M = new URL(w, window.location.origin).hostname.toLowerCase();
279
+ return u.options.iframeAllowlist.some((y) => M === y || M.endsWith("." + y));
280
+ } catch {
281
+ return !1;
282
+ }
283
+ }
284
+ this.utils = { sanitizeHTML: b, isSafeUrl: k, isAllowedIframeUrl: T };
285
+ const x = r.pluginManager.getToolbarHTML(u.features, d.toolbar), m = r.pluginManager.getModalHTML(u.features), v = document.createElement("div");
286
+ v.innerHTML = Re(x, m), n.style.display = "none", n.parentNode.insertBefore(v, n.nextSibling);
287
+ const l = v.querySelector(".te-editor"), f = v.querySelector(".te-toolbar");
288
+ try {
289
+ const w = p.value || "", g = b(w, u.options.sanitize);
290
+ l.innerHTML = g;
291
+ } catch {
292
+ }
293
+ try {
294
+ V(l), J(l);
295
+ } catch {
296
+ }
297
+ try {
298
+ J(l);
299
+ } catch {
300
+ }
301
+ d.height && (l.style.height = typeof d.height == "number" ? d.height + "px" : String(d.height), l.style.overflow = "auto"), this.container = v, this.editor = l, this.toolbar = f, this.textarea = p;
302
+ try {
303
+ document.execCommand("defaultParagraphSeparator", !1, "p");
304
+ } catch {
305
+ }
306
+ function S() {
307
+ try {
308
+ ["bold", "italic", "underline", "strikeThrough"].forEach((z) => {
309
+ const D = f.querySelector('[data-cmd="' + z + '"]');
310
+ D && (document.queryCommandState(z) ? D.classList.add("active") : D.classList.remove("active"));
311
+ });
312
+ const w = f.querySelector('[data-cmd="undo"]'), g = f.querySelector('[data-cmd="redo"]'), M = l._tableHist;
313
+ if (w) {
314
+ const z = document.queryCommandEnabled("undo") || M && M.undo.length > 0;
315
+ w.toggleAttribute("disabled", !z);
316
+ }
317
+ if (g) {
318
+ const z = document.queryCommandEnabled("redo") || M && M.redo.length > 0;
319
+ g.toggleAttribute("disabled", !z);
320
+ }
321
+ const y = window.getSelection();
322
+ let h = y && y.anchorNode;
323
+ h && h.nodeType === 3 && (h = h.parentNode);
324
+ const L = h, N = L && L.closest && L.closest("ol"), A = L && L.closest && L.closest("ul"), C = f.querySelector('[data-cmd="insertOrderedList"]'), I = f.querySelector('[data-cmd="insertUnorderedList"]');
325
+ C && C.classList.toggle("active", !!N), I && I.classList.toggle("active", !!A);
326
+ } catch {
327
+ }
328
+ }
329
+ document.addEventListener("selectionchange", () => {
330
+ v.contains(document.activeElement) && S();
331
+ }), f.querySelectorAll("[data-cmd]").forEach((w) => {
332
+ w.addEventListener("click", () => {
333
+ const g = w.getAttribute("data-cmd"), M = w.getAttribute("data-val") || void 0;
334
+ if (g === "createLink" || g === "insertImage" || g === "insertIframe" || g === "insertTable" || g === "editSource" || g === "indent" || g === "outdent" || g === "findReplace" || g === "togglePastePlain" || g === "specialChars" || g === "fullscreen" || g === "emoji" || g === "codeBlock" || g === "toggleReadOnly" || g === "shortcutsHelp" || g === "alignLeft" || g === "alignCenter" || g === "alignRight" || g === "alignJustify" || g === "toggleDark" || g === "customizeShortcuts")
335
+ return;
336
+ function y() {
337
+ l.querySelectorAll(".te-fr-match, .te-fr-active").forEach((h) => {
338
+ const L = h.parentNode;
339
+ if (L) {
340
+ for (; h.firstChild; ) L.insertBefore(h.firstChild, h);
341
+ L.removeChild(h);
342
+ }
343
+ });
344
+ }
345
+ if (g === "undo") {
346
+ const h = l._tableHist;
347
+ if (h && h.undo.length) {
348
+ y(), h.redo.push(l.innerHTML), l.contentEditable = "false", l.innerHTML = h.undo.pop(), l.contentEditable = "true", y(), l.focus(), S();
349
+ return;
350
+ }
351
+ }
352
+ if (g === "redo") {
353
+ const h = l._tableHist;
354
+ if (h && h.redo.length) {
355
+ y(), h.undo.push(l.innerHTML), l.contentEditable = "false", l.innerHTML = h.redo.pop(), l.contentEditable = "true", y(), l.focus(), S();
356
+ return;
357
+ }
358
+ }
359
+ document.execCommand(g, !1, M), l.focus(), S();
360
+ });
361
+ }), v.querySelectorAll("[data-te-close]").forEach((w) => {
362
+ w.addEventListener("click", () => {
363
+ const g = w.closest(".te-modal");
364
+ g && g.classList.remove("is-open");
365
+ });
366
+ });
367
+ try {
368
+ J(l);
369
+ } catch {
370
+ }
371
+ function E() {
372
+ const w = window.getSelection();
373
+ w && w.rangeCount > 0 && (v.__savedRange = w.getRangeAt(0).cloneRange());
374
+ }
375
+ function q() {
376
+ const w = v.__savedRange;
377
+ if (!w) return;
378
+ const g = window.getSelection();
379
+ g && (g.removeAllRanges(), g.addRange(w));
380
+ }
381
+ function H(w) {
382
+ (r.onUploadImage || function(M, y) {
383
+ const h = new FileReader();
384
+ h.onload = () => {
385
+ y(h.result);
386
+ }, h.readAsDataURL(M);
387
+ })(w, (M) => {
388
+ if (!M) return;
389
+ const y = w.name || "", h = '<img src="' + M.replace(/"/g, "&quot;") + '" alt="' + y.replace(/"/g, "&quot;") + '" style="max-width:100%;" />';
390
+ document.execCommand("insertHTML", !1, h);
391
+ });
392
+ }
393
+ function B(w) {
394
+ if (!w) return "";
395
+ let g = String(w);
396
+ return g.indexOf("mso-") === -1 && g.indexOf("xmlns:o") === -1 && g.indexOf("google-docs") === -1 || (g = g.replace(/<!--[\s\S]*?-->/g, ""), g = g.replace(/<meta[^>]*>/gi, ""), g = g.replace(/<link[^>]*>/gi, ""), g = g.replace(/<o:[^>]*>[\s\S]*?<\/o:[^>]*>/gi, ""), g = g.replace(/<w:[^>]*>[\s\S]*?<\/w:[^>]*>/gi, ""), g = g.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, ""), g = g.replace(/ class="[^"]*Mso[^"]*"/gi, ""), g = g.replace(/ class="[^"]*" style=""/gi, ""), g = g.replace(/ style="[^"]*mso-[^;]*[^"]*"/gi, ""), g = g.replace(/<span[^>]*style="[^"]*mso-[^"]*"[^>]*>/gi, "<span>"), g = g.replace(/<span[^>]*><\/span>/gi, ""), g = g.replace(/(<(p|h[1-6]|div|span|b|i|u|strong|em))[^>]*>/gi, "$1>")), g;
397
+ }
398
+ l.addEventListener("paste", (w) => {
399
+ try {
400
+ const g = w.clipboardData && w.clipboardData.files;
401
+ if (g && g.length > 0) {
402
+ let A = !1;
403
+ for (let C = 0; C < g.length; C++)
404
+ /^image\//i.test(g[C].type) && (A || (w.preventDefault(), A = !0), H(g[C]));
405
+ if (A) return;
406
+ }
407
+ const M = w.clipboardData && w.clipboardData.items;
408
+ if (M && M.length > 0) {
409
+ for (let A = 0; A < M.length; A++)
410
+ if (M[A].kind === "file" && /^image\//i.test(M[A].type)) {
411
+ w.preventDefault();
412
+ const C = M[A].getAsFile();
413
+ C && H(C);
414
+ return;
415
+ }
416
+ }
417
+ window.navigator && window.navigator.clipboard && typeof window.navigator.clipboard.read == "function" && window.navigator.clipboard.read().then((A) => {
418
+ for (let C = 0; C < A.length; C++) {
419
+ const I = A[C].types || [];
420
+ for (let z = 0; z < I.length; z++)
421
+ if (/^image\//i.test(I[z])) {
422
+ A[C].getType(I[z]).then((D) => {
423
+ H(D);
424
+ });
425
+ break;
426
+ }
427
+ }
428
+ }).catch(() => {
429
+ }), w.preventDefault();
430
+ const y = w.clipboardData && w.clipboardData.getData("text/html") || "", h = w.clipboardData && w.clipboardData.getData("text/plain") || "", L = B(y) || (h ? "<p>" + h.replace(/\n/g, "<br>") + "</p>" : ""), N = b(L, u.options.sanitize);
431
+ document.execCommand("insertHTML", !1, N), setTimeout(() => {
432
+ try {
433
+ J(l), V(l);
434
+ } catch {
435
+ }
436
+ }, 0);
437
+ } catch {
438
+ setTimeout(() => {
439
+ V(l);
440
+ }, 0);
441
+ }
442
+ }), l.addEventListener("focus", () => {
443
+ try {
444
+ J(l);
445
+ } catch {
446
+ }
447
+ }), l.addEventListener("input", () => {
448
+ setTimeout(() => {
449
+ try {
450
+ J(l), V(l);
451
+ } catch {
452
+ }
453
+ }, 0);
454
+ });
455
+ const _ = {
456
+ wrapper: v,
457
+ editor: l,
458
+ toolbar: f,
459
+ textarea: p,
460
+ features: u.features,
461
+ options: u.options,
462
+ utils: u.utils,
463
+ TulihEditor: r,
464
+ saveSel: E,
465
+ restoreSel: q,
466
+ updateActiveStates: S
467
+ };
468
+ s && v.classList.add("te-minimal"), u._ctx = _, r.pluginManager.initAll(_), r.instances.push(this);
469
+ }
470
+ getContent() {
471
+ return this.editor ? this.editor.innerHTML : "";
472
+ }
473
+ setContent(t) {
474
+ if (!this.editor) return;
475
+ const o = this.utils.sanitizeHTML(t, this.options.sanitize);
476
+ this.editor.innerHTML = o;
477
+ try {
478
+ J(this.editor), V(this.editor);
479
+ } catch {
480
+ }
481
+ }
482
+ getText() {
483
+ return this.editor && this.editor.textContent || "";
484
+ }
485
+ getWordCount() {
486
+ const t = this.getText().trim();
487
+ return t ? t.split(/\s+/).length : 0;
488
+ }
489
+ getCharCount() {
490
+ return this.getText().length;
491
+ }
492
+ setReadOnly(t) {
493
+ if (!this._ctx) return;
494
+ const o = this._ctx, r = o.editor.contentEditable === "false";
495
+ if (t === r) return;
496
+ const n = o.wrapper.querySelector('[data-cmd="toggleReadOnly"]');
497
+ n && n.click();
498
+ }
499
+ isReadOnly() {
500
+ return !!(this._ctx && this._ctx.editor && this._ctx.editor.contentEditable === "false");
501
+ }
502
+ destroy() {
503
+ if (!this.container || !this.container.parentNode) return;
504
+ const t = this._ctx ? this._ctx.TulihEditor.instances : [], o = t.indexOf(this);
505
+ o !== -1 && t.splice(o, 1), this._ctx && this._ctx.TulihEditor.pluginManager.destroyAll(this._ctx);
506
+ const r = this.textarea;
507
+ r && this.editor && (r.value = this.editor.innerHTML, r.style.display = ""), this.container.parentNode.removeChild(this.container), this.editor = null, this.container = null, this.toolbar = null, this._ctx = null;
508
+ }
509
+ }
510
+ const Oe = {
511
+ name: "block",
512
+ order: 10,
513
+ toolbarHTML: '<select class="te-block form-select form-select-sm"> <option value="p">Paragraph</option> <option value="h1">Heading 1</option> <option value="h2">Heading 2</option> <option value="h3">Heading 3</option> <option value="h4">Heading 4</option> <option value="h5">Heading 5</option> <option value="h6">Heading 6</option> <option value="blockquote">Quote</option> <option value="pre">Code</option></select>',
514
+ init(e) {
515
+ if (!e.features.block) return;
516
+ const t = e.wrapper.querySelector(".te-block");
517
+ t && t.addEventListener("change", () => {
518
+ const o = t.value;
519
+ o && (document.execCommand("formatBlock", !1, o), e.editor.focus(), e.updateActiveStates());
520
+ });
521
+ }
522
+ }, je = {
523
+ name: "inline",
524
+ order: 20,
525
+ toolbarHTML: '<button type="button" class="btn btn-sm btn-light" title="Bold" data-cmd="bold"><i class="ti ti-bold"></i></button><button type="button" class="btn btn-sm btn-light" title="Italic" data-cmd="italic"><i class="ti ti-italic"></i></button><button type="button" class="btn btn-sm btn-light" title="Underline" data-cmd="underline"><i class="ti ti-underline"></i></button><button type="button" class="btn btn-sm btn-light" title="Strikethrough" data-cmd="strikeThrough"><s>S</s></button><div class="te-divider"></div><button type="button" class="btn btn-sm btn-light" title="Quote" data-cmd="formatBlock" data-val="blockquote"><strong>"</strong></button>',
526
+ init(e) {
527
+ }
528
+ }, Pe = {
529
+ name: "pre",
530
+ order: 21,
531
+ toolbarHTML: '<button type="button" class="btn btn-sm btn-light" title="Preformatted" data-cmd="formatBlock" data-val="pre"><i class="ti ti-code"></i></button>',
532
+ init(e) {
533
+ }
534
+ }, Ue = {
535
+ name: "inlineCode",
536
+ order: 22,
537
+ toolbarHTML: '<button type="button" class="btn btn-sm btn-light" title="Inline code" data-cmd="inlineCode"><i class="ti ti-code-circle"></i></button>',
538
+ init(e) {
539
+ if (e.features.inlineCode) {
540
+ var t = e.wrapper.querySelector('[data-cmd="inlineCode"]');
541
+ t && t.addEventListener("click", function() {
542
+ var o = ie(window.getSelection().toString() || "code"), r = "<code>" + o + "</code>";
543
+ document.execCommand("insertHTML", !1, r), e.editor.focus();
544
+ });
545
+ }
546
+ }
547
+ }, Fe = {
548
+ name: "subSuper",
549
+ order: 26,
550
+ toolbarHTML: '<button type="button" class="btn btn-sm btn-light" title="Subscript" data-cmd="subscript">x₂</button><button type="button" class="btn btn-sm btn-light" title="Superscript" data-cmd="superscript">x²</button>',
551
+ init(e) {
552
+ e.features.subSuper && e.wrapper.querySelectorAll('[data-cmd="subscript"],[data-cmd="superscript"]').forEach(function(t) {
553
+ t.addEventListener("click", function() {
554
+ document.execCommand(t.getAttribute("data-cmd"), !1, void 0), e.editor.focus();
555
+ });
556
+ });
557
+ }
558
+ };
559
+ var We = "te-shortcut-map", Je = {
560
+ Bold: { key: "b", ctrl: !0, shift: !1 },
561
+ Italic: { key: "i", ctrl: !0, shift: !1 },
562
+ Underline: { key: "u", ctrl: !0, shift: !1 },
563
+ Strike: { key: "s", ctrl: !0, shift: !1 },
564
+ Undo: { key: "z", ctrl: !0, shift: !1 },
565
+ Redo: { key: "z", ctrl: !0, shift: !0 },
566
+ RedoAlt: { key: "y", ctrl: !0, shift: !1 },
567
+ Link: { key: "k", ctrl: !0, shift: !1 }
568
+ };
569
+ function Xe() {
570
+ try {
571
+ var e = localStorage.getItem(We);
572
+ if (e) return JSON.parse(e);
573
+ } catch {
574
+ }
575
+ return JSON.parse(JSON.stringify(Je));
576
+ }
577
+ const Ke = {
578
+ name: "keyboardShortcuts",
579
+ order: 5,
580
+ init(e) {
581
+ if (e.features.keyboardShortcuts !== !1) {
582
+ var t = e.editor, o = Xe();
583
+ t.addEventListener("keydown", function(r) {
584
+ if (!(!r.ctrlKey && !r.metaKey))
585
+ for (var n in o) {
586
+ var a = o[n];
587
+ if (r.key.toLowerCase() === a.key && r.ctrlKey === a.ctrl && r.shiftKey === a.shift) {
588
+ if (r.preventDefault(), n === "Bold")
589
+ document.execCommand("bold");
590
+ else if (n === "Italic")
591
+ document.execCommand("italic");
592
+ else if (n === "Underline")
593
+ document.execCommand("underline");
594
+ else if (n === "Strike")
595
+ document.execCommand("strikeThrough");
596
+ else if (n === "Undo") {
597
+ var i = t._tableHist;
598
+ i && i.undo.length ? (t.querySelectorAll(".te-fr-match, .te-fr-active").forEach(function(d) {
599
+ var p = d.parentNode;
600
+ if (p) {
601
+ for (; d.firstChild; ) p.insertBefore(d.firstChild, d);
602
+ p.removeChild(d);
603
+ }
604
+ }), i.redo.push(t.innerHTML), t.contentEditable = "false", t.innerHTML = i.undo.pop(), t.contentEditable = "true", t.querySelectorAll(".te-fr-match, .te-fr-active").forEach(function(d) {
605
+ var p = d.parentNode;
606
+ if (p) {
607
+ for (; d.firstChild; ) p.insertBefore(d.firstChild, d);
608
+ p.removeChild(d);
609
+ }
610
+ }), t.focus()) : (document.execCommand("undo"), t.focus());
611
+ } else if (n === "Redo" || n === "RedoAlt") {
612
+ var i = t._tableHist;
613
+ i && i.redo.length ? (t.querySelectorAll(".te-fr-match, .te-fr-active").forEach(function(p) {
614
+ var s = p.parentNode;
615
+ if (s) {
616
+ for (; p.firstChild; ) s.insertBefore(p.firstChild, p);
617
+ s.removeChild(p);
618
+ }
619
+ }), i.undo.push(t.innerHTML), t.contentEditable = "false", t.innerHTML = i.redo.pop(), t.contentEditable = "true", t.querySelectorAll(".te-fr-match, .te-fr-active").forEach(function(p) {
620
+ var s = p.parentNode;
621
+ if (s) {
622
+ for (; p.firstChild; ) s.insertBefore(p.firstChild, p);
623
+ s.removeChild(p);
624
+ }
625
+ }), t.focus()) : (document.execCommand("redo"), t.focus());
626
+ } else if (n === "Link") {
627
+ var c = e.wrapper.querySelector('[data-cmd="createLink"]');
628
+ c && c.click();
629
+ }
630
+ return;
631
+ }
632
+ }
633
+ });
634
+ }
635
+ }
636
+ };
637
+ function fe(e, t) {
638
+ var o = e.wrapper.querySelector('[data-cmd="toggleReadOnly"]');
639
+ t ? (e.editor.contentEditable = "false", e.wrapper.classList.add("te-readonly"), o && (o.innerHTML = '<i class="ti ti-lock-open"></i>')) : (e.editor.contentEditable = "true", e.wrapper.classList.remove("te-readonly"), o && (o.innerHTML = '<i class="ti ti-lock"></i>')), o && o.classList.toggle("active", t);
640
+ }
641
+ const $e = {
642
+ name: "readOnly",
643
+ order: 75,
644
+ css: ".te-readonly-btn.active { background: #fff3cd; border-color: #ffecb5; }.te-readonly .te-toolbar select,.te-readonly .te-toolbar input,.te-readonly .te-toolbar .btn { opacity: .5; pointer-events: none;}.te-readonly .te-editor { background: #f8f9fa; cursor: default; }",
645
+ toolbarHTML: "",
646
+ init(e) {
647
+ if (e.features.readOnly !== !1) {
648
+ e.options.readOnly && fe(e, !0);
649
+ var t = e.wrapper.querySelector('[data-cmd="toggleReadOnly"]');
650
+ t && t.addEventListener("click", function() {
651
+ var o = e.editor.contentEditable !== "false";
652
+ fe(e, !o);
653
+ });
654
+ }
655
+ }
656
+ }, Ye = {
657
+ name: "linkTooltip",
658
+ order: 4,
659
+ css: ".te-link-tooltip { position: fixed; z-index: 9999; background: #333; color: #fff; padding: 4px 8px; border-radius: 4px; font-size: .75rem; line-height: 1.4; max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; pointer-events: none; opacity: 0; transition: opacity .15s;}.te-link-tooltip.show { opacity: 1; }",
660
+ init(e) {
661
+ if (e.features.linkTooltip === !1) return;
662
+ var t = e.editor, o = document.createElement("div");
663
+ o.className = "te-link-tooltip", document.body.appendChild(o);
664
+ var r = null;
665
+ t.addEventListener("mouseover", function(i) {
666
+ var c = i.target && i.target.closest && i.target.closest("a");
667
+ if (!c || !t.contains(c)) {
668
+ a();
669
+ return;
670
+ }
671
+ clearTimeout(r);
672
+ var d = c.getAttribute("href") || "";
673
+ o.textContent = d, n(i), o.classList.add("show");
674
+ }), t.addEventListener("mousemove", function(i) {
675
+ o.classList.contains("show") && n(i);
676
+ }), t.addEventListener("mouseout", function(i) {
677
+ var c = i.target && i.target.closest && i.target.closest("a");
678
+ c && (r = setTimeout(a, 200));
679
+ });
680
+ function n(i) {
681
+ var c = i.clientX + 12, d = i.clientY + 12;
682
+ c + 310 > window.innerWidth && (c = window.innerWidth - 310), d + 30 > window.innerHeight && (d = i.clientY - 30), o.style.left = c + "px", o.style.top = d + "px";
683
+ }
684
+ function a() {
685
+ o.classList.remove("show");
686
+ }
687
+ }
688
+ };
689
+ var Ge = "😀😃😄😁😆😅🤣😂🙂🙃😉😊😇🥰😍🤩😘😗😚😋😛😜🤪😝🤑🤗🤭🤫🤔🤐🤨😐😑😶😏😒🙄😬🤥😌😔😪🤤😴😷🤒🤕🤢🤮🤧🥵🥶🥴😵🤯🤠🥳🥸😎🤓🧐😕😟🙁😮😯😲😳🥺😦😧😨😰😥😢😭😱😖😣😞😓😩😫🥱😤😡😠🤬😈👿💀☠💩🤡👹👺👻👽👾🤖".match(/.{1,2}/g) || [], Ve = {
690
+ "😀": "grinning laugh happy",
691
+ "😃": "grinning smile",
692
+ "😄": "smile happy",
693
+ "😁": "beaming grin",
694
+ "😆": "laughing grinning",
695
+ "🤣": "rolling floor laugh",
696
+ "😂": "tears joy cry",
697
+ "🙂": "slight smile",
698
+ "🙃": "upside down",
699
+ "😉": "winking wink",
700
+ "😊": "blush smile",
701
+ "😇": "innocent angel",
702
+ "🥰": "love heart",
703
+ "😍": "heart eyes",
704
+ "🤩": "star struck",
705
+ "😘": "kiss blowing",
706
+ "😗": "kissing",
707
+ "😚": "kiss closed",
708
+ "😋": "savor yum",
709
+ "😛": "tongue",
710
+ "😜": "wink tongue silly",
711
+ "🤪": "crazy wild",
712
+ "😝": "squint tongue",
713
+ "🤑": "money tongue",
714
+ "🤗": "hug",
715
+ "🤭": "hand over mouth secret",
716
+ "🤫": "shush quiet silent",
717
+ "🤔": "thinking think",
718
+ "🤐": "zipper mouth secret",
719
+ "🤨": "raised eyebrow suspicious",
720
+ "😐": "neutral straight",
721
+ "😑": "expressionless blank",
722
+ "😶": "no mouth silent",
723
+ "😏": "smirk smug",
724
+ "😒": "unamified",
725
+ "🙄": "eye roll",
726
+ "😬": "grimace awkward",
727
+ "🤥": "lying liar nose",
728
+ "😌": "relieved",
729
+ "😔": "pensive sad",
730
+ "😪": "sleepy tired",
731
+ "🤤": "drooling",
732
+ "😴": "sleeping zzz",
733
+ "😷": "mask sick",
734
+ "🤒": "fever",
735
+ "🤕": "hurt bandage",
736
+ "🤢": "nauseous sick",
737
+ "🤮": "vomiting",
738
+ "🤧": "sneeze",
739
+ "🥵": "hot sweat",
740
+ "🥶": "cold freeze",
741
+ "🥴": "dizzy",
742
+ "😵": "dizzy confused",
743
+ "🤯": "mind blown exploding",
744
+ "🤠": "cowboy",
745
+ "🥳": "party celebration",
746
+ "🥸": "disguise",
747
+ "😎": "sunglasses cool",
748
+ "🤓": "nerd geek",
749
+ "🧐": "monocle",
750
+ "😕": "confused",
751
+ "😟": "worried",
752
+ "🙁": "frown sad",
753
+ "😮": "surprised shock",
754
+ "😯": "hushed",
755
+ "😲": "astonished",
756
+ "😳": "flushed embarrassed",
757
+ "🥺": "pleading puppy eyes",
758
+ "😦": "frown",
759
+ "😧": "anguish",
760
+ "😨": "fearful afraid",
761
+ "😰": "anxious worry",
762
+ "😥": "disappointed",
763
+ "😢": "cry sad tear",
764
+ "😭": "sobbing cry",
765
+ "😱": "scream horror",
766
+ "😖": "confounded",
767
+ "😣": "struggle",
768
+ "😞": "disappointed",
769
+ "😓": "sweat",
770
+ "😩": "weary",
771
+ "😫": "tired exhausted",
772
+ "🥱": "yawn sleepy",
773
+ "😤": "frustrated",
774
+ "😡": "angry rage",
775
+ "😠": "angry mad",
776
+ "🤬": "cursing swear",
777
+ "😈": "devil evil grin",
778
+ "👿": "devil evil angry",
779
+ "💀": "skull death",
780
+ "☠": "skull crossbones danger",
781
+ "💩": "poop",
782
+ "🤡": "clown",
783
+ "👹": "ogre monster",
784
+ "👺": "goblin",
785
+ "👻": "ghost halloween",
786
+ "👽": "alien ufo",
787
+ "👾": "alien monster",
788
+ "🤖": "robot",
789
+ "💋": "kiss lips",
790
+ "👋": "wave hello bye",
791
+ "✋": "raised hand stop",
792
+ "👌": "ok perfect",
793
+ "🤏": "pinching small",
794
+ "🤞": "crossed fingers luck",
795
+ "🤟": "love gesture",
796
+ "🤘": "horns rock",
797
+ "🤙": "call me",
798
+ "👈": "point left",
799
+ "👉": "point right",
800
+ "👆": "point up",
801
+ "🖕": "middle finger",
802
+ "👍": "thumbs up like",
803
+ "👎": "thumbs down dislike",
804
+ "✊": "fist raised power",
805
+ "👊": "fist punch",
806
+ "🤛": "fist left",
807
+ "🤜": "fist right",
808
+ "👏": "clap applause",
809
+ "🙌": "celebration",
810
+ "👐": "open hands",
811
+ "🤲": "palms together pray",
812
+ "🤝": "handshake deal",
813
+ "🙏": "pray please thank",
814
+ "✍": "writing",
815
+ "💅": "nail polish",
816
+ "👂": "ear listen",
817
+ "👃": "nose smell",
818
+ "👣": "footsteps",
819
+ "👀": "eyes",
820
+ "👅": "tongue",
821
+ "👄": "mouth lips"
822
+ };
823
+ const Ze = {
824
+ name: "emojiAutocomplete",
825
+ order: 6,
826
+ css: ".te-emoji-ac { position: fixed; z-index: 9999; background: #fff; border: 1px solid #dee2e6; border-radius: .375rem; box-shadow: 0 6px 20px rgba(0,0,0,.15); padding: .25rem; display: none; max-height: 160px; overflow-y: auto; min-width: 120px;}.te-emoji-ac-item { display: flex; align-items: center; gap: 6px; padding: 4px 8px; cursor: pointer; border-radius: .25rem; font-size: 1rem;}.te-emoji-ac-item:hover, .te-emoji-ac-item.active { background: #e7f1ff;}",
827
+ init(e) {
828
+ if (e.features.emojiAutocomplete === !1) return;
829
+ var t = e.editor, o = document.createElement("div");
830
+ o.className = "te-emoji-ac", document.body.appendChild(o);
831
+ var r = "", n = 0, a = [];
832
+ function i(s) {
833
+ s = s || "", o.innerHTML = "", a = [], n = 0;
834
+ var u = s.toLowerCase();
835
+ if (Ge.forEach(function(b) {
836
+ var k = (Ve[b] || "").toLowerCase();
837
+ if (!(u && k.indexOf(u) === -1)) {
838
+ var T = document.createElement("div");
839
+ T.className = "te-emoji-ac-item", T.textContent = b, T.setAttribute("data-emoji", b), o.appendChild(T);
840
+ }
841
+ }), a = Array.prototype.slice.call(o.children), a.length === 0) {
842
+ o.style.display = "none";
843
+ return;
844
+ }
845
+ a[0].classList.add("active"), o.style.display = "block", c();
846
+ }
847
+ function c() {
848
+ var s = window.getSelection();
849
+ if (!(!s || !s.rangeCount)) {
850
+ var u = s.getRangeAt(0), b = u.getBoundingClientRect();
851
+ o.style.left = Math.max(4, b.left) + "px", o.style.top = b.bottom + 4 + "px";
852
+ var k = o.getBoundingClientRect();
853
+ k.right > window.innerWidth - 4 && (o.style.left = window.innerWidth - k.width - 4 + "px"), k.bottom > window.innerHeight - 4 && (o.style.top = b.top - k.height - 4 + "px");
854
+ }
855
+ }
856
+ function d(s) {
857
+ t.focus();
858
+ var u = window.getSelection();
859
+ if (u && u.rangeCount > 0 && r) {
860
+ var b = u.getRangeAt(0), k = r.length + 1;
861
+ b.startOffset >= k && b.startContainer.nodeType === 3 && (b.setStart(b.startContainer, b.startOffset - k), b.deleteContents());
862
+ }
863
+ document.execCommand("insertText", !1, s), o.style.display = "none", r = "";
864
+ }
865
+ function p(s) {
866
+ a.length !== 0 && (a[n].classList.remove("active"), n = (n + s + a.length) % a.length, a[n].classList.add("active"), a[n].scrollIntoView({ block: "nearest" }));
867
+ }
868
+ t.addEventListener("keydown", function(s) {
869
+ if (o.style.display !== "none") {
870
+ if (s.key === "ArrowDown") {
871
+ s.preventDefault(), p(1);
872
+ return;
873
+ }
874
+ if (s.key === "ArrowUp") {
875
+ s.preventDefault(), p(-1);
876
+ return;
877
+ }
878
+ if (s.key === "Enter" || s.key === "Tab") {
879
+ s.preventDefault();
880
+ var u = o.querySelector(".active");
881
+ if (u) {
882
+ var b = u.getAttribute("data-emoji");
883
+ b && d(b);
884
+ }
885
+ return;
886
+ }
887
+ if (s.key === "Escape") {
888
+ o.style.display = "none", r = "";
889
+ return;
890
+ }
891
+ }
892
+ }), t.addEventListener("input", function() {
893
+ var s = window.getSelection();
894
+ if (!(!s || !s.rangeCount || !s.anchorNode)) {
895
+ var u = s.anchorNode, b = u.textContent || "", k = s.anchorOffset, T = b.slice(0, k), x = T.lastIndexOf(":");
896
+ if (x !== -1 && T.indexOf(" ", x) === -1 && x !== k - 1) {
897
+ if (r = T.slice(x + 1), r.indexOf(":") !== -1) {
898
+ o.style.display = "none";
899
+ return;
900
+ }
901
+ i(r);
902
+ } else x !== -1 && x === k - 1 ? (r = "", i("")) : (o.style.display = "none", r = "");
903
+ }
904
+ }), o.addEventListener("mousedown", function(s) {
905
+ var u = s.target && s.target.closest && s.target.closest(".te-emoji-ac-item");
906
+ if (u) {
907
+ s.preventDefault();
908
+ var b = u.getAttribute("data-emoji");
909
+ b && d(b);
910
+ }
911
+ });
912
+ }
913
+ }, Qe = {
914
+ name: "statusBar",
915
+ order: 100,
916
+ css: ".te-statusbar { display: flex; justify-content: space-between; gap: 1rem; padding: 4px 8px; font-size: .75rem; color: #6c757d; background: #f8f9fa; border: 1px solid #dee2e6; border-top: none; border-radius: 0 0 .375rem .375rem;}.te-statusbar .te-status-tag { font-weight: 600; font-family: monospace;}",
917
+ init(e) {
918
+ if (e.features.statusBar === !1) return;
919
+ var t = e.editor, o = document.createElement("div");
920
+ o.className = "te-statusbar", o.innerHTML = '<span class="te-status-tag"></span><span class="te-status-right"><span class="te-status-words">0 words</span><span class="te-status-chars">0 characters</span></span>', t.parentNode.insertBefore(o, t.nextSibling);
921
+ function r() {
922
+ var a = window.getSelection();
923
+ if (!a || a.rangeCount === 0) return "";
924
+ var i = a.anchorNode;
925
+ if (i && i.nodeType === 3 && (i = i.parentNode), !i || !t.contains(i)) return "";
926
+ for (var c = "", d = i; d && d !== t; ) {
927
+ var p = d.tagName ? d.tagName.toLowerCase() : "";
928
+ if (["p", "h1", "h2", "h3", "h4", "h5", "h6", "div", "blockquote", "pre", "li", "td", "th", "ol", "ul", "table", "thead", "tbody", "tfoot", "tr"].indexOf(p) !== -1) {
929
+ c = p;
930
+ break;
931
+ }
932
+ d = d.parentElement;
933
+ }
934
+ return c;
935
+ }
936
+ function n() {
937
+ var a = window.getSelection(), i = a && !a.isCollapsed && t.contains(a.anchorNode) && t.contains(a.focusNode), c = t.textContent || "", d = c.trim() ? c.trim().split(/\s+/).length : 0, p = c.length, s = o.querySelector(".te-status-tag"), u = o.querySelector(".te-status-right");
938
+ if (s && (s.textContent = r()), u) {
939
+ var b = u.querySelector(".te-status-words"), k = u.querySelector(".te-status-chars");
940
+ if ((!b || !k) && (u.innerHTML = '<span class="te-status-words"></span><span class="te-status-chars"></span>', b = u.querySelector(".te-status-words"), k = u.querySelector(".te-status-chars")), b && (b.textContent = d + " word" + (d !== 1 ? "s" : "")), k && (k.textContent = p + " character" + (p !== 1 ? "s" : "")), i) {
941
+ var T = a.toString(), x = T.trim() ? T.trim().split(/\s+/).length : 0, m = x + " word" + (x !== 1 ? "s" : "") + ", " + T.length + " char selected | " + d + " word" + (d !== 1 ? "s" : "") + ", " + p + " characters";
942
+ b && (b.style.display = "none"), k && (k.textContent = m);
943
+ } else
944
+ b && (b.style.display = "");
945
+ }
946
+ }
947
+ t.addEventListener("input", n), t.addEventListener("paste", function() {
948
+ setTimeout(n, 100);
949
+ }), document.addEventListener("selectionchange", function() {
950
+ (document.activeElement === t || t.contains(document.activeElement)) && n();
951
+ }), n();
952
+ }
953
+ };
954
+ var et = [
955
+ { id: "none", label: "Plain text" },
956
+ { id: "markup", label: "HTML" },
957
+ { id: "css", label: "CSS" },
958
+ { id: "javascript", label: "JavaScript" },
959
+ { id: "php", label: "PHP" },
960
+ { id: "python", label: "Python" },
961
+ { id: "java", label: "Java" },
962
+ { id: "c", label: "C" },
963
+ { id: "cpp", label: "C++" },
964
+ { id: "sql", label: "SQL" },
965
+ { id: "bash", label: "Bash" },
966
+ { id: "json", label: "JSON" },
967
+ { id: "typescript", label: "TypeScript" },
968
+ { id: "go", label: "Go" },
969
+ { id: "rust", label: "Rust" },
970
+ { id: "ruby", label: "Ruby" }
971
+ ];
972
+ const tt = {
973
+ name: "codeBlock",
974
+ order: 23,
975
+ css: '.te-codeblock-popup { position: absolute; z-index: 3000; background: #fff; border: 1px solid #dee2e6; border-radius: .375rem; box-shadow: 0 6px 20px rgba(0,0,0,.15); padding: .5rem; min-width: 160px;}.te-codeblock-popup select { width: 100%; margin-bottom: .5rem;}.te-codeblock-popup .btn { width: 100%; }.te-editor pre { background: #1e1e2e; border: 1px solid #45475a; border-left: 4px solid #89b4fa; border-radius: .375rem; padding: .75rem; overflow-x: auto; margin: .5rem 0; font-family: "JetBrains Mono", "Fira Code", "Cascadia Code", Consolas, monospace; font-size: .875rem; line-height: 1.6; color: #cdd6f4;}.te-editor pre code { background: none; padding: 0; font-size: inherit; line-height: inherit; color: inherit;}',
976
+ toolbarHTML: '<button type="button" class="btn btn-sm btn-light" title="Code block" data-cmd="codeBlock"><i class="ti ti-codeblock"></i></button>',
977
+ init(e) {
978
+ if (e.features.codeBlock !== !1) {
979
+ var t = e.wrapper.querySelector('[data-cmd="codeBlock"]');
980
+ if (t) {
981
+ var o = document.createElement("div");
982
+ o.className = "te-codeblock-popup", o.style.display = "none", o.innerHTML = '<select class="te-codeblock-lang form-select form-select-sm">' + et.map(function(r) {
983
+ return '<option value="' + r.id + '">' + r.label + "</option>";
984
+ }).join("") + '</select><button type="button" class="btn btn-sm btn-primary te-codeblock-insert">Insert</button>', document.body.appendChild(o), t.addEventListener("click", function(r) {
985
+ var n = t.getBoundingClientRect();
986
+ o.style.left = window.scrollX + n.left + "px", o.style.top = window.scrollY + n.bottom + 4 + "px", o.style.display = o.style.display === "none" ? "block" : "none";
987
+ }), o.querySelector(".te-codeblock-insert").addEventListener("click", function() {
988
+ var r = o.querySelector(".te-codeblock-lang").value, n = window.getSelection(), a = n ? n.toString() : "";
989
+ a || (a = "code");
990
+ var i = r && r !== "none" ? ' class="language-' + r + '"' : "", c = "<pre><code" + i + ">" + a.replace(/</g, "&lt;").replace(/>/g, "&gt;") + "</code></pre>";
991
+ document.execCommand("insertHTML", !1, c), o.style.display = "none", e.editor.focus();
992
+ }), document.addEventListener("click", function(r) {
993
+ o.style.display !== "none" && !o.contains(r.target) && r.target !== t && (o.style.display = "none");
994
+ });
995
+ }
996
+ }
997
+ }
998
+ };
999
+ var te = [
1000
+ {
1001
+ match: /(?:https?:\/\/)?(?:www\.)?(?:youtube\.com\/(?:watch\?v=|embed\/|shorts\/)|youtu\.be\/)([a-zA-Z0-9_-]{11})/,
1002
+ embed: function(e) {
1003
+ return '<iframe src="https://www.youtube.com/embed/' + e + '" style="max-width:100%;border:0;aspect-ratio:16/9;" allowfullscreen></iframe>';
1004
+ }
1005
+ },
1006
+ {
1007
+ match: /(?:https?:\/\/)?(?:www\.)?vimeo\.com\/(\d+)/,
1008
+ embed: function(e) {
1009
+ return '<iframe src="https://player.vimeo.com/video/' + e + '" style="max-width:100%;border:0;aspect-ratio:16/9;" allowfullscreen></iframe>';
1010
+ }
1011
+ }
1012
+ ];
1013
+ const rt = {
1014
+ name: "mediaEmbed",
1015
+ order: 2,
1016
+ init(e) {
1017
+ if (e.features.mediaEmbed !== !1) {
1018
+ var t = e.editor;
1019
+ t.addEventListener("paste", function(o) {
1020
+ var r = o.clipboardData && o.clipboardData.getData("text/plain") || "";
1021
+ if (r) {
1022
+ r = r.trim();
1023
+ for (var n = 0; n < te.length; n++) {
1024
+ var a = r.match(te[n].match);
1025
+ if (a && a[1]) {
1026
+ o.preventDefault(), o.stopImmediatePropagation();
1027
+ var i = te[n].embed(a[1]);
1028
+ document.execCommand("insertHTML", !1, i), setTimeout(function() {
1029
+ try {
1030
+ V(t), J(t);
1031
+ } catch {
1032
+ }
1033
+ }, 0);
1034
+ return;
1035
+ }
1036
+ }
1037
+ }
1038
+ }, !0);
1039
+ }
1040
+ }
1041
+ }, ot = {
1042
+ name: "dragDrop",
1043
+ order: 3,
1044
+ css: ".te-editor.te-dragover { outline: 3px dashed rgba(13,110,253,.5); outline-offset: -6px; background: rgba(13,110,253,.03);}",
1045
+ init(e) {
1046
+ if (e.features.dragDrop === !1) return;
1047
+ var t = e.editor;
1048
+ function o(n) {
1049
+ return n && /^image\/(png|jpe?g|gif|webp|svg\+xml|bmp)$/i.test(n.type);
1050
+ }
1051
+ function r(n, a) {
1052
+ var i = new FileReader();
1053
+ i.onload = function() {
1054
+ a(i.result);
1055
+ }, i.readAsDataURL(n);
1056
+ }
1057
+ t.addEventListener("dragenter", function(n) {
1058
+ n.preventDefault(), n.stopPropagation(), t.classList.add("te-dragover");
1059
+ }), t.addEventListener("dragover", function(n) {
1060
+ n.preventDefault(), n.stopPropagation();
1061
+ }), t.addEventListener("dragleave", function(n) {
1062
+ n.preventDefault(), n.stopPropagation(), t.contains(n.relatedTarget) || t.classList.remove("te-dragover");
1063
+ }), t.addEventListener("drop", function(n) {
1064
+ n.preventDefault(), n.stopPropagation(), t.classList.remove("te-dragover");
1065
+ var a = n.dataTransfer && n.dataTransfer.files;
1066
+ if (!(!a || a.length === 0))
1067
+ for (var i = 0; i < a.length; i++) {
1068
+ var c = a[i];
1069
+ if (o(c)) {
1070
+ var d = e.TulihEditor && e.TulihEditor.onUploadImage || r;
1071
+ d(c, function(p) {
1072
+ if (p) {
1073
+ var s = '<img src="' + p.replace(/"/g, "&quot;") + '" alt="' + (c.name || "").replace(/"/g, "&quot;") + '" style="max-width:100%;" />';
1074
+ document.execCommand("insertHTML", !1, s);
1075
+ }
1076
+ });
1077
+ }
1078
+ }
1079
+ });
1080
+ }
1081
+ }, nt = {
1082
+ name: "pastePlain",
1083
+ order: 24,
1084
+ css: ".te-pasteplain-btn.active { background: #e7f1ff; border-color: #b6d4fe; }",
1085
+ toolbarHTML: '<button type="button" class="btn btn-sm btn-light te-pasteplain-btn" title="Paste as plain text" data-cmd="togglePastePlain"><i class="ti ti-clipboard"></i></button>',
1086
+ init(e) {
1087
+ if (e.features.pastePlain) {
1088
+ var t = e.editor;
1089
+ e._pastePlain = !1;
1090
+ var o = e.wrapper.querySelector('[data-cmd="togglePastePlain"]');
1091
+ o && o.addEventListener("click", function() {
1092
+ e._pastePlain = !e._pastePlain, o.classList.toggle("active", e._pastePlain);
1093
+ }), t.addEventListener("paste", function(r) {
1094
+ if (e._pastePlain) {
1095
+ r.stopImmediatePropagation(), r.preventDefault();
1096
+ var n = r.clipboardData && r.clipboardData.getData("text/plain") || "";
1097
+ if (n) {
1098
+ var a = ie(n), i = "<p>" + a.replace(/\n{2,}/g, "</p><p>").replace(/\n/g, "<br>") + "</p>";
1099
+ document.execCommand("insertHTML", !1, i);
1100
+ }
1101
+ setTimeout(function() {
1102
+ try {
1103
+ V(t), J(t);
1104
+ } catch {
1105
+ }
1106
+ }, 0);
1107
+ }
1108
+ }, !0);
1109
+ }
1110
+ }
1111
+ }, at = {
1112
+ name: "findReplace",
1113
+ order: 31,
1114
+ css: ".te-fr-popup { position: absolute; z-index: 3000; background: #fff; border: 1px solid #dee2e6; border-radius: .5rem; box-shadow: 0 6px 20px rgba(0,0,0,.15); padding: .75rem; width: 320px;}.te-fr-popup .te-fr-row { display: flex; gap: .5rem; margin-bottom: .5rem; }.te-fr-popup .te-fr-row:last-child { margin-bottom: 0; }.te-fr-popup input { flex: 1; }.te-fr-popup .btn { white-space: nowrap; }.te-fr-count { font-size: .8rem; color: #6c757d; padding: .25rem .5rem; }.te-fr-match { background: #fff3cd; outline: 2px solid #ffc107; }.te-fr-active { background: #f0ad4e; outline: 2px solid #e68600; }",
1115
+ toolbarHTML: '<button type="button" class="btn btn-sm btn-light" title="Find & Replace" data-cmd="findReplace"><i class="ti ti-search"></i></button>',
1116
+ init(e) {
1117
+ if (!e.features.findReplace) return;
1118
+ var t = e.editor, o = document.createElement("div");
1119
+ o.className = "te-fr-popup", o.style.display = "none", o.innerHTML = '<div class="te-fr-row"><input type="text" class="form-control form-control-sm te-fr-find" placeholder="Find..." /><button type="button" class="btn btn-sm btn-outline-primary te-fr-prev" title="Previous">&uarr;</button><button type="button" class="btn btn-sm btn-primary te-fr-next" title="Next">&darr;</button></div><div class="te-fr-row"><input type="text" class="form-control form-control-sm te-fr-replace" placeholder="Replace..." /><button type="button" class="btn btn-sm btn-outline-secondary te-fr-replace-btn">Replace</button><button type="button" class="btn btn-sm btn-outline-secondary te-fr-replace-all">All</button></div><div class="te-fr-row"><span class="te-fr-count"></span><button type="button" class="btn btn-sm btn-outline-secondary te-fr-close ms-auto" title="Close">&times;</button></div>', document.body.appendChild(o);
1120
+ var r = o.querySelector(".te-fr-find"), n = o.querySelector(".te-fr-replace"), a = o.querySelector(".te-fr-count");
1121
+ function i(f) {
1122
+ return f.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1123
+ }
1124
+ function c() {
1125
+ t.querySelectorAll(".te-fr-match, .te-fr-active").forEach(function(f) {
1126
+ var S = f.parentNode;
1127
+ if (S) {
1128
+ for (; f.firstChild; ) S.insertBefore(f.firstChild, f);
1129
+ S.removeChild(f);
1130
+ }
1131
+ }), t.normalize();
1132
+ }
1133
+ function d(f) {
1134
+ if (t.querySelectorAll(".te-fr-active").forEach(function(q) {
1135
+ q.classList.remove("te-fr-active"), q.classList.add("te-fr-match");
1136
+ }), !!f) {
1137
+ f.classList.remove("te-fr-match"), f.classList.add("te-fr-active"), f.scrollIntoView({ block: "nearest" });
1138
+ var S = document.createRange();
1139
+ S.selectNodeContents(f);
1140
+ var E = window.getSelection();
1141
+ E.removeAllRanges(), E.addRange(S);
1142
+ }
1143
+ }
1144
+ var p = [], s = -1;
1145
+ function u() {
1146
+ c();
1147
+ var f = r.value.trim();
1148
+ if (f) {
1149
+ for (var S = [], E = document.createTreeWalker(t, NodeFilter.SHOW_TEXT, null); E.nextNode(); ) S.push(E.currentNode);
1150
+ p = [], S.forEach(function(q) {
1151
+ for (var H = q.textContent, B = new RegExp(i(f), "gi"), _ = [], w; (w = B.exec(H)) !== null; )
1152
+ _.push({ idx: w.index, len: w[0].length });
1153
+ for (var g = _.length - 1; g >= 0; g--) {
1154
+ var M = _[g], y = document.createElement("span");
1155
+ y.className = "te-fr-match", y.textContent = H.substring(M.idx, M.idx + M.len), q.splitText(M.idx + M.len);
1156
+ var h = q.splitText(M.idx);
1157
+ h.parentNode.replaceChild(y, h), p.push(y);
1158
+ }
1159
+ }), a.textContent = p.length + " matches";
1160
+ }
1161
+ }
1162
+ function b() {
1163
+ if (p.length)
1164
+ s = (s + 1) % p.length;
1165
+ else {
1166
+ if (u(), !p.length) return;
1167
+ s = 0;
1168
+ }
1169
+ d(p[s]);
1170
+ }
1171
+ function k() {
1172
+ if (p.length)
1173
+ s = (s - 1 + p.length) % p.length;
1174
+ else {
1175
+ if (u(), !p.length) return;
1176
+ s = p.length - 1;
1177
+ }
1178
+ d(p[s]);
1179
+ }
1180
+ function T(f) {
1181
+ u(), p.length && (s = 0, d(p[s]));
1182
+ }
1183
+ o.querySelector(".te-fr-next").addEventListener("click", b), o.querySelector(".te-fr-prev").addEventListener("click", k);
1184
+ function x() {
1185
+ o.style.display = "none", c(), t.focus();
1186
+ }
1187
+ r.addEventListener("input", function() {
1188
+ u();
1189
+ }), r.addEventListener("keydown", function(f) {
1190
+ f.key === "Enter" && (f.preventDefault(), T()), f.key === "Escape" && (f.preventDefault(), x());
1191
+ }), n.addEventListener("keydown", function(f) {
1192
+ f.key === "Enter" && (f.preventDefault(), o.querySelector(".te-fr-replace-btn").click()), f.key === "Escape" && (f.preventDefault(), x());
1193
+ });
1194
+ function m() {
1195
+ c(), t._tableHist || (t._tableHist = { undo: [], redo: [] }), t._tableHist.undo.push(t.innerHTML), t._tableHist.undo.length > 50 && t._tableHist.undo.shift(), t._tableHist.redo = [];
1196
+ }
1197
+ function v() {
1198
+ var f = e.wrapper.querySelector('[data-cmd="undo"]'), S = e.wrapper.querySelector('[data-cmd="redo"]'), E = t._tableHist;
1199
+ f && f.toggleAttribute("disabled", !E || !E.undo.length), S && S.toggleAttribute("disabled", !E || !E.redo.length);
1200
+ }
1201
+ o.querySelector(".te-fr-replace-btn").addEventListener("click", function() {
1202
+ if (p.length) {
1203
+ var f = t.querySelector(".te-fr-active");
1204
+ if (f) {
1205
+ m();
1206
+ var S = n.value, E = f.parentNode;
1207
+ E && E.replaceChild(document.createTextNode(S), f), p.splice(s, 1), a.textContent = p.length + " matches", p.length ? (s = Math.min(s, p.length - 1), d(p[s])) : a.textContent = "0 matches", v();
1208
+ }
1209
+ }
1210
+ }), o.querySelector(".te-fr-replace-all").addEventListener("click", function() {
1211
+ var f = r.value.trim(), S = n.value;
1212
+ if (f) {
1213
+ m(), c();
1214
+ for (var E = new RegExp(i(f), "gi"), q = document.createTreeWalker(t, NodeFilter.SHOW_TEXT, null), H = []; q.nextNode(); ) H.push(q.currentNode);
1215
+ var B = 0;
1216
+ H.forEach(function(_) {
1217
+ var w = _.textContent;
1218
+ E.test(w) && (E.lastIndex = 0, _.textContent = w.replace(E, function() {
1219
+ return B++, S;
1220
+ }));
1221
+ }), a.textContent = B + " replaced", p = [], s = -1, v();
1222
+ }
1223
+ }), o.querySelector(".te-fr-close").addEventListener("click", x);
1224
+ var l = e.wrapper.querySelector('[data-cmd="findReplace"]');
1225
+ l && (l.addEventListener("click", function(f) {
1226
+ var S = l.getBoundingClientRect();
1227
+ o.style.left = window.scrollX + S.left + "px", o.style.top = window.scrollY + S.bottom + 4 + "px", o.style.display = o.style.display === "none" ? "block" : "none", o.style.display !== "none" && (r.value = "", n.value = "", a.textContent = "", c(), p = [], s = -1, r.focus());
1228
+ }), document.addEventListener("click", function(f) {
1229
+ o.style.display !== "none" && !o.contains(f.target) && f.target !== l && (o.style.display = "none", c());
1230
+ }));
1231
+ }
1232
+ }, it = {
1233
+ name: "indent",
1234
+ order: 25,
1235
+ toolbarHTML: '<button type="button" class="btn btn-sm btn-light" title="Indent" data-cmd="indent"><i class="ti ti-indent-increase"></i></button><button type="button" class="btn btn-sm btn-light" title="Outdent" data-cmd="outdent"><i class="ti ti-indent-decrease"></i></button>',
1236
+ init(e) {
1237
+ if (!e.features.indent) return;
1238
+ const t = e.wrapper.querySelector('[data-cmd="indent"]');
1239
+ t && t.addEventListener("click", function() {
1240
+ document.execCommand("indent", !1, void 0), e.editor.focus();
1241
+ });
1242
+ const o = e.wrapper.querySelector('[data-cmd="outdent"]');
1243
+ o && o.addEventListener("click", function() {
1244
+ document.execCommand("outdent", !1, void 0), e.editor.focus();
1245
+ });
1246
+ }
1247
+ };
1248
+ var lt = /\bte-list-\S+/g, be = [
1249
+ { val: "decimal", label: "1.", cls: "" },
1250
+ { val: "upper-alpha", label: "A.", cls: "te-list-upper-alpha" },
1251
+ { val: "lower-alpha", label: "a.", cls: "te-list-lower-alpha" },
1252
+ { val: "upper-roman", label: "I.", cls: "te-list-upper-roman" },
1253
+ { val: "lower-roman", label: "i.", cls: "te-list-lower-roman" }
1254
+ ], me = [
1255
+ { val: "disc", label: "•", cls: "" },
1256
+ { val: "circle", label: "○", cls: "te-list-circle" },
1257
+ { val: "square", label: "■", cls: "te-list-square" }
1258
+ ];
1259
+ function re(e, t, o) {
1260
+ e && (e.className = (e.className || "").replace(lt, "").trim(), o && e.classList.add(o), e.style.listStyleType = t || "");
1261
+ }
1262
+ function Z(e) {
1263
+ for (; e && e.nodeType === 1; ) {
1264
+ if (e.tagName === "OL" || e.tagName === "UL") return e;
1265
+ e = e.parentElement;
1266
+ }
1267
+ return null;
1268
+ }
1269
+ function ge(e) {
1270
+ for (var t = '<option value="">—</option>', o = 0; o < e.length; o++)
1271
+ t += '<option value="' + e[o].val + '">' + e[o].label + "</option>";
1272
+ return t;
1273
+ }
1274
+ function ve(e, t, o, r) {
1275
+ var n = t.value;
1276
+ t.value = "";
1277
+ var a = window.getSelection();
1278
+ if (!(!a || !a.anchorNode)) {
1279
+ var i = a.anchorNode;
1280
+ i.nodeType === 3 && (i = i.parentNode);
1281
+ var c = Z(i), d = o === "OL" ? "insertOrderedList" : "insertUnorderedList";
1282
+ if (!n) {
1283
+ c && c.tagName === o && document.execCommand(d, !1, void 0), e.editor.focus();
1284
+ return;
1285
+ }
1286
+ for (var p = null, s = 0; s < r.length; s++)
1287
+ if (r[s].val === n) {
1288
+ p = r[s];
1289
+ break;
1290
+ }
1291
+ if (p) {
1292
+ if (c)
1293
+ if (c.tagName === o)
1294
+ re(c, n, p.cls);
1295
+ else {
1296
+ document.execCommand(d, !1, void 0);
1297
+ var u = a.focusNode;
1298
+ u && u.nodeType === 3 && (u = u.parentNode);
1299
+ var b = Z(u);
1300
+ b && b.tagName === o && re(b, n, p.cls);
1301
+ }
1302
+ else {
1303
+ document.execCommand(d, !1, void 0);
1304
+ var u = a.focusNode;
1305
+ u && u.nodeType === 3 && (u = u.parentNode);
1306
+ var b = Z(u);
1307
+ b && re(b, n, p.cls);
1308
+ }
1309
+ e.editor.focus();
1310
+ }
1311
+ }
1312
+ }
1313
+ const st = {
1314
+ name: "list",
1315
+ order: 25,
1316
+ css: ".te-list-select { width: auto; }.te-editor ol.te-list-upper-alpha { list-style-type: upper-alpha; }.te-editor ol.te-list-lower-alpha { list-style-type: lower-alpha; }.te-editor ol.te-list-upper-roman { list-style-type: upper-roman; }.te-editor ol.te-list-lower-roman { list-style-type: lower-roman; }.te-editor ul.te-list-circle { list-style-type: circle; }.te-editor ul.te-list-square { list-style-type: square; }",
1317
+ toolbarHTML: '<select class="te-list-ol form-select form-select-sm te-list-select" title="Ordered list style">' + ge(be) + '</select><select class="te-list-ul form-select form-select-sm te-list-select" title="Unordered list style">' + ge(me) + "</select>",
1318
+ init(e) {
1319
+ if (e.features.list !== !1) {
1320
+ var t = e.wrapper.querySelector(".te-list-ol"), o = e.wrapper.querySelector(".te-list-ul");
1321
+ t && t.addEventListener("change", function() {
1322
+ ve(e, t, "OL", be);
1323
+ }), o && o.addEventListener("change", function() {
1324
+ ve(e, o, "UL", me);
1325
+ }), e.editor.addEventListener("keydown", function(r) {
1326
+ if (r.key === "Tab") {
1327
+ var n = window.getSelection();
1328
+ if (!n || !n.anchorNode) return;
1329
+ var a = n.anchorNode;
1330
+ a.nodeType === 3 && (a = a.parentNode);
1331
+ var i = Z(a);
1332
+ i && (r.preventDefault(), document.execCommand(r.shiftKey ? "outdent" : "indent", !1, void 0), e.editor.focus());
1333
+ }
1334
+ });
1335
+ }
1336
+ }
1337
+ }, dt = {
1338
+ name: "lineHeight",
1339
+ order: 26,
1340
+ css: ".te-lh-select { width: auto; }",
1341
+ toolbarHTML: '<select class="te-lh form-select form-select-sm te-lh-select" title="Line height"> <option value="" disabled selected>Line Height</option> <option value="1">1</option> <option value="1.15">1.15</option> <option value="1.5">1.5</option> <option value="1.8">1.8</option> <option value="2">2</option> <option value="2.5">2.5</option> <option value="3">3</option></select>',
1342
+ init(e) {
1343
+ if (e.features.lineHeight) {
1344
+ var t = e.wrapper.querySelector(".te-lh");
1345
+ t && t.addEventListener("change", function() {
1346
+ var o = t.value;
1347
+ if (o) {
1348
+ document.execCommand("formatBlock", !1, "p");
1349
+ var r = window.getSelection();
1350
+ if (!(!r || !r.rangeCount)) {
1351
+ var n = r.anchorNode;
1352
+ n && n.nodeType === 3 && (n = n.parentNode);
1353
+ var a = n && n.closest && n.closest("p,h1,h2,h3,h4,h5,h6,div,li,blockquote");
1354
+ a && e.wrapper.contains(a) && (a.style.lineHeight = o), e.editor.focus();
1355
+ }
1356
+ }
1357
+ });
1358
+ }
1359
+ }
1360
+ };
1361
+ var ct = ["8", "9", "10", "11", "12", "13", "14", "16", "18", "20", "22", "24", "26", "28", "36", "48", "72"];
1362
+ const ut = {
1363
+ name: "fontSize",
1364
+ order: 27,
1365
+ css: ".te-fontsize-select { width: auto; }",
1366
+ toolbarHTML: '<span class="te-dropdown-icon te-dropdown-icon-text">Aa</span><select class="te-fontsize form-select form-select-sm te-fontsize-select" title="Font size"> <option value="">Normal</option>' + ct.map(function(e) {
1367
+ return '<option value="' + e + '">' + e + "</option>";
1368
+ }).join("") + "</select>",
1369
+ init(e) {
1370
+ if (e.features.fontSize) {
1371
+ var t = e.wrapper.querySelector(".te-fontsize");
1372
+ t && t.addEventListener("change", function() {
1373
+ var o = t.value;
1374
+ if (o) {
1375
+ var r = ie(window.getSelection().toString() || "text"), n = '<span style="font-size:' + o + 'px">' + r + "</span>";
1376
+ document.execCommand("insertHTML", !1, n), e.editor.focus();
1377
+ }
1378
+ });
1379
+ }
1380
+ }
1381
+ };
1382
+ var pt = [
1383
+ "Arial",
1384
+ "Arial Black",
1385
+ "Comic Sans MS",
1386
+ "Courier New",
1387
+ "Georgia",
1388
+ "Impact",
1389
+ "Lucida Console",
1390
+ "Tahoma",
1391
+ "Times New Roman",
1392
+ "Trebuchet MS",
1393
+ "Verdana"
1394
+ ];
1395
+ const ft = {
1396
+ name: "fontFamily",
1397
+ order: 28,
1398
+ css: ".te-fontfamily-select { width: auto; }",
1399
+ toolbarHTML: '<span class="te-dropdown-icon"><i class="ti ti-typography"></i></span><select class="te-fontfamily form-select form-select-sm te-fontfamily-select" title="Font family"> <option value="">Normal</option>' + pt.map(function(e) {
1400
+ return '<option value="' + e + '">' + e + "</option>";
1401
+ }).join("") + "</select>",
1402
+ init(e) {
1403
+ if (e.features.fontFamily) {
1404
+ var t = e.wrapper.querySelector(".te-fontfamily");
1405
+ t && t.addEventListener("change", function() {
1406
+ var o = t.value;
1407
+ o && (document.execCommand("fontName", !1, o), e.editor.focus());
1408
+ });
1409
+ }
1410
+ }
1411
+ };
1412
+ var bt = "©®™§±•·†‡•¶′″←↑→↓↔↕⇒⇔∞≈≠≤≥√∛∜÷×∑∏∫∂∇∅∈∉∋∧∨∩∪⊂⊃⊆⊇¬∧∨⇒⇔∀∃∄∵∴∷∠∟∡∥∦∼≅≜≛≝≟≠≡≢≤≥≦≧≨≩≪≫≬≭≮≯≰≱≲≳≴≵≶≷≸≹≺≻≼≽≾≿⊀⊁⊂⊃⊄⊅⊆⊇⊈⊉⊊⊋⊌⊍⊎⊏⊐⊑⊒⊓⊔⊕⊖⊗⊘⊙⊚⊛⊜⊝⊞⊟⊠⊡⊢⊣⊤⊥⊦⊧⊨⊩⊪⊫⊬⊭⊮⊯⊰⊱⊲⊳⊴⊵⊶⊷⊸⊹⊺⊻⊼⊽⊾⊿⋀⋁⋂⋃⋄⋅⋆⋇⋈⋉⋊⋋⋌⋍⋎⋏⋐⋑⋒⋓⋔⋕⋖⋗⋘⋙⋚⋛⋜⋝⋞⋟€£¥₩₽₨₪₫₭₮₰₱₲₳₴₵₶₷₸₹₺₻₼₽₾₿".split("");
1413
+ const mt = {
1414
+ name: "specialChars",
1415
+ order: 29,
1416
+ css: ".te-sc-popup { position: absolute; z-index: 3000; display: grid; grid-template-columns: repeat(10, 1fr); gap: 2px; background: #fff; border: 1px solid #dee2e6; border-radius: .5rem; box-shadow: 0 6px 20px rgba(0,0,0,.15); padding: .5rem; max-width: 320px; max-height: 200px; overflow-y: auto;}.te-sc-popup button { background: none; border: none; font-size: 1rem; padding: .25rem; cursor: pointer; border-radius: .25rem; text-align: center;}.te-sc-popup button:hover { background: #f0f0f0; }",
1417
+ toolbarHTML: '<button type="button" class="btn btn-sm btn-light" title="Special characters" data-cmd="specialChars"><i class="ti ti-hash"></i></button>',
1418
+ init(e) {
1419
+ if (e.features.specialChars) {
1420
+ var t = document.createElement("div");
1421
+ t.className = "te-sc-popup", t.style.display = "none", bt.forEach(function(r) {
1422
+ var n = document.createElement("button");
1423
+ n.type = "button", n.textContent = r, n.setAttribute("data-sc", r), t.appendChild(n);
1424
+ }), document.body.appendChild(t);
1425
+ var o = e.wrapper.querySelector('[data-cmd="specialChars"]');
1426
+ o && o.addEventListener("click", function(r) {
1427
+ var n = o.getBoundingClientRect();
1428
+ t.style.left = window.scrollX + n.left + "px", t.style.top = window.scrollY + n.bottom + 4 + "px", t.style.display = t.style.display === "none" ? "grid" : "none";
1429
+ }), t.addEventListener("click", function(r) {
1430
+ var n = r.target && r.target.getAttribute("data-sc");
1431
+ n && (document.execCommand("insertHTML", !1, n), t.style.display = "none", e.editor.focus());
1432
+ }), document.addEventListener("click", function(r) {
1433
+ t.style.display !== "none" && !t.contains(r.target) && r.target !== o && (t.style.display = "none");
1434
+ });
1435
+ }
1436
+ }
1437
+ }, gt = {
1438
+ name: "colors",
1439
+ order: 30,
1440
+ css: '.te-color-btn { position: relative; padding: .15rem .35rem !important; min-width: 28px; text-align: center;}.te-color-preview { display: block; font-size: 1rem; line-height: 1;}.te-color-preview::after { content: ""; display: block; height: 3px; border-radius: 1px; margin-top: 2px;}.te-fore-btn .te-color-preview::after { background: currentColor;}.te-back-btn .te-color-preview::after { background: var(--te-back-color, #ffff00);}.te-color-input { position: absolute; top: 0; left: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; border: none; padding: 0;}',
1441
+ toolbarHTML: '<button type="button" class="btn btn-sm btn-light te-color-btn te-fore-btn" title="Text color"><span class="te-color-preview" style="color:#000000">A</span><input type="color" class="te-color-input te-fore-color" value="#000000"></button><button type="button" class="btn btn-sm btn-light te-color-btn te-back-btn" title="Background color"><span class="te-color-preview" style="--te-back-color:#ffff00;color:#000">A</span><input type="color" class="te-color-input te-back-color" value="#ffff00"></button>',
1442
+ init(e) {
1443
+ if (e.features.colors) {
1444
+ var t = e.wrapper.querySelector(".te-fore-color"), o = e.wrapper.querySelector(".te-fore-btn");
1445
+ o && t && t.addEventListener("change", function() {
1446
+ var a = o.querySelector(".te-color-preview");
1447
+ a.style.color = t.value, document.execCommand("foreColor", !1, t.value), e.editor.focus();
1448
+ });
1449
+ var r = e.wrapper.querySelector(".te-back-color"), n = e.wrapper.querySelector(".te-back-btn");
1450
+ n && r && r.addEventListener("change", function() {
1451
+ var a = n.querySelector(".te-color-preview");
1452
+ a.style.setProperty("--te-back-color", r.value);
1453
+ try {
1454
+ document.execCommand("hiliteColor", !1, r.value);
1455
+ } catch {
1456
+ document.execCommand("backColor", !1, r.value);
1457
+ }
1458
+ e.editor.focus();
1459
+ });
1460
+ }
1461
+ }
1462
+ }, vt = {
1463
+ name: "tableBg",
1464
+ order: 56,
1465
+ init(e) {
1466
+ }
1467
+ };
1468
+ var oe = {
1469
+ alignLeft: { exec: "justifyLeft", match: "left" },
1470
+ alignCenter: { exec: "justifyCenter", match: "center" },
1471
+ alignRight: { exec: "justifyRight", match: "right" },
1472
+ alignJustify: { exec: "justifyFull", match: "justify" }
1473
+ };
1474
+ function he(e) {
1475
+ if ((!e || e.nodeType === 3) && (e = e ? e.parentNode : null), !e) return "";
1476
+ var t = e.closest ? e.closest("p,h1,h2,h3,h4,h5,h6,li,div,blockquote") : null;
1477
+ if (!t) return "";
1478
+ try {
1479
+ var o = window.getComputedStyle(t), r = o.textAlign.toLowerCase();
1480
+ return r === "start" ? "left" : r;
1481
+ } catch {
1482
+ return "";
1483
+ }
1484
+ }
1485
+ const ht = {
1486
+ name: "align",
1487
+ order: 40,
1488
+ css: "",
1489
+ toolbarHTML: '<button type="button" class="btn btn-sm btn-light te-align-btn" title="Align left" data-cmd="alignLeft"><i class="ti ti-align-left"></i></button><button type="button" class="btn btn-sm btn-light te-align-btn" title="Align center" data-cmd="alignCenter"><i class="ti ti-align-center"></i></button><button type="button" class="btn btn-sm btn-light te-align-btn" title="Align right" data-cmd="alignRight"><i class="ti ti-align-right"></i></button><button type="button" class="btn btn-sm btn-light te-align-btn" title="Justify" data-cmd="alignJustify"><i class="ti ti-align-justified"></i></button>',
1490
+ init(e) {
1491
+ if (!e.features.align) return;
1492
+ var t = Object.keys(oe);
1493
+ t.forEach(function(r) {
1494
+ var n = e.wrapper.querySelector('[data-cmd="' + r + '"]');
1495
+ if (n) {
1496
+ var a = oe[r];
1497
+ n.addEventListener("click", function() {
1498
+ var i = he(window.getSelection().anchorNode);
1499
+ i === a.match ? document.execCommand("justifyLeft", !1, void 0) : document.execCommand(a.exec, !1, void 0), e.editor.focus(), o();
1500
+ });
1501
+ }
1502
+ });
1503
+ function o() {
1504
+ var r = window.getSelection().anchorNode;
1505
+ if (!(!r || !e.wrapper.contains(r))) {
1506
+ var n = he(r);
1507
+ t.forEach(function(a) {
1508
+ var i = e.wrapper.querySelector('[data-cmd="' + a + '"]');
1509
+ i && i.classList.toggle("active", n === oe[a].match);
1510
+ });
1511
+ }
1512
+ }
1513
+ document.addEventListener("selectionchange", function() {
1514
+ (document.activeElement === e.editor || e.editor.contains(document.activeElement)) && o();
1515
+ });
1516
+ }
1517
+ };
1518
+ var ye = [
1519
+ { re: /^#{6}\s$/, cmd: "formatBlock", val: "h6" },
1520
+ { re: /^#{5}\s$/, cmd: "formatBlock", val: "h5" },
1521
+ { re: /^#{4}\s$/, cmd: "formatBlock", val: "h4" },
1522
+ { re: /^#{3}\s$/, cmd: "formatBlock", val: "h3" },
1523
+ { re: /^#{2}\s$/, cmd: "formatBlock", val: "h2" },
1524
+ { re: /^#{1}\s$/, cmd: "formatBlock", val: "h1" },
1525
+ { re: /^>\s$/, cmd: "formatBlock", val: "blockquote" },
1526
+ { re: /^[-*]\s$/, cmd: "insertUnorderedList", val: null },
1527
+ { re: /^1[.)]\s$/, cmd: "insertOrderedList", val: null }
1528
+ ];
1529
+ const yt = {
1530
+ name: "markdown",
1531
+ order: 5,
1532
+ init(e) {
1533
+ e.features.markdown && e.editor.addEventListener("keydown", function(t) {
1534
+ if (!(t.key !== " " && t.key !== "Enter")) {
1535
+ var o = window.getSelection();
1536
+ if (!(!o || o.rangeCount === 0 || !o.isCollapsed)) {
1537
+ var r = o.anchorNode;
1538
+ if (!(!r || r.nodeType !== 3)) {
1539
+ for (var n = r.textContent || "", a = 0; a < ye.length; a++) {
1540
+ var i = ye[a];
1541
+ if (i.re.test(n)) {
1542
+ if (t.preventDefault(), t.key === "Enter") {
1543
+ r.textContent = n.slice(0, -1), setTimeout(function() {
1544
+ document.execCommand(i.cmd, !1, i.val || void 0);
1545
+ }, 0);
1546
+ return;
1547
+ }
1548
+ r.textContent = "", document.execCommand(i.cmd, !1, i.val || void 0), e.editor.focus();
1549
+ return;
1550
+ }
1551
+ }
1552
+ if (t.key === "Enter" && n.trim() === "") {
1553
+ var c = r.parentNode;
1554
+ c && (c.tagName === "BLOCKQUOTE" || c.tagName === "PRE") && (t.preventDefault(), document.execCommand("formatBlock", !1, "p"));
1555
+ }
1556
+ }
1557
+ }
1558
+ }
1559
+ });
1560
+ }
1561
+ }, wt = {
1562
+ name: "link",
1563
+ order: 50,
1564
+ toolbarHTML: '<button type="button" class="btn btn-sm btn-light" title="Link" data-cmd="createLink"><i class="ti ti-link"></i></button>',
1565
+ css: ".te-link-tools { position: fixed; display: none; z-index: 3000; background: #fff; border: 1px solid #dee2e6; border-radius: .375rem; box-shadow: 0 6px 20px rgba(0,0,0,.15); padding: .25rem .35rem; gap: .2rem; align-items: center; white-space: nowrap;}.te-link-tools .btn { padding: .2rem .45rem !important; font-size: .75rem !important; line-height: 1 !important;}.te-link-tools .btn i,.te-link-tools .btn svg { width: 12px !important; height: 12px !important; pointer-events: none;}.te-link-tools .te-divider-v { display: inline-block; width: 1px; height: 14px; background: #dee2e6; margin: 0 .15rem; vertical-align: middle;}.te-link-edit-popup { position: fixed; display: none; z-index: 3001; background: #fff; border: 1px solid #dee2e6; border-radius: .375rem; box-shadow: 0 6px 20px rgba(0,0,0,.15); padding: .35rem; gap: .25rem; align-items: center; white-space: nowrap;}.te-link-edit-popup input { width: 220px; padding: .2rem .4rem; font-size: .8rem; border: 1px solid #dee2e6; border-radius: .25rem; outline: none;}.te-link-edit-popup input:focus { border-color: #86b7fe; box-shadow: 0 0 0 2px rgba(13,110,253,.15);}.te-link-edit-popup .btn { padding: .2rem .5rem !important; font-size: .75rem !important; line-height: 1 !important;}",
1566
+ modalHTML: '<div class="te-link-modal te-modal" aria-hidden="true"> <div class="te-modal-backdrop" data-te-close></div> <div class="te-modal-dialog"> <div class="te-modal-header"> <h5 class="te-modal-title m-0">Insert Link</h5> <button type="button" class="btn-close" data-te-close aria-label="Close"></button> </div> <form class="te-link-form"> <div class="te-modal-body"> <div class="mb-3"> <label class="form-label">URL</label> <input type="url" class="te-link-url form-control" placeholder="https://example.com" required> </div> <div class="mb-3"> <label class="form-label">Text (optional)</label> <input type="text" class="te-link-text form-control" placeholder="Link text"> </div> <div class="mb-3"> <label class="form-label">Rel (optional)</label> <input type="text" class="te-link-rel form-control" placeholder="noopener noreferrer, nofollow, ugc, sponsored"> </div> <div class="form-check"> <input class="te-link-blank form-check-input" type="checkbox" checked> <label class="form-check-label">Open in new tab</label> </div> </div> <div class="te-modal-footer"> <button type="button" class="btn btn-outline-secondary" data-te-close>Cancel</button> <button type="submit" class="btn btn-primary">Insert</button> </div> </form> </div></div>',
1567
+ init(e) {
1568
+ if (!e.features.link) return;
1569
+ var t = null, o = document.createElement("div");
1570
+ o.className = "te-link-tools", o.innerHTML = '<button type="button" class="btn btn-sm btn-light" data-te-link="edit" title="Edit link"><i class="ti ti-edit"></i> Edit</button><button type="button" class="btn btn-sm btn-light" data-te-link="remove" title="Remove link"><i class="ti ti-link-off"></i> Remove</button>', document.body.appendChild(o);
1571
+ var r = document.createElement("div");
1572
+ r.className = "te-link-edit-popup", r.innerHTML = '<input type="url" class="te-link-edit-url" placeholder="https://example.com" /><button type="button" class="btn btn-sm btn-primary" data-te-link-edit="apply">Apply</button><button type="button" class="btn btn-sm btn-light" data-te-link-edit="cancel">Cancel</button>', document.body.appendChild(r);
1573
+ function n(l) {
1574
+ var f = l.getBoundingClientRect(), S = e.editor.getBoundingClientRect();
1575
+ o.style.display = "flex", o.style.visibility = "hidden";
1576
+ var E = o.offsetWidth, q = o.offsetHeight, H = f.left + f.width / 2 - E / 2;
1577
+ H < S.left && (H = S.left), H + E > S.right && (H = S.right - E), o.style.left = H + "px";
1578
+ var B = window.innerHeight - f.bottom, _ = B >= q + 6 ? f.bottom + 6 : f.top - q - 6;
1579
+ _ < S.top && (_ = f.bottom + 6), o.style.top = _ + "px", o.style.visibility = "";
1580
+ }
1581
+ function a() {
1582
+ o.style.display = "none", t = null;
1583
+ }
1584
+ var i = 0;
1585
+ function c(l) {
1586
+ Date.now() - i < 200 || (r.style.display = "none");
1587
+ }
1588
+ function d(l) {
1589
+ i = Date.now();
1590
+ var f = l.getBoundingClientRect(), S = e.editor.getBoundingClientRect();
1591
+ r.style.display = "flex", r.style.visibility = "hidden";
1592
+ var E = r.offsetWidth || 350, q = r.offsetHeight || 32, H = f.left + f.width / 2 - E / 2;
1593
+ H < S.left && (H = S.left), H + E > S.right && (H = S.right - E), r.style.left = H + "px";
1594
+ var B = window.innerHeight - f.bottom;
1595
+ r.style.top = (B >= q + 6 ? f.bottom + 6 : f.top - q - 6) + "px", r.style.visibility = "", r.querySelector(".te-link-edit-url").value = l.getAttribute("href") || "", setTimeout(function() {
1596
+ r.querySelector(".te-link-edit-url").focus();
1597
+ }, 0);
1598
+ }
1599
+ function p() {
1600
+ e.saveSel();
1601
+ var l = e.wrapper.querySelector(".te-link-modal");
1602
+ l && l.classList.add("is-open");
1603
+ }
1604
+ function s() {
1605
+ var l = e.wrapper.querySelector(".te-link-modal");
1606
+ l && l.classList.remove("is-open");
1607
+ }
1608
+ function u(l) {
1609
+ var f = e.wrapper.querySelector(".te-link-url"), S = e.wrapper.querySelector(".te-link-text"), E = e.wrapper.querySelector(".te-link-rel"), q = e.wrapper.querySelector(".te-link-blank"), H = e.wrapper.querySelector('.te-link-form button[type="submit"]');
1610
+ f && (f.value = l.getAttribute("href") || ""), S && (S.value = l.textContent || ""), E && (E.value = l.getAttribute("rel") || ""), q && (q.checked = l.getAttribute("target") === "_blank"), H && (H.textContent = "Update");
1611
+ }
1612
+ function b() {
1613
+ var l = window.getSelection();
1614
+ return l && l.toString().trim() || "";
1615
+ }
1616
+ var k = e.wrapper.querySelector('[data-cmd="createLink"]');
1617
+ k && k.addEventListener("click", function() {
1618
+ t = null, a(), c();
1619
+ var l = e.wrapper.querySelector(".te-link-url"), f = e.wrapper.querySelector(".te-link-text"), S = e.wrapper.querySelector(".te-link-rel"), E = e.wrapper.querySelector(".te-link-blank"), q = e.wrapper.querySelector('.te-link-form button[type="submit"]');
1620
+ l && (l.value = ""), f && (f.value = b() || ""), S && (S.value = ""), E && (E.checked = !0), q && (q.textContent = "Insert"), p();
1621
+ }), e.editor.addEventListener("click", function(l) {
1622
+ var f = l.target.closest && l.target.closest("a");
1623
+ !f || !e.editor.contains(f) || e.wrapper.contains(f) && ((l.ctrlKey || l.metaKey) && l.preventDefault(), l.stopPropagation(), c(), t = f, u(f), n(f));
1624
+ }), o.addEventListener("mousedown", function(l) {
1625
+ l.preventDefault(), l.stopPropagation();
1626
+ var f = l.target.closest && l.target.closest("[data-te-link]");
1627
+ if (f) {
1628
+ var S = f.getAttribute("data-te-link"), E = t;
1629
+ if (S === "edit")
1630
+ E && e.editor.contains(E) && (t = E, d(E), setTimeout(function() {
1631
+ o.style.display = "none";
1632
+ }, 0));
1633
+ else if (S === "remove" && (a(), E && e.editor.contains(E))) {
1634
+ for (var q = E.parentNode; E.firstChild; )
1635
+ q.insertBefore(E.firstChild, E);
1636
+ q.removeChild(E), e.editor.focus();
1637
+ }
1638
+ }
1639
+ });
1640
+ function T(l) {
1641
+ !t || !e.editor.contains(t) || (!/^https?:\/\//i.test(l) && !/^mailto:/i.test(l) && !/^tel:/i.test(l) && (l = "https://" + l), t.setAttribute("href", l), c(), t = null, e.editor.focus());
1642
+ }
1643
+ r.addEventListener("click", function(l) {
1644
+ l.stopPropagation();
1645
+ }), r.addEventListener("mousedown", function(l) {
1646
+ l.preventDefault(), l.stopPropagation();
1647
+ var f = l.target.closest && l.target.closest("[data-te-link-edit]");
1648
+ if (f) {
1649
+ var S = f.getAttribute("data-te-link-edit");
1650
+ if (S === "cancel") {
1651
+ c(), t = null, e.editor.focus();
1652
+ return;
1653
+ }
1654
+ if (S === "apply") {
1655
+ var E = r.querySelector(".te-link-edit-url").value.trim();
1656
+ if (!E) return;
1657
+ T(E);
1658
+ }
1659
+ }
1660
+ }), r.addEventListener("keydown", function(l) {
1661
+ if (l.key === "Enter") {
1662
+ l.preventDefault();
1663
+ var f = r.querySelector(".te-link-edit-url").value.trim();
1664
+ if (!f) return;
1665
+ T(f);
1666
+ }
1667
+ l.key === "Escape" && (c(), t = null, e.editor.focus());
1668
+ }), o.addEventListener("click", function(l) {
1669
+ l.stopPropagation();
1670
+ }), document.addEventListener("click", function(l) {
1671
+ if (o.style.display !== "none" && !o.contains(l.target) && a(), r.style.display !== "none" && !r.contains(l.target)) {
1672
+ var f = l.target.closest && l.target.closest(".te-link-tools");
1673
+ f || Date.now() - i < 200 || (c(), t = null);
1674
+ }
1675
+ });
1676
+ var x = e.wrapper.querySelector(".te-link-form");
1677
+ x && x.addEventListener("submit", function(l) {
1678
+ l.preventDefault();
1679
+ var f = (e.wrapper.querySelector(".te-link-url").value || "").trim(), S = (e.wrapper.querySelector(".te-link-text").value || "").trim(), E = e.wrapper.querySelector(".te-link-blank").checked, q = (e.wrapper.querySelector(".te-link-rel").value || "").trim();
1680
+ if (f) {
1681
+ var H = e.utils.isSafeUrl ? e.utils.isSafeUrl(f, e.options.urlSchemes || ["http", "https"]) : !0;
1682
+ if (H) {
1683
+ if (t && e.editor.contains(t)) {
1684
+ t.setAttribute("href", f), E ? t.setAttribute("target", "_blank") : t.removeAttribute("target"), q ? t.setAttribute("rel", q) : t.removeAttribute("rel"), S && (t.textContent = S), s(), e.editor.focus();
1685
+ return;
1686
+ }
1687
+ e.restoreSel();
1688
+ var B = q || (E ? "noopener noreferrer" : ""), _ = (S || f).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;"), w = '<a href="' + f.replace(/"/g, "&quot;") + '"' + (E ? ' target="_blank"' : "") + (B ? ' rel="' + B.replace(/"/g, "&quot;") + '"' : "") + ">" + _ + "</a>";
1689
+ document.execCommand("insertHTML", !1, w), s(), e.editor.focus();
1690
+ }
1691
+ }
1692
+ });
1693
+ for (var m = e.wrapper.querySelectorAll("[data-te-close]"), v = 0; v < m.length; v++)
1694
+ m[v].addEventListener("click", function() {
1695
+ t = null;
1696
+ });
1697
+ }
1698
+ }, kt = {
1699
+ name: "image",
1700
+ order: 51,
1701
+ toolbarHTML: '<button type="button" class="btn btn-sm btn-light" title="Image" data-cmd="insertImage"><i class="ti ti-photo"></i></button>',
1702
+ modalHTML: '<div class="te-image-modal te-modal" aria-hidden="true"> <div class="te-modal-backdrop" data-te-close></div> <div class="te-modal-dialog"> <div class="te-modal-header"> <h5 class="te-modal-title m-0">Insert Image</h5> <button type="button" class="btn-close" data-te-close aria-label="Close"></button> </div> <form class="te-image-form"> <div class="te-modal-body"> <div class="mb-3"> <label class="form-label">Image URL</label> <input type="text" class="te-image-url form-control" placeholder="/path/to/image.jpg or https://..." required> <div class="mt-2"><button type="button" class="te-image-browse btn btn-sm btn-outline-secondary"><i class="ti ti-folder"></i> Browse...</button></div> </div> <div class="mb-3"> <label class="form-label">Alt text (optional)</label> <input type="text" class="te-image-alt form-control" placeholder="Description"> </div> </div> <div class="te-modal-footer"> <button type="button" class="btn btn-outline-secondary" data-te-close>Cancel</button> <button type="submit" class="btn btn-primary">Insert</button> </div> </form> </div></div>',
1703
+ init(e) {
1704
+ if (e.features.image) {
1705
+ var t = e.wrapper.querySelector('[data-cmd="insertImage"]');
1706
+ t && t.addEventListener("click", function() {
1707
+ e.saveSel();
1708
+ var a = e.wrapper.querySelector(".te-image-modal");
1709
+ a && a.classList.add("is-open");
1710
+ });
1711
+ var o = e.wrapper.querySelector(".te-image-url"), r = e.wrapper.querySelector(".te-image-browse");
1712
+ r && r.addEventListener("click", function(a) {
1713
+ if (a.preventDefault(), e.TulihEditor && typeof e.TulihEditor.onBrowseImage == "function") {
1714
+ e.TulihEditor.onBrowseImage({ container: e.wrapper, editor: e.editor }, function(c) {
1715
+ c && o && (o.value = c, o.focus());
1716
+ });
1717
+ return;
1718
+ }
1719
+ var i = document.createElement("input");
1720
+ i.type = "file", i.accept = "image/*", i.style.display = "none", document.body.appendChild(i), i.addEventListener("change", function() {
1721
+ var c = i.files && i.files[0];
1722
+ if (!c) {
1723
+ document.body.removeChild(i);
1724
+ return;
1725
+ }
1726
+ var d = new FileReader();
1727
+ d.onload = function() {
1728
+ o && (o.value = d.result, o.focus()), document.body.removeChild(i);
1729
+ }, d.readAsDataURL(c);
1730
+ }), i.click();
1731
+ });
1732
+ var n = e.wrapper.querySelector(".te-image-form");
1733
+ n && n.addEventListener("submit", function(a) {
1734
+ a.preventDefault();
1735
+ var i = (e.wrapper.querySelector(".te-image-url").value || "").trim(), c = (e.wrapper.querySelector(".te-image-alt").value || "").trim();
1736
+ if (i) {
1737
+ var d = e.utils.isSafeUrl ? e.utils.isSafeUrl(i, e.options.imageSchemes || ["http", "https", "data"]) : !0;
1738
+ if (d) {
1739
+ e.restoreSel(), e.editor.focus();
1740
+ var p = document.createElement("img");
1741
+ p.src = i, c && (p.alt = c);
1742
+ var s = window.getSelection();
1743
+ if (s && s.rangeCount > 0) {
1744
+ var u = s.getRangeAt(0);
1745
+ u.deleteContents(), u.insertNode(p), u.setStartAfter(p), u.collapse(!0), s.removeAllRanges(), s.addRange(u);
1746
+ }
1747
+ n.closest(".te-modal").classList.remove("is-open");
1748
+ }
1749
+ }
1750
+ });
1751
+ }
1752
+ }
1753
+ }, St = {
1754
+ name: "imageProps",
1755
+ order: 52,
1756
+ deps: ["image"],
1757
+ modalHTML: '<div class="te-image-props-modal te-modal" aria-hidden="true"> <div class="te-modal-backdrop" data-te-close></div> <div class="te-modal-dialog"> <div class="te-modal-header"> <h5 class="te-modal-title m-0">Image Properties</h5> <button type="button" class="btn-close" data-te-close aria-label="Close"></button> </div> <form class="te-image-props-form"> <div class="te-modal-body"> <div class="row g-2 mb-3"> <div class="col"> <label class="form-label">Width</label> <input type="number" min="0" class="te-image-props-width form-control" placeholder="e.g. 800"> </div> <div class="col"> <label class="form-label">Height</label> <input type="number" min="0" class="te-image-props-height form-control" placeholder="e.g. 600"> </div> </div> <div class="mb-3"> <label class="form-label">Alt</label> <input type="text" class="te-image-props-alt form-control" placeholder="Alternative text"> </div> <div class="row g-2"> <div class="col"> <label class="form-label">Class</label> <input type="text" class="te-image-props-class form-control" placeholder="class-1 class-2"> </div> <div class="col"> <label class="form-label">ID</label> <input type="text" class="te-image-props-id form-control" placeholder="optional-id"> </div> </div> <div class="mb-3 mt-3"> <label class="form-label">Style (inline CSS)</label> <input type="text" class="te-image-props-style form-control" placeholder="max-width:100%; height:auto;"> </div> </div> <div class="te-modal-footer"> <button type="button" class="btn btn-outline-secondary" data-te-close>Cancel</button> <button type="submit" class="btn btn-primary">Apply</button> </div> </form> </div></div>',
1758
+ init(e) {
1759
+ if (!(!e.features.image || !e.features.imageProps)) {
1760
+ var t = e.wrapper.querySelector(".te-image-props-modal"), o = e.wrapper.querySelector(".te-image-props-form"), r = e.wrapper.querySelector(".te-image-props-alt"), n = e.wrapper.querySelector(".te-image-props-width"), a = e.wrapper.querySelector(".te-image-props-height"), i = e.wrapper.querySelector(".te-image-props-class"), c = e.wrapper.querySelector(".te-image-props-id"), d = e.wrapper.querySelector(".te-image-props-style"), p = null;
1761
+ e.editor.addEventListener("dblclick", function(s) {
1762
+ var u = s.target && s.target.closest && s.target.closest("img");
1763
+ u && e.wrapper.contains(u) && t && (p = u, r && (r.value = u.getAttribute("alt") || ""), n && (n.value = u.getAttribute("width") || ""), a && (a.value = u.getAttribute("height") || ""), i && (i.value = u.getAttribute("class") || ""), c && (c.value = u.getAttribute("id") || ""), d && (d.value = u.getAttribute("style") || ""), t.classList.add("is-open"));
1764
+ }), o && o.addEventListener("submit", function(s) {
1765
+ if (s.preventDefault(), !p) {
1766
+ t && t.classList.remove("is-open");
1767
+ return;
1768
+ }
1769
+ var u = r && r.value || "", b = n && n.value || "", k = a && a.value || "", T = i && i.value || "", x = c && c.value || "", m = d && d.value || "";
1770
+ if (m) {
1771
+ var v = [];
1772
+ m.split(";").forEach(function(l) {
1773
+ var f = l.indexOf(":");
1774
+ if (f !== -1) {
1775
+ var S = l.slice(0, f).trim().toLowerCase(), E = l.slice(f + 1).trim(), q = ["color", "background-color", "font-family", "font-size", "font-style", "font-weight", "text-align", "text-decoration", "line-height", "letter-spacing", "word-spacing", "margin", "margin-top", "margin-right", "margin-bottom", "margin-left", "padding", "padding-top", "padding-right", "padding-bottom", "padding-left", "border", "border-collapse", "border-color", "border-style", "border-width", "border-radius", "width", "height", "max-width", "max-height", "min-width", "min-height", "float", "clear", "vertical-align", "direction", "white-space"];
1776
+ q.indexOf(S) !== -1 && v.push(S + ":" + E);
1777
+ }
1778
+ }), m = v.join(";");
1779
+ }
1780
+ u ? p.setAttribute("alt", u) : p.removeAttribute("alt"), b ? p.setAttribute("width", b) : p.removeAttribute("width"), k ? p.setAttribute("height", k) : p.removeAttribute("height"), T ? p.setAttribute("class", T) : p.removeAttribute("class"), x ? p.setAttribute("id", x) : p.removeAttribute("id"), m ? p.setAttribute("style", m) : p.removeAttribute("style"), t && t.classList.remove("is-open"), p = null;
1781
+ });
1782
+ }
1783
+ }
1784
+ }, Lt = {
1785
+ name: "imageTools",
1786
+ order: 56,
1787
+ deps: ["image", "imageProps"],
1788
+ css: ".te-image-tools { position: absolute; display: none; z-index: 2000; background: #fff; border: 1px solid #dee2e6; border-radius: .375rem; box-shadow: 0 6px 20px rgba(0,0,0,.15); padding: .375rem; gap: .25rem; align-items: center;}.te-image-tools .btn { padding: .2rem .4rem; font-size: .8rem; }.te-image-tools svg, .te-image-tools i { pointer-events: none; }.te-image-tools .te-image-tools-alt { width: 130px; height: 26px; font-size: .8rem; padding: 0 .35rem; border: 1px solid #dee2e6; border-radius: .25rem;}.te-image-tools .te-image-tools-alt:focus { outline: none; border-color: #86b7fe; box-shadow: 0 0 0 2px rgba(13,110,253,.25); }.te-image-tools .te-divider-v { width: 1px; height: 20px; background: #dee2e6;}.te-image-tools .active { background: #e7f1ff; border-color: #b6d4fe; }.te-editor img.te-focused { outline: 3px solid rgba(13,110,253,.4); outline-offset: 1px;}.te-image-resize { position: absolute; display: none; z-index: 2001; width: 10px; height: 10px; background: #0d6efd; border: 2px solid #fff; border-radius: 50%; cursor: nwse-resize; box-shadow: 0 1px 4px rgba(0,0,0,.3);}.te-image-resize:hover { transform: scale(1.2); }.te-figure { display: inline-block; margin: .5rem 0; text-align: center; max-width: 100%;}.te-figure figcaption { font-size: .85rem; color: #6c757d; padding: .25rem .5rem; font-style: italic;}",
1789
+ init(e) {
1790
+ if (!e.features.image || !e.features.imageTools) return;
1791
+ var t = e.wrapper, o = e.editor, r = null, n = document.createElement("div");
1792
+ n.className = "te-image-tools", n.innerHTML = '<input type="text" class="te-image-tools-alt" placeholder="Alt text" title="Alt text (Enter to apply)" /><div class="te-divider-v"></div><button type="button" class="btn btn-sm btn-light" data-te-image="align-default" title="Inline"><i class="ti ti-align-left"></i></button><button type="button" class="btn btn-sm btn-light" data-te-image="align-left" title="Float left"><i class="ti ti-align-left"></i></button><button type="button" class="btn btn-sm btn-light" data-te-image="align-center" title="Center"><i class="ti ti-align-center"></i></button><button type="button" class="btn btn-sm btn-light" data-te-image="align-right" title="Float right"><i class="ti ti-align-right"></i></button><button type="button" class="btn btn-sm btn-light" data-te-image="caption" title="Caption (toggle)"><i class="ti ti-typography"></i></button><div class="te-divider-v"></div><button type="button" class="btn btn-sm btn-light" data-te-image="width-100" title="Width 100%">100%</button><button type="button" class="btn btn-sm btn-light" data-te-image="width-75" title="Width 75%">75%</button><button type="button" class="btn btn-sm btn-light" data-te-image="width-50" title="Width 50%">50%</button><button type="button" class="btn btn-sm btn-light" data-te-image="width-orig" title="Original size">Orig</button><div class="te-divider-v"></div><button type="button" class="btn btn-sm btn-light" data-te-image="border" title="Toggle border">Brdr</button><button type="button" class="btn btn-sm btn-light" data-te-image="rounded" title="Toggle rounded corners">Rnd</button><div class="te-divider-v"></div><button type="button" class="btn btn-sm btn-outline-secondary" data-te-image="props" title="Image Properties"><i class="ti ti-settings"></i></button><button type="button" class="btn btn-sm btn-outline-danger" data-te-image="delete" title="Delete image"><i class="ti ti-x"></i></button>', document.body.appendChild(n);
1793
+ var a = document.createElement("div");
1794
+ a.className = "te-image-resize", document.body.appendChild(a);
1795
+ function i(m) {
1796
+ var v = m.style;
1797
+ return v.float === "left" ? "left" : v.float === "right" ? "right" : v.display === "block" && v.marginLeft === "auto" && v.marginRight === "auto" ? "center" : "default";
1798
+ }
1799
+ function c(m, v) {
1800
+ v === "default" ? (m.style.float = "", m.style.display = "", m.style.marginLeft = "", m.style.marginRight = "") : v === "left" ? (m.style.float = "left", m.style.display = "", m.style.marginLeft = "0", m.style.marginRight = "1em") : v === "right" ? (m.style.float = "right", m.style.display = "", m.style.marginLeft = "1em", m.style.marginRight = "0") : v === "center" && (m.style.float = "", m.style.display = "block", m.style.marginLeft = "auto", m.style.marginRight = "auto");
1801
+ }
1802
+ function d() {
1803
+ if (o) {
1804
+ var m = o.querySelector(".te-focused");
1805
+ m && m.classList.remove("te-focused");
1806
+ }
1807
+ }
1808
+ function p(m) {
1809
+ var v = m.getBoundingClientRect();
1810
+ a.style.left = window.scrollX + v.right - 5 + "px", a.style.top = window.scrollY + v.bottom - 5 + "px", a.style.display = "block";
1811
+ }
1812
+ function s(m) {
1813
+ var v = i(m);
1814
+ n.querySelectorAll('[data-te-image^="align-"]').forEach(function(l) {
1815
+ l.classList.toggle("active", l.getAttribute("data-te-image") === "align-" + v);
1816
+ });
1817
+ }
1818
+ function u(m) {
1819
+ var v = m.getBoundingClientRect(), l = n.querySelector(".te-image-tools-alt");
1820
+ l && (l.value = m.getAttribute("alt") || ""), n.style.display = "flex", n.style.left = window.scrollX + v.left + "px", n.style.visibility = "hidden";
1821
+ var f = n.offsetHeight, S = t.getBoundingClientRect(), E = v.bottom + 6 + f, q = v.top - 6 - f;
1822
+ E > S.bottom && q > S.top ? n.style.top = window.scrollY + v.top - 6 - f + "px" : n.style.top = window.scrollY + v.bottom + 6 + "px", n.style.visibility = "", p(m), s(m);
1823
+ var H = n.querySelector('[data-te-image="caption"]');
1824
+ H && H.classList.toggle("active", !!(m.parentNode && m.parentNode.tagName === "FIGURE"));
1825
+ var B = n.querySelector('[data-te-image="border"]');
1826
+ if (B) {
1827
+ var _ = m.style.border || "";
1828
+ B.classList.toggle("active", !!(_ && _ !== "none"));
1829
+ }
1830
+ var w = n.querySelector('[data-te-image="rounded"]');
1831
+ if (w) {
1832
+ var g = m.style.borderRadius || "";
1833
+ w.classList.toggle("active", !!(g && g !== "0px" && g !== ""));
1834
+ }
1835
+ }
1836
+ function b() {
1837
+ n.style.display = "none", a.style.display = "none", d(), r = null;
1838
+ }
1839
+ o.addEventListener("click", function(m) {
1840
+ var v = m.target && (m.target.closest ? m.target.closest("img") : null);
1841
+ if (v && t.contains(v)) {
1842
+ m.stopPropagation(), r = v, d(), v.classList.add("te-focused"), v.setAttribute("tabindex", "-1");
1843
+ try {
1844
+ v.focus({ preventScroll: !0 });
1845
+ } catch {
1846
+ }
1847
+ u(v);
1848
+ } else
1849
+ !n.contains(m.target) && m.target !== a && b();
1850
+ }), o.addEventListener("dblclick", function() {
1851
+ b();
1852
+ }), document.addEventListener("selectionchange", function() {
1853
+ if (r && document.activeElement !== r && !n.contains(document.activeElement)) {
1854
+ var m = window.getSelection();
1855
+ (!m || m.isCollapsed) && b();
1856
+ }
1857
+ }), n.addEventListener("click", function(m) {
1858
+ var v = m.target && m.target.closest("[data-te-image]"), l = v && v.getAttribute("data-te-image");
1859
+ if (!(!l || !r)) {
1860
+ if (m.preventDefault(), m.stopPropagation(), l === "width-100")
1861
+ r.setAttribute("width", "100%"), r.style && (r.style.maxWidth = "100%"), u(r);
1862
+ else if (l === "width-75")
1863
+ r.setAttribute("width", "75%"), u(r);
1864
+ else if (l === "width-50")
1865
+ r.setAttribute("width", "50%"), u(r);
1866
+ else if (l === "width-orig")
1867
+ r.removeAttribute("width"), r.removeAttribute("height"), r.style && (r.style.maxWidth = ""), u(r);
1868
+ else if (l === "delete") {
1869
+ var f = r.parentNode;
1870
+ f && f.removeChild(r), b();
1871
+ } else if (l === "props") {
1872
+ var S = new MouseEvent("dblclick", { bubbles: !0 });
1873
+ r.dispatchEvent(S), b();
1874
+ } else if (l.indexOf("align-") === 0) {
1875
+ var E = l.replace("align-", "");
1876
+ c(r, E), s(r), u(r);
1877
+ } else if (l === "border") {
1878
+ var q = r.style.border || "";
1879
+ q && q !== "none" ? (r.style.border = "", r.removeAttribute("border")) : r.style.border = "2px solid #dee2e6", u(r);
1880
+ } else if (l === "rounded") {
1881
+ var H = r.style.borderRadius || "";
1882
+ H && H !== "0px" ? r.style.borderRadius = "" : r.style.borderRadius = "8px", u(r);
1883
+ } else if (l === "caption") {
1884
+ var B = r.parentNode;
1885
+ if (B && B.tagName === "FIGURE" && B.classList.contains("te-figure")) {
1886
+ var f = B.parentNode, _ = B.querySelector("img") || B.querySelector("figcaption");
1887
+ _ && (f.insertBefore(_, B), f.removeChild(B));
1888
+ } else {
1889
+ var w = document.createElement("figure");
1890
+ w.className = "te-figure";
1891
+ var g = document.createElement("figcaption");
1892
+ g.textContent = "Caption", r.parentNode.insertBefore(w, r), w.appendChild(r), w.appendChild(g), g.contentEditable = "true";
1893
+ }
1894
+ u(r);
1895
+ }
1896
+ }
1897
+ }), n.addEventListener("keydown", function(m) {
1898
+ if (m.key === "Enter" && r) {
1899
+ var v = n.querySelector(".te-image-tools-alt");
1900
+ if (v) {
1901
+ var l = v.value.trim();
1902
+ l ? r.setAttribute("alt", l) : r.removeAttribute("alt");
1903
+ }
1904
+ }
1905
+ });
1906
+ var k = null;
1907
+ a.addEventListener("mousedown", function(m) {
1908
+ if (m.preventDefault(), m.stopPropagation(), !!r) {
1909
+ var v = r.parentNode ? r.parentNode.clientWidth : r.clientWidth, l = r.clientWidth / v * 100, f = r.getBoundingClientRect();
1910
+ k = {
1911
+ startX: m.clientX,
1912
+ parentW: v,
1913
+ startPct: l,
1914
+ startH: f.height
1915
+ }, document.addEventListener("mousemove", T), document.addEventListener("mouseup", x);
1916
+ }
1917
+ });
1918
+ function T(m) {
1919
+ if (!(!k || !r)) {
1920
+ var v = m.clientX - k.startX, l = v / k.parentW * 100, f = Math.max(5, k.startPct + l);
1921
+ r.style.width = f + "%", r.style.height = "auto", r.removeAttribute("width"), r.removeAttribute("height"), p(r);
1922
+ }
1923
+ }
1924
+ function x() {
1925
+ document.removeEventListener("mousemove", T), document.removeEventListener("mouseup", x), k = null, r && u(r);
1926
+ }
1927
+ window.addEventListener("scroll", function() {
1928
+ r && n.style.display !== "none" && u(r);
1929
+ }), window.addEventListener("resize", function() {
1930
+ r && n.style.display !== "none" && u(r);
1931
+ });
1932
+ }
1933
+ }, xt = {
1934
+ name: "iframe",
1935
+ order: 53,
1936
+ toolbarHTML: '<button type="button" class="btn btn-sm btn-light" title="Iframe" data-cmd="insertIframe"><i class="ti ti-video"></i></button>',
1937
+ modalHTML: '<div class="te-iframe-modal te-modal" aria-hidden="true"> <div class="te-modal-backdrop" data-te-close></div> <div class="te-modal-dialog"> <div class="te-modal-header"> <h5 class="te-modal-title m-0">Insert Iframe</h5> <button type="button" class="btn-close" data-te-close aria-label="Close"></button> </div> <form class="te-iframe-form"> <div class="te-modal-body"> <div class="mb-3"> <label class="form-label">Src URL</label> <input type="url" class="te-iframe-src form-control" placeholder="https://..." required> </div> <div class="row g-2 mb-3"> <div class="col"> <label class="form-label">Width (px)</label> <input type="number" min="0" class="te-iframe-width form-control" placeholder="640"> </div> <div class="col"> <label class="form-label">Height (px)</label> <input type="number" min="0" class="te-iframe-height form-control" placeholder="360"> </div> </div> <div class="mb-3"> <label class="form-label">Allow (optional)</label> <input type="text" class="te-iframe-allow form-control" placeholder="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"> </div> <div class="form-check mb-2"> <input class="te-iframe-allowfullscreen form-check-input" type="checkbox" checked> <label class="form-check-label">Allow Fullscreen</label> </div> <div class="mb-2"> <label class="form-label">Title (accessibility, optional)</label> <input type="text" class="te-iframe-title form-control" placeholder="Embedded content description"> </div> </div> <div class="te-modal-footer"> <button type="button" class="btn btn-outline-secondary" data-te-close>Cancel</button> <button type="submit" class="btn btn-primary">Insert</button> </div> </form> </div></div>',
1938
+ init(e) {
1939
+ if (e.features.iframe) {
1940
+ var t = e.wrapper.querySelector('[data-cmd="insertIframe"]');
1941
+ t && t.addEventListener("click", function() {
1942
+ e.saveSel();
1943
+ var r = e.wrapper.querySelector(".te-iframe-modal");
1944
+ r && r.classList.add("is-open");
1945
+ });
1946
+ var o = e.wrapper.querySelector(".te-iframe-form");
1947
+ o && o.addEventListener("submit", function(r) {
1948
+ r.preventDefault(), e.restoreSel();
1949
+ var n = (e.wrapper.querySelector(".te-iframe-src").value || "").trim(), a = (e.wrapper.querySelector(".te-iframe-width").value || "").trim(), i = (e.wrapper.querySelector(".te-iframe-height").value || "").trim();
1950
+ if (n) {
1951
+ var c = e.utils.isAllowedIframeUrl ? e.utils.isAllowedIframeUrl(n) : !0;
1952
+ if (c) {
1953
+ var d = ' src="' + n.replace(/"/g, "&quot;") + '"';
1954
+ a && (d += ' width="' + a.replace(/"/g, "&quot;") + '"'), i && (d += ' height="' + i.replace(/"/g, "&quot;") + '"');
1955
+ var p = e.options && e.options.iframeSandbox || "", s = e.options && e.options.iframeAllow || "";
1956
+ p && (d += ' sandbox="' + p.replace(/"/g, "&quot;") + '"'), s && (d += ' allow="' + s.replace(/"/g, "&quot;") + '"');
1957
+ var u = "<iframe" + d + ' style="max-width:100%;border:0;"></iframe>';
1958
+ document.execCommand("insertHTML", !1, u), o.closest(".te-modal").classList.remove("is-open");
1959
+ }
1960
+ }
1961
+ });
1962
+ }
1963
+ }
1964
+ };
1965
+ var we = 10, Ct = 10;
1966
+ const Et = {
1967
+ name: "table",
1968
+ order: 54,
1969
+ css: '.te-table-grid { position: absolute; z-index: 3000; background: #fff; border: 1px solid #dee2e6; border-radius: .5rem; box-shadow: 0 6px 20px rgba(0,0,0,.15); padding: .75rem;}.te-table-grid .te-tg-label { font-size: .8rem; color: #6c757d; text-align: center; margin-bottom: .5rem;}.te-table-grid .te-tg-cells { display: grid; gap: 2px;}.te-table-grid .te-tg-cell { width: 18px; height: 18px; background: #f0f0f0; border: 1px solid #dee2e6; border-radius: 2px; cursor: pointer;}.te-table-grid .te-tg-cell.active { background: #86b7fe; border-color: #0d6efd;}.te-tg-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: .5rem;}.te-toolbar [data-cmd="insertTable"] svg { pointer-events: none; }',
1970
+ toolbarHTML: '<button type="button" class="btn btn-sm btn-light" title="Table" data-cmd="insertTable"><i class="ti ti-table-plus"></i></button>',
1971
+ modalHTML: '<div class="te-table-props-modal te-modal" aria-hidden="true"> <div class="te-modal-backdrop" data-te-close></div> <div class="te-modal-dialog"> <div class="te-modal-header"> <h5 class="te-modal-title m-0">Table Properties</h5> <button type="button" class="btn-close" data-te-close aria-label="Close"></button> </div> <form class="te-table-props-form"> <div class="te-modal-body"> <div class="mb-3"> <label class="form-label">Width (e.g. 100% or 800px)</label> <input type="text" class="te-table-props-width form-control" placeholder="100%"> </div> <div class="mb-3"> <label class="form-label">Caption</label> <input type="text" class="te-table-props-caption form-control" placeholder="Optional caption"> </div> </div> <div class="te-modal-footer"> <button type="button" class="btn btn-outline-secondary" data-te-close>Cancel</button> <button type="submit" class="btn btn-primary">Apply</button> </div> </form> </div></div>',
1972
+ init(e) {
1973
+ if (!e.features.table) return;
1974
+ var t = document.createElement("div");
1975
+ t.className = "te-table-grid", t.style.display = "none", t.innerHTML = '<div class="te-tg-header"><span class="te-tg-label">0 &times; 0</span><button type="button" class="btn-close te-tg-close" aria-label="Close"></button></div><div class="te-tg-cells" style="grid-template-columns: repeat(' + we + ', 18px);"></div>';
1976
+ for (var o = t.querySelector(".te-tg-cells"), r = t.querySelector(".te-tg-label"), n = 0; n < Ct; n++)
1977
+ for (var a = 0; a < we; a++) {
1978
+ var i = document.createElement("div");
1979
+ i.className = "te-tg-cell", i.setAttribute("data-r", n.toString()), i.setAttribute("data-c", a.toString()), o.appendChild(i);
1980
+ }
1981
+ function c() {
1982
+ t.querySelectorAll(".te-tg-cell.active").forEach(function(u) {
1983
+ u.classList.remove("active");
1984
+ });
1985
+ }
1986
+ function d(u, b) {
1987
+ c(), t.querySelectorAll(".te-tg-cell").forEach(function(k) {
1988
+ var T = parseInt(k.getAttribute("data-r"), 10), x = parseInt(k.getAttribute("data-c"), 10);
1989
+ T <= u && x <= b && k.classList.add("active");
1990
+ }), r.textContent = b + 1 + " × " + (u + 1);
1991
+ }
1992
+ o.addEventListener("mouseover", function(u) {
1993
+ var b = u.target.closest(".te-tg-cell");
1994
+ if (b) {
1995
+ var k = parseInt(b.getAttribute("data-r"), 10), T = parseInt(b.getAttribute("data-c"), 10);
1996
+ d(k, T);
1997
+ }
1998
+ }), o.addEventListener("mouseleave", function() {
1999
+ c(), r.textContent = "0 × 0";
2000
+ });
2001
+ function p(u, b) {
2002
+ e.restoreSel();
2003
+ for (var k = '<table class="te-table"><tbody>', T = 0; T < b; T++) {
2004
+ k += "<tr>";
2005
+ for (var x = 0; x < u; x++)
2006
+ k += "<td><br></td>";
2007
+ k += "</tr>";
2008
+ }
2009
+ k += "</tbody></table>", document.execCommand("insertHTML", !1, k);
2010
+ }
2011
+ o.addEventListener("click", function(u) {
2012
+ var b = u.target.closest(".te-tg-cell");
2013
+ if (b) {
2014
+ var k = parseInt(b.getAttribute("data-c"), 10) + 1, T = parseInt(b.getAttribute("data-r"), 10) + 1;
2015
+ t.style.display = "none", p(k, T), e.editor.focus();
2016
+ }
2017
+ }), document.body.appendChild(t), t.querySelector(".te-tg-close").addEventListener("click", function() {
2018
+ t.style.display = "none";
2019
+ });
2020
+ var s = e.wrapper.querySelector('[data-cmd="insertTable"]');
2021
+ s && s.addEventListener("click", function(u) {
2022
+ u.stopPropagation(), e.saveSel();
2023
+ var b = s.getBoundingClientRect();
2024
+ t.style.left = window.scrollX + b.left + "px", t.style.top = window.scrollY + b.bottom + 4 + "px", t.style.display = t.style.display === "none" ? "block" : "none";
2025
+ }), document.addEventListener("click", function(u) {
2026
+ t.style.display !== "none" && !t.contains(u.target) && u.target !== s && (t.style.display = "none");
2027
+ });
2028
+ }
2029
+ }, Tt = {
2030
+ name: "tableTools",
2031
+ order: 55,
2032
+ deps: ["table"],
2033
+ css: ".te-table-tools { position: absolute; display: none; z-index: 2000; background: #fff; border: 1px solid #dee2e6; border-radius: .375rem; box-shadow: 0 6px 20px rgba(0,0,0,.15); padding: .2rem .3rem; gap: .1rem; align-items: center; white-space: nowrap;}.te-table-tools .btn { padding: .15rem .35rem !important; font-size: .7rem !important; line-height: 1 !important;}.te-table-tools .btn svg { width: 12px !important; height: 12px !important; margin-right: 2px; vertical-align: middle;}.te-table-tools .te-divider-v { display: inline-block; width: 1px; height: 16px; background: #dee2e6; margin: 0 .2rem;}.te-table-tools .tt-label { font-size: .6rem; color: #6c757d; text-transform: uppercase; letter-spacing: .5px; margin: 0 .15rem;}.te-table-tools .te-bg-input { width: 26px !important; height: 20px !important; padding: 1px !important; border: 1px solid #dee2e6; border-radius: 3px; cursor: pointer;}.te-cell-selected { outline: 2px solid #0d6efd !important; outline-offset: -1px;}",
2034
+ init(e) {
2035
+ if (!e.features.table || !e.features.tableTools) return;
2036
+ var t = e.wrapper, o = e.editor, r = e.editor, n = document.createElement("div");
2037
+ n.className = "te-table-tools", n.style.display = "none", n.innerHTML = '<span class="tt-label">Add</span><button type="button" class="btn btn-sm btn-light" data-te-table="row-before" title="Row above"><i class="ti ti-chevron-up"></i> Row</button><button type="button" class="btn btn-sm btn-light" data-te-table="row-after" title="Row below"><i class="ti ti-chevron-down"></i> Row</button><button type="button" class="btn btn-sm btn-light" data-te-table="col-before" title="Column before"><i class="ti ti-chevron-left"></i> Col</button><button type="button" class="btn btn-sm btn-light" data-te-table="col-after" title="Column after"><i class="ti ti-chevron-right"></i> Col</button><span class="te-divider-v"></span><span class="tt-label">Del</span><button type="button" class="btn btn-sm btn-outline-danger" data-te-table="del-row" title="Delete row"><i class="ti ti-x"></i> Row</button><button type="button" class="btn btn-sm btn-outline-danger" data-te-table="del-col" title="Delete column"><i class="ti ti-x"></i> Col</button><button type="button" class="btn btn-sm btn-outline-danger" data-te-table="del-table" title="Delete table"><i class="ti ti-trash"></i> Tbl</button><span class="te-divider-v"></span><button type="button" class="btn btn-sm btn-light" data-te-table="merge" title="Merge selected cells"><i class="ti ti-maximize"></i> Merge</button><button type="button" class="btn btn-sm btn-light" data-te-table="unmerge" title="Unmerge cells" style="display:none"><i class="ti ti-minimize"></i> Unmerge</button><span class="te-divider-v"></span><button type="button" class="btn btn-sm btn-outline-secondary" data-te-table="toggle-header" title="Toggle header"><i class="ti ti-typography"></i> Hdr</button><button type="button" class="btn btn-sm btn-outline-secondary" data-te-table="toggle-caption" title="Toggle caption"><i class="ti ti-align-left"></i> Cap</button><span class="te-divider-v"></span><span class="tt-label">BG</span><input type="color" class="te-bg-input form-control form-control-color" value="#ffffff" title="Cell background color" /><button type="button" class="btn btn-sm btn-light" data-te-table="bg-apply" title="Apply background color">Apply</button><button type="button" class="btn btn-sm btn-light" data-te-table="bg-clear" title="Remove background color">Clear</button><span class="te-divider-v"></span><span class="tt-label">V</span><button type="button" class="btn btn-sm btn-light" data-te-table="valign-top" title="Align top">Top</button><button type="button" class="btn btn-sm btn-light" data-te-table="valign-middle" title="Align middle">Mid</button><button type="button" class="btn btn-sm btn-light" data-te-table="valign-bottom" title="Align bottom">Bot</button>', document.body.appendChild(n);
2038
+ var a = null, i = null, c = null, d = null, p = [];
2039
+ function s() {
2040
+ r._tableHist || (r._tableHist = { undo: [], redo: [] }), r._tableHist.undo.push(o.innerHTML), r._tableHist.redo = [], r._tableHist.undo.length > 50 && r._tableHist.undo.shift();
2041
+ }
2042
+ function u() {
2043
+ var y = n.querySelector('[data-te-table="merge"]');
2044
+ y && (y.style.display = p.length >= 2 ? "" : "none");
2045
+ }
2046
+ function b() {
2047
+ p.forEach(function(y) {
2048
+ y.classList.remove("te-cell-selected");
2049
+ }), p = [], u();
2050
+ }
2051
+ function k(y) {
2052
+ var h = p.indexOf(y);
2053
+ h !== -1 ? (p.splice(h, 1), y.classList.remove("te-cell-selected")) : (p.push(y), y.classList.add("te-cell-selected")), u();
2054
+ }
2055
+ o.addEventListener("click", function(y) {
2056
+ var h = y.target.closest && y.target.closest("td,th");
2057
+ !h || !o.contains(h) || (y.ctrlKey || y.metaKey ? (y.preventDefault(), k(h)) : y.shiftKey || b());
2058
+ });
2059
+ function T(y) {
2060
+ var h = n.querySelector('[data-te-table="unmerge"]');
2061
+ if (h) {
2062
+ var L = parseInt(y.getAttribute("colspan"), 10) || 1, N = parseInt(y.getAttribute("rowspan"), 10) || 1;
2063
+ h.style.display = L > 1 || N > 1 ? "" : "none";
2064
+ }
2065
+ }
2066
+ function x(y) {
2067
+ n.querySelectorAll('[data-te-table^="valign-"]').forEach(function(h) {
2068
+ var L = h.getAttribute("data-te-table").replace("valign-", ""), N = (y.style.verticalAlign || "").toLowerCase();
2069
+ h.classList.toggle("active", N === L);
2070
+ });
2071
+ }
2072
+ function m(y) {
2073
+ var h = y.getBoundingClientRect();
2074
+ n.style.display = "flex", n.style.visibility = "hidden";
2075
+ var L = n.offsetWidth, N = n.offsetHeight, A = o.getBoundingClientRect(), C = window.scrollX, I = window.scrollY, z = h.left + C, D = A.left + C + 2, U = A.right + C - L - 2;
2076
+ z < D && (z = D), z > U && (z = U), n.style.left = z + "px";
2077
+ var j = A.bottom - (h.bottom + 6), F = h.top - 6 - A.top, O;
2078
+ j >= N || j >= F ? O = h.bottom + 6 + I : O = h.top - 6 - N + I;
2079
+ var R = A.top + I + 2, K = A.bottom + I - N - 2;
2080
+ O < R && (O = R), O > K && (O = K), n.style.top = O + "px", n.style.visibility = "", u(), T(y), x(y);
2081
+ var X = n.querySelector('[data-te-table="toggle-caption"]');
2082
+ X && i && X.classList.toggle("active", !!i.querySelector("caption"));
2083
+ }
2084
+ function v() {
2085
+ n.style.display = "none", a = null, i = null;
2086
+ }
2087
+ function l() {
2088
+ var y = window.getSelection();
2089
+ if (!y || y.rangeCount === 0) {
2090
+ v();
2091
+ return;
2092
+ }
2093
+ var h = y.anchorNode;
2094
+ if (h && h.nodeType === 3 && (h = h.parentNode), !h || !t.contains(h)) {
2095
+ v();
2096
+ return;
2097
+ }
2098
+ var L = h.closest && h.closest("td,th");
2099
+ L && o.contains(L) ? (a = L, i = L.closest("table"), c = a, d = i, m(L)) : v();
2100
+ }
2101
+ function f() {
2102
+ var y = n.querySelectorAll(".te-cell-selected");
2103
+ if (y.length) return Array.prototype.slice.call(y);
2104
+ var h = window.getSelection();
2105
+ if (!h || h.rangeCount === 0) return null;
2106
+ var L = h.getRangeAt(0), N = i || d;
2107
+ if (!N) return null;
2108
+ var A = [];
2109
+ return N.querySelectorAll("td,th").forEach(function(C) {
2110
+ L.intersectsNode(C) && A.push(C);
2111
+ }), A.length ? A : null;
2112
+ }
2113
+ function S(y) {
2114
+ var h = f();
2115
+ if (h)
2116
+ for (var L = 0; L < h.length; L++)
2117
+ h[L].style.backgroundColor = y;
2118
+ }
2119
+ function E() {
2120
+ var y = f();
2121
+ if (y)
2122
+ for (var h = 0; h < y.length; h++)
2123
+ y[h].style.backgroundColor = "";
2124
+ }
2125
+ var q = n.querySelector(".te-bg-input");
2126
+ q && q.addEventListener("change", function() {
2127
+ (a || c) && S(q.value);
2128
+ }), document.addEventListener("selectionchange", l), window.addEventListener("scroll", function() {
2129
+ a && m(a);
2130
+ }), window.addEventListener("resize", function() {
2131
+ a && m(a);
2132
+ });
2133
+ function H(y) {
2134
+ for (var h = 0, L = y; L && L.previousElementSibling; )
2135
+ h++, L = L.previousElementSibling;
2136
+ return h;
2137
+ }
2138
+ function B(y, h) {
2139
+ ["thead", "tbody"].forEach(function(L) {
2140
+ var N = y.querySelector(L);
2141
+ N && Array.prototype.forEach.call(N.rows, function(A) {
2142
+ h(A, L);
2143
+ });
2144
+ });
2145
+ }
2146
+ var _;
2147
+ function w() {
2148
+ _ && clearTimeout(_), _ = setTimeout(function() {
2149
+ e.editor.focus(), l(), _ = null;
2150
+ }, 0);
2151
+ }
2152
+ function g() {
2153
+ var y = i || d;
2154
+ if (y) {
2155
+ var h = Array.prototype.slice.call(y.querySelectorAll("tr"));
2156
+ if (h.length) {
2157
+ var L;
2158
+ if (p.length > 1)
2159
+ L = p.slice();
2160
+ else {
2161
+ var N = window.getSelection();
2162
+ if (!N || N.rangeCount === 0) return;
2163
+ var A = N.getRangeAt(0);
2164
+ L = [], y.querySelectorAll("td,th").forEach(function(R) {
2165
+ A.intersectsNode(R) && L.push(R);
2166
+ });
2167
+ }
2168
+ if (!(L.length < 2)) {
2169
+ s();
2170
+ var C = L.map(function(R) {
2171
+ return {
2172
+ cell: R,
2173
+ row: h.indexOf(R.parentElement),
2174
+ col: H(R)
2175
+ };
2176
+ }), I = Math.min.apply(null, C.map(function(R) {
2177
+ return R.row;
2178
+ })), z = Math.max.apply(null, C.map(function(R) {
2179
+ return R.row;
2180
+ })), D = Math.min.apply(null, C.map(function(R) {
2181
+ return R.col;
2182
+ })), U = Math.max.apply(null, C.map(function(R) {
2183
+ return R.col;
2184
+ }));
2185
+ if (I !== z && D !== U) {
2186
+ var j = n.querySelector('[data-te-table="merge"]');
2187
+ j && (j.style.outline = "2px solid #dc3545", j.style.outlineOffset = "1px", setTimeout(function() {
2188
+ j.style.outline = "", j.style.outlineOffset = "";
2189
+ }, 600));
2190
+ return;
2191
+ }
2192
+ var F = L.map(function(R) {
2193
+ return R.innerHTML;
2194
+ }), O = C.filter(function(R) {
2195
+ return R.row === I && R.col === D;
2196
+ })[0];
2197
+ O || (O = C[0]), L.forEach(function(R) {
2198
+ R !== O.cell && R.parentNode.removeChild(R);
2199
+ }), O.cell.setAttribute("colspan", String(U - D + 1)), O.cell.setAttribute("rowspan", String(z - I + 1)), O.cell.innerHTML = F.join(""), b();
2200
+ }
2201
+ }
2202
+ }
2203
+ }
2204
+ function M(y) {
2205
+ var h = parseInt(y.getAttribute("colspan"), 10) || 1, L = parseInt(y.getAttribute("rowspan"), 10) || 1;
2206
+ if (!(h === 1 && L === 1)) {
2207
+ var N = y.tagName, A = y.closest("table"), C = Array.prototype.slice.call(A.querySelectorAll("tr")), I = y.parentElement, z = C.indexOf(I), D = H(y);
2208
+ y.removeAttribute("colspan"), y.removeAttribute("rowspan"), y.innerHTML = "<br>";
2209
+ for (var U = y.nextSibling, j = 1; j < h; j++) {
2210
+ var F = document.createElement(N);
2211
+ F.innerHTML = "<br>", I.insertBefore(F, U);
2212
+ }
2213
+ for (var O = 1; O < L; O++) {
2214
+ var R = C[z + O];
2215
+ if (!R) break;
2216
+ for (var K = R.cells[D] || null, j = 0; j < h; j++) {
2217
+ var F = document.createElement(N);
2218
+ F.innerHTML = "<br>", R.insertBefore(F, K);
2219
+ }
2220
+ }
2221
+ }
2222
+ }
2223
+ n.addEventListener("mousedown", function(y) {
2224
+ var h = y.target && y.target.closest("[data-te-table]"), L = h && h.getAttribute("data-te-table");
2225
+ if (L) {
2226
+ y.preventDefault();
2227
+ var N = a || c, A = i || d;
2228
+ if (!(!N || !A)) {
2229
+ s();
2230
+ var C = N.parentElement, I = H(N);
2231
+ if (L === "row-before" || L === "row-after") {
2232
+ var z = C.cloneNode(!0);
2233
+ Array.prototype.forEach.call(z.cells, function(P) {
2234
+ P.innerHTML = "<br>", P.removeAttribute("colspan"), P.removeAttribute("rowspan");
2235
+ }), L === "row-before" ? C.parentNode.insertBefore(z, C) : C.parentNode.insertBefore(z, C.nextSibling), w();
2236
+ } else if (L === "col-before" || L === "col-after") {
2237
+ var D = L === "col-after";
2238
+ B(A, function(P, $) {
2239
+ var Y = P.cells[I], G = document.createElement($ === "thead" ? "th" : "td");
2240
+ G.innerHTML = "<br>", D && Y && Y.nextSibling ? P.insertBefore(G, Y.nextSibling) : Y ? P.insertBefore(G, Y) : P.appendChild(G);
2241
+ }), w();
2242
+ } else if (L === "del-row")
2243
+ C.parentNode.removeChild(C), A.querySelector("tr") ? w() : (A.parentNode.removeChild(A), v());
2244
+ else if (L === "del-col") {
2245
+ B(A, function(P) {
2246
+ P.cells[I] && P.deleteCell(I);
2247
+ });
2248
+ var U = A.querySelector("tr");
2249
+ U && U.cells.length === 0 ? (A.parentNode.removeChild(A), v()) : w();
2250
+ } else if (L === "del-table")
2251
+ A.parentNode.removeChild(A), v();
2252
+ else if (L === "bg-apply")
2253
+ S(q ? q.value : "#ffffff"), w();
2254
+ else if (L === "bg-clear")
2255
+ E(), w();
2256
+ else if (L === "valign-top" || L === "valign-middle" || L === "valign-bottom") {
2257
+ var j = f();
2258
+ (!j || !j.length) && (j = [N]);
2259
+ for (var F = L.replace("valign-", ""), O = 0; O < j.length; O++)
2260
+ j[O].style.verticalAlign = F;
2261
+ w();
2262
+ } else if (L === "merge")
2263
+ g(), w();
2264
+ else if (L === "unmerge")
2265
+ M(N), w();
2266
+ else if (L === "toggle-header") {
2267
+ var R = A.querySelector("thead");
2268
+ if (R) {
2269
+ var K = A.querySelector("tbody") || (function() {
2270
+ var P = document.createElement("tbody");
2271
+ return A.appendChild(P), P;
2272
+ })();
2273
+ Array.prototype.slice.call(R.rows).forEach(function(P) {
2274
+ var $ = document.createElement("tr");
2275
+ Array.prototype.forEach.call(P.cells, function(Y) {
2276
+ var G = document.createElement("td");
2277
+ G.innerHTML = Y.innerHTML || "<br>", $.appendChild(G);
2278
+ }), K.insertBefore($, K.firstChild);
2279
+ }), R.parentNode.removeChild(R);
2280
+ } else {
2281
+ var X = A.querySelector("tbody");
2282
+ if (X && X.rows.length) {
2283
+ var se = X.rows[0], de = document.createElement("thead"), ce = document.createElement("tr");
2284
+ Array.prototype.forEach.call(se.cells, function(P) {
2285
+ var $ = document.createElement("th");
2286
+ $.innerHTML = P.innerHTML || "<br>", ce.appendChild($);
2287
+ }), de.appendChild(ce), A.insertBefore(de, X), X.removeChild(se);
2288
+ }
2289
+ }
2290
+ w();
2291
+ } else if (L === "toggle-caption") {
2292
+ var ee = A.querySelector("caption");
2293
+ if (ee)
2294
+ ee.parentNode.removeChild(ee);
2295
+ else {
2296
+ var W = document.createElement("caption");
2297
+ W.innerHTML = "<br>", W.contentEditable = "true", W.style.captionSide = "bottom", W.style.textAlign = "left", W.style.padding = "4px 6px", W.style.fontStyle = "italic", W.style.color = "#6c757d", A.insertBefore(W, A.firstChild), setTimeout(function() {
2298
+ W.focus();
2299
+ }, 0);
2300
+ }
2301
+ w();
2302
+ }
2303
+ }
2304
+ }
2305
+ });
2306
+ }
2307
+ }, At = {
2308
+ name: "hr",
2309
+ order: 55,
2310
+ toolbarHTML: '<button type="button" class="btn btn-sm btn-light" title="Horizontal rule" data-cmd="insertHR"><i class="ti ti-minus"></i></button>',
2311
+ css: '.te-hr-popup { position: fixed; display: none; z-index: 3000; background: #fff; border: 1px solid #dee2e6; border-radius: .375rem; box-shadow: 0 6px 20px rgba(0,0,0,.15); padding: .5rem; white-space: nowrap;}.te-hr-popup .btn { padding: .15rem .4rem !important; font-size: 1rem !important; line-height: 1 !important; margin-right: 2px;}.te-hr-popup .btn.active { background: #e7f1ff; border-color: #b6d4fe; }.te-hr-popup input[type="color"] { width: 26px; height: 22px; padding: 1px; border: 1px solid #dee2e6; border-radius: 3px; cursor: pointer; vertical-align: middle;}',
2312
+ init(e) {
2313
+ if (!e.features.hr) return;
2314
+ var t = e.wrapper.querySelector('[data-cmd="insertHR"]');
2315
+ if (!t) return;
2316
+ var o = document.createElement("div");
2317
+ o.className = "te-hr-popup", o.innerHTML = '<button type="button" class="btn btn-sm btn-light active" data-te-hr="solid" title="Solid">━</button><button type="button" class="btn btn-sm btn-light" data-te-hr="dashed" title="Dashed">┅</button><button type="button" class="btn btn-sm btn-light" data-te-hr="dotted" title="Dotted">┈</button><input type="color" class="te-hr-color" value="#cccccc" title="HR color" />', document.body.appendChild(o);
2318
+ var r = "solid", n = "#cccccc", a = null;
2319
+ function i() {
2320
+ var b = window.getSelection();
2321
+ b && b.rangeCount > 0 ? a = b.getRangeAt(0).cloneRange() : a = null;
2322
+ }
2323
+ function c() {
2324
+ if (a) {
2325
+ var b = window.getSelection();
2326
+ b.removeAllRanges(), b.addRange(a);
2327
+ }
2328
+ }
2329
+ function d() {
2330
+ var b = t.getBoundingClientRect(), k = o.offsetWidth || 200, T = b.left + b.width / 2 - k / 2;
2331
+ T < 4 && (T = 4), T + k > window.innerWidth - 4 && (T = window.innerWidth - k - 4), o.style.left = T + "px", o.style.top = b.bottom + 4 + "px";
2332
+ }
2333
+ function p() {
2334
+ e.editor.focus(), c();
2335
+ var b = "border: none; border-top: 2px " + r + " " + n + "; margin: 1em 0;";
2336
+ document.execCommand("insertHTML", !1, '<hr style="' + b + '">'), s();
2337
+ }
2338
+ function s() {
2339
+ o.style.display = "none";
2340
+ }
2341
+ function u() {
2342
+ i(), o.style.display = "block", d();
2343
+ }
2344
+ t.addEventListener("click", function(b) {
2345
+ if (b.preventDefault(), b.stopPropagation(), o.style.display === "block") {
2346
+ s();
2347
+ return;
2348
+ }
2349
+ u();
2350
+ }), o.addEventListener("mousedown", function(b) {
2351
+ var k = b.target.closest("[data-te-hr]");
2352
+ if (k) {
2353
+ b.preventDefault(), r = k.getAttribute("data-te-hr"), o.querySelectorAll("[data-te-hr]").forEach(function(T) {
2354
+ T.classList.remove("active");
2355
+ }), k.classList.add("active"), p();
2356
+ return;
2357
+ }
2358
+ }), o.addEventListener("change", function(b) {
2359
+ var k = b.target.closest(".te-hr-color");
2360
+ k && (n = k.value, p());
2361
+ }), document.addEventListener("click", function(b) {
2362
+ o.style.display === "block" && !o.contains(b.target) && b.target !== t && !t.contains(b.target) && s();
2363
+ }), window.addEventListener("scroll", function() {
2364
+ o.style.display === "block" && d();
2365
+ }), window.addEventListener("resize", function() {
2366
+ o.style.display === "block" && d();
2367
+ });
2368
+ }
2369
+ }, qt = {
2370
+ name: "unlink",
2371
+ order: 58,
2372
+ toolbarHTML: '<button type="button" class="btn btn-sm btn-light" title="Remove link" data-cmd="unlink"><i class="ti ti-x"></i></button>',
2373
+ init(e) {
2374
+ if (e.features.unlink) {
2375
+ var t = e.wrapper.querySelector('[data-cmd="unlink"]');
2376
+ t && t.addEventListener("click", function() {
2377
+ var o = window.getSelection();
2378
+ if (!(!o || o.rangeCount === 0)) {
2379
+ var r = o.anchorNode;
2380
+ r && r.nodeType === 3 && (r = r.parentNode);
2381
+ var n = r && r.closest && r.closest("a");
2382
+ if (n) {
2383
+ for (var a = n.parentNode; n.firstChild; )
2384
+ a.insertBefore(n.firstChild, n);
2385
+ a.removeChild(n);
2386
+ } else
2387
+ document.execCommand("unlink", !1, void 0);
2388
+ e.editor.focus();
2389
+ }
2390
+ });
2391
+ }
2392
+ }
2393
+ };
2394
+ var Ht = "😀😃😄😁😆😅🤣😂🙂🙃😉😊😇🥰😍🤩😘😗😚😋😛😜🤪😝🤑🤗🤭🤫🤔🤐🤨😐😑😶😏😒🙄😬🤥😌😔😪🤤😴😷🤒🤕🤢🤮🤧🥵🥶🥴😵🤯🤠🥳🥸😎🤓🧐😕😟🙁😮😯😲😳🥺😦😧😨😰😥😢😭😱😖😣😞😓😩😫🥱😤😡😠🤬😈👿💀☠💩🤡👹👺👻👽👾🤖💋👋✋👌🤏🤞🤟🤘🤙👈👉👆🖕👍👎✊👊🤛🤜👏🙌👐🤲🤝🙏✍💅👂👃👣👀👅👄".match(/.{1,2}/g) || [], ke = {
2395
+ "😀": "grinning laugh happy",
2396
+ "😃": "grinning smile happy",
2397
+ "😄": "grinning smile happy",
2398
+ "😁": "beaming grin happy",
2399
+ "😆": "laughing grinning",
2400
+ "🤣": "rolling floor laughing",
2401
+ "😂": "tears joy laughing cry",
2402
+ "🙂": "slight smile",
2403
+ "🙃": "upside down",
2404
+ "😉": "winking wink",
2405
+ "😊": "blush smile happy",
2406
+ "😇": "innocent halo angel",
2407
+ "🥰": "love heart smile",
2408
+ "😍": "heart eyes love",
2409
+ "🤩": "star struck",
2410
+ "😘": "kiss blowing heart",
2411
+ "😗": "kissing kiss",
2412
+ "😚": "kiss closed eyes",
2413
+ "😋": "savor tongue yum",
2414
+ "😛": "tongue playful",
2415
+ "😜": "wink tongue silly",
2416
+ "🤪": "crazy wild",
2417
+ "😝": "squint tongue",
2418
+ "🤑": "money tongue rich",
2419
+ "🤗": "hug open hands",
2420
+ "🤭": "hand over mouth secret",
2421
+ "🤫": "shush quiet silent",
2422
+ "🤔": "thinking think",
2423
+ "🤐": "zipper mouth secret",
2424
+ "🤨": "raised eyebrow suspicious",
2425
+ "😐": "neutral straight face",
2426
+ "😑": "expressionless blank",
2427
+ "😶": "no mouth silent",
2428
+ "😏": "smirk smug",
2429
+ "😒": "unamified roll",
2430
+ "🙄": "eye roll",
2431
+ "😬": "grimace awkward",
2432
+ "🤥": "lying liar nose",
2433
+ "😌": "relieved relief",
2434
+ "😔": "pensive sad",
2435
+ "😪": "sleepy tired",
2436
+ "🤤": "drooling drool",
2437
+ "😴": "sleeping sleep zzz",
2438
+ "😷": "medical mask sick",
2439
+ "🤒": "thermometer sick fever",
2440
+ "🤕": "head bandage hurt",
2441
+ "🤢": "nauseous sick vomit",
2442
+ "🤮": "vomiting sick",
2443
+ "🤧": "sneeze sick",
2444
+ "🥵": "hot fever sweat",
2445
+ "🥶": "cold freeze ice",
2446
+ "🥴": "dizzy tipsy",
2447
+ "😵": "dizzy confused",
2448
+ "🤯": "exploding head mind blown",
2449
+ "🤠": "cowboy hat",
2450
+ "🥳": "party celebration",
2451
+ "🥸": "disguise mask",
2452
+ "😎": "sunglasses cool",
2453
+ "🤓": "nerd geek glasses",
2454
+ "🧐": "monocle detective",
2455
+ "😕": "confused unsure",
2456
+ "😟": "worried concern",
2457
+ "🙁": "slight frown sad",
2458
+ "😮": "surprised shock",
2459
+ "😯": "hushed surprise",
2460
+ "😲": "astonished amazed",
2461
+ "😳": "flushed embarrassed",
2462
+ "🥺": "pleading puppy eyes",
2463
+ "😦": "frown sad",
2464
+ "😧": "anguish distressed",
2465
+ "😨": "fearful afraid",
2466
+ "😰": "anxious sweat worry",
2467
+ "😥": "disappointed sad",
2468
+ "😢": "cry sad tear",
2469
+ "😭": "sobbing cry tears",
2470
+ "😱": "scream fear horror",
2471
+ "😖": "confounded frustrated",
2472
+ "😣": "persevere struggle",
2473
+ "😞": "disappointed sad",
2474
+ "😓": "downcast sweat",
2475
+ "😩": "weary tired",
2476
+ "😫": "tired exhausted",
2477
+ "🥱": "yawn sleepy",
2478
+ "😤": "triumph frustrated steam",
2479
+ "😡": "angry rage",
2480
+ "😠": "angry mad",
2481
+ "🤬": "cursing swear",
2482
+ "😈": "devil evil grin",
2483
+ "👿": "devil evil angry",
2484
+ "💀": "skull death",
2485
+ "☠": "skull crossbones danger",
2486
+ "💩": "poop poo",
2487
+ "🤡": "clown circus",
2488
+ "👹": "ogre monster",
2489
+ "👺": "goblin monster",
2490
+ "👻": "ghost halloween",
2491
+ "👽": "alien ufo",
2492
+ "👾": "alien monster space",
2493
+ "🤖": "robot ai",
2494
+ "💋": "kiss lips",
2495
+ "👋": "wave hand hello bye",
2496
+ "✋": "raised hand stop high five",
2497
+ "👌": "ok perfect",
2498
+ "🤏": "pinching small little",
2499
+ "🤞": "crossed fingers luck",
2500
+ "🤟": "love gesture",
2501
+ "🤘": "horns rock metal",
2502
+ "🤙": "call me phone",
2503
+ "👈": "point left",
2504
+ "👉": "point right",
2505
+ "👆": "point up",
2506
+ "🖕": "middle finger fuck",
2507
+ "👍": "thumbs up like",
2508
+ "👎": "thumbs down dislike",
2509
+ "✊": "fist raised power",
2510
+ "👊": "fist punch",
2511
+ "🤛": "fist left",
2512
+ "🤜": "fist right",
2513
+ "👏": "clap applause",
2514
+ "🙌": "raised hands celebration",
2515
+ "👐": "open hands",
2516
+ "🤲": "palms together pray",
2517
+ "🤝": "handshake deal agree",
2518
+ "🙏": "folded hands pray please thank",
2519
+ "✍": "writing hand",
2520
+ "💅": "nail polish care",
2521
+ "👂": "ear listen",
2522
+ "👃": "nose smell",
2523
+ "👣": "footsteps feet",
2524
+ "👀": "eyes look",
2525
+ "👅": "tongue taste",
2526
+ "👄": "mouth lips"
2527
+ };
2528
+ const Mt = {
2529
+ name: "emoji",
2530
+ order: 60,
2531
+ css: ".te-emoji-popup { position: absolute; z-index: 3000; background: #fff; border: 1px solid #dee2e6; border-radius: .5rem; box-shadow: 0 6px 20px rgba(0,0,0,.15); padding: .4rem; max-width: 290px;}.te-emoji-popup .te-emoji-search { width: 100%; box-sizing: border-box; padding: .3rem .5rem; margin-bottom: .4rem; border: 1px solid #dee2e6; border-radius: .375rem; font-size: .8rem; outline: none;}.te-emoji-popup .te-emoji-search:focus { border-color: #86b7fe; box-shadow: 0 0 0 2px rgba(13,110,253,.15);}.te-emoji-popup .te-emoji-no-result { padding: 1rem; text-align: center; color: #6c757d; font-size: .8rem;}.te-emoji-popup .te-emoji-grid { display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px; max-height: 220px; overflow-y: auto;}.te-emoji-popup .te-emoji-grid button { background: none; border: none; font-size: 1.3rem; padding: .25rem; cursor: pointer; border-radius: .25rem; text-align: center;}.te-emoji-popup .te-emoji-grid button:hover { background: #f0f0f0; }.te-emoji-popup .te-emoji-grid button.hidden { display: none; }",
2532
+ toolbarHTML: '<button type="button" class="btn btn-sm btn-light" title="Emoji" data-cmd="emoji"><i class="ti ti-mood-smile"></i></button>',
2533
+ init(e) {
2534
+ if (!e.features.emoji) return;
2535
+ var t = document.createElement("div");
2536
+ t.className = "te-emoji-popup", t.style.display = "none", t.innerHTML = '<input type="text" class="te-emoji-search" placeholder="Search emoji..." /><div class="te-emoji-grid"></div><div class="te-emoji-no-result" style="display:none">No emoji found</div>';
2537
+ var o = t.querySelector(".te-emoji-grid"), r = t.querySelector(".te-emoji-search"), n = t.querySelector(".te-emoji-no-result");
2538
+ Ht.forEach(function(s) {
2539
+ var u = document.createElement("button");
2540
+ u.type = "button", u.textContent = s, u.setAttribute("data-emoji", s), u.title = ke[s] || "", o.appendChild(u);
2541
+ }), document.body.appendChild(t);
2542
+ var a = e.wrapper.querySelector('[data-cmd="emoji"]'), i = null;
2543
+ function c() {
2544
+ var s = window.getSelection();
2545
+ s && s.rangeCount > 0 ? i = s.getRangeAt(0).cloneRange() : i = null;
2546
+ }
2547
+ function d() {
2548
+ if (i) {
2549
+ var s = window.getSelection();
2550
+ s.removeAllRanges(), s.addRange(i);
2551
+ }
2552
+ }
2553
+ function p() {
2554
+ c();
2555
+ var s = a.getBoundingClientRect();
2556
+ t.style.display = "block", t.style.visibility = "hidden";
2557
+ var u = t.offsetWidth, b = t.offsetHeight, k = window.scrollX, T = window.scrollY, x = window.innerWidth, m = window.innerHeight, v = s.left + k;
2558
+ v + u > k + x - 8 && (v = k + x - u - 8), v < k + 4 && (v = k + 4), t.style.left = v + "px";
2559
+ var l = s.bottom + 4 + T;
2560
+ l + b > T + m - 8 && (l = s.top - b - 4 + T), l < T + 4 && (l = T + 4), t.style.top = l + "px", t.style.visibility = "", r.value = "", o.querySelectorAll("button").forEach(function(f) {
2561
+ f.classList.remove("hidden");
2562
+ }), n.style.display = "none", r.focus();
2563
+ }
2564
+ a && a.addEventListener("click", function(s) {
2565
+ if (t.style.display !== "none") {
2566
+ t.style.display = "none";
2567
+ return;
2568
+ }
2569
+ p();
2570
+ }), r.addEventListener("input", function() {
2571
+ var s = r.value.trim().toLowerCase(), u = 0;
2572
+ o.querySelectorAll("button").forEach(function(b) {
2573
+ var k = (ke[b.textContent] || "").toLowerCase(), T = !s || k.indexOf(s) !== -1;
2574
+ b.classList.toggle("hidden", !T), T && u++;
2575
+ }), n.style.display = u ? "none" : "block";
2576
+ }), r.addEventListener("keydown", function(s) {
2577
+ s.key === "Escape" && (t.style.display = "none", e.editor.focus());
2578
+ }), t.addEventListener("mousedown", function(s) {
2579
+ var u = s.target.closest && s.target.closest("[data-emoji]");
2580
+ u && (s.preventDefault(), e.editor.focus(), d(), document.execCommand("insertHTML", !1, u.textContent), t.style.display = "none");
2581
+ }), document.addEventListener("click", function(s) {
2582
+ t.style.display !== "none" && !t.contains(s.target) && s.target !== a && (t.style.display = "none");
2583
+ });
2584
+ }
2585
+ }, Rt = {
2586
+ name: "direction",
2587
+ order: 61,
2588
+ toolbarHTML: '<button type="button" class="btn btn-sm btn-light" title="Left to Right" data-cmd="ltr"><i class="ti ti-arrow-left"></i> LTR</button><button type="button" class="btn btn-sm btn-light" title="Right to Left" data-cmd="rtl">RTL <i class="ti ti-arrow-right"></i></button>',
2589
+ init(e) {
2590
+ e.features.direction && e.wrapper.querySelectorAll('[data-cmd="ltr"],[data-cmd="rtl"]').forEach(function(t) {
2591
+ t.addEventListener("click", function() {
2592
+ var o = t.getAttribute("data-cmd");
2593
+ document.execCommand("formatBlock", !1, "p");
2594
+ var r = window.getSelection();
2595
+ if (r && r.rangeCount > 0) {
2596
+ var n = r.anchorNode;
2597
+ n && n.nodeType === 3 && (n = n.parentNode);
2598
+ var a = n && n.closest && n.closest("p,h1,h2,h3,h4,h5,h6,div");
2599
+ a && e.wrapper.contains(a) && a.setAttribute("dir", o);
2600
+ }
2601
+ e.editor.focus();
2602
+ });
2603
+ });
2604
+ }
2605
+ }, Nt = {
2606
+ name: "source",
2607
+ order: 65,
2608
+ css: ".te-source-toggle.active { background: #e7f1ff; border-color: #b6d4fe; }.te-editor.te-source-mode { display: none; }.te-source-textarea { width: 100%; min-height: 200px; border: 1px solid #dee2e6; border-radius: .375rem; padding: .75rem; resize: vertical; font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-size: .85rem; line-height: 1.6; display: none;}",
2609
+ toolbarHTML: '<button type="button" class="btn btn-sm btn-outline-secondary" title="Toggle source" data-cmd="editSource"><i class="ti ti-source-code"></i></button>',
2610
+ init(e) {
2611
+ if (!e.features.source) return;
2612
+ var t = e.wrapper.querySelector('[data-cmd="editSource"]');
2613
+ if (!t) return;
2614
+ var o = document.createElement("textarea");
2615
+ o.className = "te-source-textarea", o.spellcheck = !1, e.editor.parentNode.insertBefore(o, e.editor);
2616
+ var r = !1;
2617
+ function n(i) {
2618
+ if (!i) return "";
2619
+ var c = String(i), d = ["p", "h1", "h2", "h3", "h4", "h5", "h6", "blockquote", "pre", "li", "tr", "thead", "tbody", "tfoot", "table", "ul", "ol"];
2620
+ return d.forEach(function(p) {
2621
+ var s = new RegExp("<" + p + "(\\s[^>]*)?>", "gi"), u = new RegExp("</" + p + ">", "gi");
2622
+ c = c.replace(s, function(b) {
2623
+ return `
2624
+ ` + b;
2625
+ }), c = c.replace(u, function(b) {
2626
+ return b + `
2627
+ `;
2628
+ });
2629
+ }), c = c.replace(/\n{2,}/g, `
2630
+ `), c.trim();
2631
+ }
2632
+ function a() {
2633
+ if (r = !r, r)
2634
+ o.value = n(e.editor.innerHTML), e.editor.classList.add("te-source-mode"), o.style.display = "block", o.focus();
2635
+ else {
2636
+ var i = e.utils.sanitizeHTML ? e.utils.sanitizeHTML(o.value, e.options.sanitize || {}) : o.value;
2637
+ e.editor.innerHTML = i, e.editor.classList.remove("te-source-mode"), o.style.display = "none", e.editor.focus();
2638
+ }
2639
+ t.classList.toggle("active", r);
2640
+ for (var c = e.toolbar.querySelectorAll("[data-cmd], select, input"), d = 0; d < c.length; d++)
2641
+ c[d] !== t && (r ? (c[d].setAttribute("disabled", "disabled"), c[d].style.opacity = ".4", c[d].style.pointerEvents = "none") : (c[d].removeAttribute("disabled"), c[d].style.opacity = "", c[d].style.pointerEvents = ""));
2642
+ }
2643
+ t.addEventListener("click", a);
2644
+ }
2645
+ }, Bt = {
2646
+ name: "history",
2647
+ order: 70,
2648
+ toolbarHTML: '<button type="button" class="btn btn-sm btn-light" title="Undo" data-cmd="undo"><i class="ti ti-arrow-back-up"></i></button><button type="button" class="btn btn-sm btn-light" title="Redo" data-cmd="redo"><i class="ti ti-arrow-forward-up"></i></button><button type="button" class="btn btn-sm btn-light" title="Clear formatting" data-cmd="removeFormat"><i class="ti ti-trash"></i></button>',
2649
+ init(e) {
2650
+ }
2651
+ }, zt = {
2652
+ name: "fullscreen",
2653
+ order: 75,
2654
+ css: ".te-fullscreen { position: fixed; inset: 0; z-index: 9999;}.te-fullscreen .te-container { max-width: none; display: flex; flex-direction: column; height: 100%;}.te-fullscreen .te-container .te-editor { flex: 1; height: auto !important; min-height: 300px;}.te-fullscreen .te-container .te-toolbar { border-radius: 0;}.te-fullscreen .te-btn-fullscreen { background: #e7f1ff; border-color: #b6d4fe;}",
2655
+ toolbarHTML: '<button type="button" class="btn btn-sm btn-light te-btn-fullscreen" title="Fullscreen" data-cmd="fullscreen"><i class="ti ti-maximize"></i></button>',
2656
+ init(e) {
2657
+ if (e.features.fullscreen) {
2658
+ var t = e.wrapper.querySelector('[data-cmd="fullscreen"]');
2659
+ t && t.addEventListener("click", function() {
2660
+ var o = e.wrapper.classList.toggle("te-fullscreen");
2661
+ t.innerHTML = o ? '<i class="ti ti-minimize"></i>' : '<i class="ti ti-maximize"></i>', e.editor.focus();
2662
+ });
2663
+ }
2664
+ }
2665
+ }, It = {
2666
+ name: "toolbarCollapse",
2667
+ order: 1e3,
2668
+ css: ".te-toolbar .btn svg, .te-toolbar .btn i { width: 14px !important; height: 14px !important; vertical-align: middle;}",
2669
+ init(e) {
2670
+ }
2671
+ };
2672
+ var _t = "te-autosave-";
2673
+ function Dt(e) {
2674
+ var t = e.id || e.name || e.className || "";
2675
+ return _t + (t || Math.random().toString(36).slice(2, 8));
2676
+ }
2677
+ const Ot = {
2678
+ name: "autosave",
2679
+ order: 210,
2680
+ css: ".te-autosave-badge { font-size: .7rem; padding: 1px 6px; border-radius: 8px; line-height: 1.4; opacity: .6; margin-left: auto;}.te-autosave-badge.saved { background: #d1e7dd; color: #0f5132; }.te-autosave-badge.unsaved { background: #fff3cd; color: #664d03; }",
2681
+ init(e) {
2682
+ if (!e.features.autosave) return;
2683
+ var t = Dt(e.textarea);
2684
+ try {
2685
+ var o = localStorage.getItem(t);
2686
+ o && o !== e.editor.innerHTML && (e.editor.innerHTML = o);
2687
+ } catch {
2688
+ }
2689
+ var r = document.createElement("span");
2690
+ r.className = "te-autosave-badge saved", r.textContent = "Saved";
2691
+ var n = e.wrapper.querySelector(".te-status-right");
2692
+ n && (n.style.display = "inline-flex", n.style.alignItems = "center", n.style.gap = "8px", n.appendChild(r));
2693
+ function a(d) {
2694
+ r.textContent = d ? "Saved" : "Unsaved", r.className = "te-autosave-badge " + (d ? "saved" : "unsaved");
2695
+ }
2696
+ var i = null;
2697
+ function c() {
2698
+ a(!1), i && clearTimeout(i), i = setTimeout(function() {
2699
+ try {
2700
+ localStorage.setItem(t, e.editor.innerHTML), a(!0);
2701
+ } catch {
2702
+ }
2703
+ }, 500);
2704
+ }
2705
+ e.editor.addEventListener("input", c), e.editor.addEventListener("paste", c), e.editor.addEventListener("blur", function() {
2706
+ try {
2707
+ localStorage.removeItem(t);
2708
+ } catch {
2709
+ }
2710
+ });
2711
+ }
2712
+ };
2713
+ var ne = /(?:https?:\/\/|www\.)[^\s<>"'()]+(?:\.[^\s<>"'()]+)*/gi;
2714
+ const jt = {
2715
+ name: "autoLinkify",
2716
+ order: 1,
2717
+ init(e) {
2718
+ if (e.features.autoLinkify !== !1) {
2719
+ var t = e.editor;
2720
+ t.addEventListener("paste", function(o) {
2721
+ var r = o.clipboardData && o.clipboardData.getData("text/plain") || "";
2722
+ if (r && (r = r.trim(), ne.test(r))) {
2723
+ ne.lastIndex = 0;
2724
+ var n = r.match(ne)[0], a = n.indexOf("://") === -1 ? "https://" + n : n, i = e.utils.isSafeUrl ? e.utils.isSafeUrl(a, e.options.urlSchemes || ["http", "https", "mailto", "tel"]) : !0;
2725
+ if (i) {
2726
+ o.preventDefault(), o.stopImmediatePropagation();
2727
+ var c = '<p><a href="' + a.replace(/"/g, "&quot;") + '" target="_blank" rel="noopener noreferrer">' + n.replace(/</g, "&lt;").replace(/>/g, "&gt;") + "</a></p>";
2728
+ document.execCommand("insertHTML", !1, c);
2729
+ }
2730
+ }
2731
+ }, !0);
2732
+ }
2733
+ }
2734
+ }, Pt = {
2735
+ name: "caseTransform",
2736
+ order: 31,
2737
+ toolbarHTML: '<select class="te-case form-select form-select-sm" title="Change case"> <option value="">Case</option> <option value="upper">UPPERCASE</option> <option value="lower">lowercase</option> <option value="title">Title Case</option> <option value="sentence">Sentence case</option></select>',
2738
+ init(e) {
2739
+ if (e.features.caseTransform !== !1) {
2740
+ var t = e.wrapper.querySelector(".te-case");
2741
+ t && (t.addEventListener("mousedown", function() {
2742
+ e.saveSel();
2743
+ }), t.addEventListener("change", function() {
2744
+ var o = t.value;
2745
+ if (t.value = "", !!o) {
2746
+ e.restoreSel();
2747
+ var r = window.getSelection();
2748
+ if (!(!r || r.isCollapsed || !r.rangeCount)) {
2749
+ var n = r.toString();
2750
+ if (n) {
2751
+ var a;
2752
+ switch (o) {
2753
+ case "upper":
2754
+ a = n.toUpperCase();
2755
+ break;
2756
+ case "lower":
2757
+ a = n.toLowerCase();
2758
+ break;
2759
+ case "title":
2760
+ a = n.toLowerCase().replace(/\b\w/g, function(i) {
2761
+ return i.toUpperCase();
2762
+ });
2763
+ break;
2764
+ case "sentence":
2765
+ a = n.charAt(0).toUpperCase() + n.slice(1).toLowerCase().replace(/([.!?]\s+)(\w)/g, function(i) {
2766
+ return i.toUpperCase();
2767
+ });
2768
+ break;
2769
+ default:
2770
+ return;
2771
+ }
2772
+ document.execCommand("insertText", !1, a), e.editor.focus();
2773
+ }
2774
+ }
2775
+ }
2776
+ }));
2777
+ }
2778
+ }
2779
+ }, Ut = {
2780
+ name: "shortcutsHelp",
2781
+ order: 90,
2782
+ css: ".te-shortcuts-table { width: 100%; border-collapse: collapse; font-size: .875rem; }.te-shortcuts-table th, .te-shortcuts-table td { padding: .4rem .75rem; border-bottom: 1px solid #e9ecef; text-align: left; color: #000; }.te-shortcuts-table th { background: #f8f9fa; font-weight: 600; }.te-shortcuts-table kbd { display: inline-block; padding: 2px 6px; font-size: .75rem; font-family: monospace; background: #f0f0f0; border: 1px solid #d0d0d0; border-radius: 3px; color: #000; }",
2783
+ toolbarHTML: '<button type="button" class="btn btn-sm btn-light" title="Keyboard shortcuts" data-cmd="shortcutsHelp"><i class="ti ti-help-circle"></i></button>',
2784
+ modalHTML: '<div class="te-shortcuts-modal te-modal" aria-hidden="true"> <div class="te-modal-backdrop" data-te-close></div> <div class="te-modal-dialog"> <div class="te-modal-header"> <h5 class="te-modal-title m-0">Keyboard Shortcuts</h5> <button type="button" class="btn-close" data-te-close aria-label="Close"></button> </div> <div class="te-modal-body"> <table class="te-shortcuts-table"> <thead><tr><th>Shortcut</th><th>Action</th></tr></thead> <tbody> <tr><td><kbd>Ctrl</kbd> + <kbd>B</kbd></td><td>Bold</td></tr> <tr><td><kbd>Ctrl</kbd> + <kbd>I</kbd></td><td>Italic</td></tr> <tr><td><kbd>Ctrl</kbd> + <kbd>U</kbd></td><td>Underline</td></tr> <tr><td><kbd>Ctrl</kbd> + <kbd>S</kbd></td><td>Strikethrough</td></tr> <tr><td><kbd>Ctrl</kbd> + <kbd>Z</kbd></td><td>Undo</td></tr> <tr><td><kbd>Ctrl</kbd> + <kbd>Shift</kbd> + <kbd>Z</kbd></td><td>Redo</td></tr> <tr><td><kbd>Ctrl</kbd> + <kbd>Y</kbd></td><td>Redo</td></tr> <tr><td><kbd>Ctrl</kbd> + <kbd>K</kbd></td><td>Insert link</td></tr> <tr><td><kbd>Tab</kbd></td><td>Indent list item</td></tr> <tr><td><kbd>Shift</kbd> + <kbd>Tab</kbd></td><td>Outdent list item</td></tr> </tbody> </table> </div> </div></div>',
2785
+ init(e) {
2786
+ if (e.features.shortcutsHelp !== !1) {
2787
+ var t = e.wrapper.querySelector('[data-cmd="shortcutsHelp"]');
2788
+ t && t.addEventListener("click", function() {
2789
+ var o = e.wrapper.querySelector(".te-shortcuts-modal");
2790
+ o && o.classList.add("is-open");
2791
+ });
2792
+ }
2793
+ }
2794
+ }, Ft = {
2795
+ name: "floatingToolbar",
2796
+ order: 58,
2797
+ css: ".te-float-toolbar { position: fixed; display: none; z-index: 3100; background: #fff; border: 1px solid #dee2e6; border-radius: .375rem; box-shadow: 0 6px 20px rgba(0,0,0,.15); padding: .2rem; gap: 2px; align-items: center; white-space: nowrap;}.te-float-toolbar .btn { padding: .2rem .4rem !important; font-size: .75rem !important; line-height: 1 !important;}.te-float-toolbar .btn i,.te-float-toolbar .btn svg { width: 13px !important; height: 13px !important; pointer-events: none;}.te-float-link-input { position: fixed; display: none; z-index: 3101; background: #fff; border: 1px solid #dee2e6; border-radius: .375rem; box-shadow: 0 6px 20px rgba(0,0,0,.15); padding: .35rem; gap: .25rem; align-items: center; white-space: nowrap;}.te-float-link-input input { width: 220px; padding: .2rem .4rem; font-size: .8rem; border: 1px solid #dee2e6; border-radius: .25rem; outline: none;}.te-float-link-input input:focus { border-color: #86b7fe; box-shadow: 0 0 0 2px rgba(13,110,253,.15);}.te-float-link-input .btn { padding: .2rem .5rem !important; font-size: .75rem !important; line-height: 1 !important;}",
2798
+ init(e) {
2799
+ if (!e.features.floatingToolbar) return;
2800
+ var t = e.editor, o = document.createElement("div");
2801
+ o.className = "te-float-toolbar", o.innerHTML = '<button type="button" class="btn btn-sm btn-light" data-te-float="bold" title="Bold"><i class="ti ti-bold"></i></button><button type="button" class="btn btn-sm btn-light" data-te-float="italic" title="Italic"><i class="ti ti-italic"></i></button><button type="button" class="btn btn-sm btn-light" data-te-float="underline" title="Underline"><i class="ti ti-underline"></i></button><span class="te-divider-v" style="display:inline-block;width:1px;height:14px;background:#dee2e6;margin:0 2px;vertical-align:middle"></span><button type="button" class="btn btn-sm btn-light te-float-fore" title="Text color" style="position:relative;padding:.15rem .35rem!important;min-width:22px;text-align:center"><span class="te-float-cp" style="display:block;font-size:.8rem;line-height:1">A<span style="display:block;height:2px;border-radius:1px;margin-top:1px;background:#000"></span></span><input type="color" class="te-float-fore-input" value="#000000" style="position:absolute;top:0;left:0;width:100%;height:100%;opacity:0;cursor:pointer;border:none;padding:0"></button><button type="button" class="btn btn-sm btn-light te-float-back" title="Background color" style="position:relative;padding:.15rem .35rem!important;min-width:22px;text-align:center"><span class="te-float-cp" style="display:block;font-size:.8rem;line-height:1">A<span style="display:block;height:2px;border-radius:1px;margin-top:1px;background:#ffff00"></span></span><input type="color" class="te-float-back-input" value="#ffff00" style="position:absolute;top:0;left:0;width:100%;height:100%;opacity:0;cursor:pointer;border:none;padding:0"></button><span class="te-divider-v" style="display:inline-block;width:1px;height:14px;background:#dee2e6;margin:0 2px;vertical-align:middle"></span><button type="button" class="btn btn-sm btn-light" data-te-float="link" title="Insert link"><i class="ti ti-link"></i></button><span class="te-divider-v" style="display:inline-block;width:1px;height:14px;background:#dee2e6;margin:0 2px;vertical-align:middle"></span><button type="button" class="btn btn-sm btn-light" data-te-float="removeFormat" title="Clear formatting"><i class="ti ti-clear-formatting"></i></button>', document.body.appendChild(o);
2802
+ var r = document.createElement("div");
2803
+ r.className = "te-float-link-input", r.innerHTML = '<input type="url" class="te-float-link-url" placeholder="https://example.com" /><button type="button" class="btn btn-sm btn-primary" data-te-float-link="apply">Apply</button><button type="button" class="btn btn-sm btn-light" data-te-float-link="cancel">Cancel</button>', document.body.appendChild(r);
2804
+ var n = o.querySelector(".te-float-fore-input"), a = o.querySelector(".te-float-back-input");
2805
+ n && n.addEventListener("change", function() {
2806
+ t.focus(), s(), document.execCommand("foreColor", !1, n.value);
2807
+ var x = o.querySelector(".te-float-fore .te-float-cp");
2808
+ x && (x.style.color = n.value), b();
2809
+ }), a && a.addEventListener("change", function() {
2810
+ t.focus(), s();
2811
+ try {
2812
+ document.execCommand("hiliteColor", !1, a.value);
2813
+ } catch {
2814
+ document.execCommand("backColor", !1, a.value);
2815
+ }
2816
+ var x = o.querySelector(".te-float-back .te-float-cp span:last-child");
2817
+ x && (x.style.background = a.value), b();
2818
+ });
2819
+ var i = null, c = !1, d = null;
2820
+ function p() {
2821
+ var x = window.getSelection();
2822
+ x && x.rangeCount > 0 ? d = x.getRangeAt(0).cloneRange() : d = null;
2823
+ }
2824
+ function s() {
2825
+ if (d) {
2826
+ var x = window.getSelection();
2827
+ x.removeAllRanges(), x.addRange(d);
2828
+ }
2829
+ }
2830
+ function u(x, m, v) {
2831
+ var l = o.offsetWidth || 100, f = o.offsetHeight || 30, S = t.getBoundingClientRect(), E = x - l / 2;
2832
+ E < S.left && (E = S.left), E + l > S.right && (E = S.right - l);
2833
+ var q = v ? v.top - S.top : m - S.top, H = v ? S.bottom - v.bottom : S.bottom - m, B;
2834
+ q >= f + 8 ? B = (v ? v.top : m) - f - 8 : H >= f + 8 ? B = (v ? v.bottom : m) + 8 : B = q > H ? S.top + 2 : S.bottom - f - 2, o.style.left = E + "px", o.style.top = B + "px";
2835
+ }
2836
+ function b() {
2837
+ c = !1, r.style.display = "none", o.style.display = "none";
2838
+ }
2839
+ function k(x, m, v) {
2840
+ c = !0, o.style.display = "flex", u(x, m, v), p();
2841
+ }
2842
+ function T() {
2843
+ p();
2844
+ var x = t.getBoundingClientRect(), m = o.getBoundingClientRect();
2845
+ r.style.display = "flex", r.style.visibility = "hidden";
2846
+ var v = r.offsetWidth || 320, l = r.offsetHeight || 32, f = m.left + m.width / 2 - v / 2;
2847
+ f < x.left && (f = x.left), f + v > x.right && (f = x.right - v), r.style.left = f + "px";
2848
+ var S = window.innerHeight - m.bottom;
2849
+ r.style.top = (S >= l + 4 ? m.bottom + 4 : m.top - l - 4) + "px", r.style.visibility = "", r.querySelector(".te-float-link-url").value = "", r.querySelector(".te-float-link-url").focus();
2850
+ }
2851
+ t.addEventListener("mouseup", function(x) {
2852
+ if (t.contentEditable === "true") {
2853
+ i && clearTimeout(i);
2854
+ var m = window.getSelection();
2855
+ if (!m || m.isCollapsed || !m.toString().trim()) {
2856
+ b();
2857
+ return;
2858
+ }
2859
+ if (!t.contains(m.anchorNode) || !t.contains(m.focusNode)) {
2860
+ b();
2861
+ return;
2862
+ }
2863
+ var v = m.getRangeAt(0), l = v.getBoundingClientRect(), f = l.left + l.width / 2;
2864
+ k(f, 0, l);
2865
+ }
2866
+ }), t.addEventListener("mousedown", function() {
2867
+ i && clearTimeout(i), i = setTimeout(function() {
2868
+ b();
2869
+ }, 200);
2870
+ }), t.addEventListener("keydown", function() {
2871
+ b();
2872
+ }), t.addEventListener("scroll", function() {
2873
+ c && b();
2874
+ }), o.addEventListener("mousedown", function(x) {
2875
+ x.preventDefault();
2876
+ var m = x.target.closest("[data-te-float]");
2877
+ if (m) {
2878
+ var v = m.getAttribute("data-te-float");
2879
+ if (v) {
2880
+ if (v === "link") {
2881
+ T();
2882
+ return;
2883
+ }
2884
+ t.focus();
2885
+ var l = window.getSelection();
2886
+ !l || l.rangeCount === 0 || (document.execCommand(v, !1, void 0), b());
2887
+ }
2888
+ }
2889
+ }), r.addEventListener("mousedown", function(x) {
2890
+ x.preventDefault();
2891
+ var m = x.target.closest("[data-te-float-link]");
2892
+ if (m) {
2893
+ var v = m.getAttribute("data-te-float-link");
2894
+ if (v === "cancel") {
2895
+ b();
2896
+ return;
2897
+ }
2898
+ if (v === "apply") {
2899
+ var l = r.querySelector(".te-float-link-url").value.trim();
2900
+ if (!l) return;
2901
+ t.focus(), s(), !/^https?:\/\//i.test(l) && !/^mailto:/i.test(l) && !/^tel:/i.test(l) && (l = "https://" + l), document.execCommand("createLink", !1, l), b();
2902
+ }
2903
+ }
2904
+ }), r.addEventListener("keydown", function(x) {
2905
+ if (x.key === "Enter") {
2906
+ x.preventDefault();
2907
+ var m = r.querySelector(".te-float-link-url").value.trim();
2908
+ if (!m) return;
2909
+ t.focus(), s(), !/^https?:\/\//i.test(m) && !/^mailto:/i.test(m) && !/^tel:/i.test(m) && (m = "https://" + m), document.execCommand("createLink", !1, m), b();
2910
+ }
2911
+ x.key === "Escape" && b();
2912
+ }), document.addEventListener("mousedown", function(x) {
2913
+ c && !o.contains(x.target) && !r.contains(x.target) && x.target !== t && !t.contains(x.target) && b();
2914
+ });
2915
+ }
2916
+ }, Wt = {
2917
+ name: "darkMode",
2918
+ order: 59,
2919
+ toolbarHTML: '<button type="button" class="btn btn-sm btn-light" title="Toggle dark mode" data-cmd="toggleDark"><i class="ti ti-moon"></i></button>',
2920
+ css: ".te-container.te-dark { color-scheme: dark;}.te-container.te-dark .te-toolbar { background: #1e1e1e; border-color: #444;}.te-container.te-dark .te-toolbar .btn { color: #ccc; border-color: #555; background: #2a2a2a;}.te-container.te-dark .te-toolbar .btn:hover { background: #333; color: #fff;}.te-container.te-dark .te-toolbar .btn.active { background: #0d6efd; color: #fff; border-color: #0d6efd;}.te-container.te-dark .te-editor { background: #121212; border-color: #444; color: #e0e0e0;}.te-container.te-dark .te-editor:focus { box-shadow: inset 0 0 0 2px rgba(13,110,253,.5);}.te-container.te-dark .te-editor[placeholder]:empty:before { color: #666;}.te-container.te-dark .te-divider { background: #444;}.te-container.te-dark .te-status { color: #999;}.te-container.te-dark .te-modal-dialog { background: #1e1e1e; color: #e0e0e0; box-shadow: 0 20px 60px rgba(0,0,0,.5);}.te-container.te-dark .te-modal-header,.te-container.te-dark .te-modal-footer { background: #2a2a2a; border-color: #444;}.te-container.te-dark .te-modal-header .te-modal-title { color: #e0e0e0;}.te-container.te-dark .te-modal-body { color: #e0e0e0;}.te-container.te-dark .btn-close { filter: invert(1);}.te-container.te-dark .te-modal .btn-primary { background: #555; border-color: #555; color: #fff;}.te-container.te-dark .te-modal .btn-primary:hover { background: #777; border-color: #777;}.te-container.te-dark .te-modal .btn-outline-secondary { color: #ccc; border-color: #555;}.te-container.te-dark .te-modal .btn-outline-secondary:hover { background: #333; border-color: #777;}.te-container.te-dark .te-modal .btn-outline-danger { color: #e57373; border-color: #e57373;}.te-container.te-dark .te-modal .btn-outline-danger:hover { background: #C1272D; border-color: #C1272D; color: #fff;}.te-container.te-dark .form-control { background: #2a2a2a; border-color: #555; color: #e0e0e0;}.te-container.te-dark .form-select { background: #2a2a2a; border-color: #555; color: #e0e0e0;}.te-container.te-dark .te-table-tools { background: #1e1e1e; border-color: #444;}.te-container.te-dark .te-table-tools .btn { color: #ccc; border-color: #555; background: #2a2a2a;}.te-container.te-dark .te-table-tools .tt-label { color: #999;}.te-container.te-dark .te-image-tools { background: #1e1e1e; border-color: #444;}.te-container.te-dark .te-image-tools .btn { color: #ccc; border-color: #555; background: #2a2a2a;}.te-container.te-dark .te-float-toolbar { background: #1e1e1e; border-color: #444;}.te-container.te-dark .te-float-toolbar .btn { color: #ccc; border-color: #555; background: #2a2a2a;}.te-container.te-dark .te-hr-popup { background: #1e1e1e; border-color: #444;}.te-container.te-dark .te-hr-popup .btn { color: #ccc; border-color: #555; background: #2a2a2a;}",
2921
+ init(e) {
2922
+ if (e.features.darkMode) {
2923
+ var t = e.wrapper.querySelector('[data-cmd="toggleDark"]');
2924
+ t && t.addEventListener("click", function() {
2925
+ var o = e.wrapper.querySelector(".te-container");
2926
+ if (o) {
2927
+ var r = o.classList.toggle("te-dark"), n = t.querySelector(".ti");
2928
+ n && (n.className = "ti " + (r ? "ti-sun" : "ti-moon")), t.classList.toggle("active", r);
2929
+ }
2930
+ });
2931
+ }
2932
+ }
2933
+ };
2934
+ var Te = "te-shortcut-map", ae = {
2935
+ Bold: { key: "b", ctrl: !0, shift: !1 },
2936
+ Italic: { key: "i", ctrl: !0, shift: !1 },
2937
+ Underline: { key: "u", ctrl: !0, shift: !1 },
2938
+ Strike: { key: "s", ctrl: !0, shift: !1 },
2939
+ Undo: { key: "z", ctrl: !0, shift: !1 },
2940
+ Redo: { key: "z", ctrl: !0, shift: !0 },
2941
+ RedoAlt: { key: "y", ctrl: !0, shift: !1 },
2942
+ Link: { key: "k", ctrl: !0, shift: !1 }
2943
+ };
2944
+ function Jt() {
2945
+ try {
2946
+ var e = localStorage.getItem(Te);
2947
+ if (e) return JSON.parse(e);
2948
+ } catch {
2949
+ }
2950
+ return JSON.parse(JSON.stringify(ae));
2951
+ }
2952
+ function Se(e) {
2953
+ try {
2954
+ localStorage.setItem(Te, JSON.stringify(e));
2955
+ } catch {
2956
+ }
2957
+ }
2958
+ function Le(e) {
2959
+ return String(e).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
2960
+ }
2961
+ const Xt = {
2962
+ name: "shortcutCustomizer",
2963
+ order: 6,
2964
+ toolbarHTML: '<button type="button" class="btn btn-sm btn-light" title="Customize shortcuts" data-cmd="customizeShortcuts"><i class="ti ti-edit"></i></button>',
2965
+ modalHTML: '<div class="te-modal" data-te-modal="shortcutCustomizer"> <div class="te-modal-backdrop" data-te-close></div> <div class="te-modal-dialog" style="width:420px"> <div class="te-modal-header"><strong>Customize Shortcuts</strong><button type="button" class="btn-close" data-te-close></button></div> <div class="te-modal-body te-shortcut-body"></div> <div class="te-modal-footer"> <button type="button" class="btn btn-sm btn-secondary" data-te-sc-reset>Reset</button> <button type="button" class="btn btn-sm btn-secondary" data-te-close>Close</button> <button type="button" class="btn btn-sm btn-primary" data-te-shortcut-save>Save</button> </div> </div></div>',
2966
+ css: '.te-shortcut-body table { width: 100%; border-collapse: collapse; }.te-shortcut-body td, .te-shortcut-body th { padding: 4px 8px; border-bottom: 1px solid #dee2e6; text-align: left; font-size: .85rem; }.te-shortcut-body th { font-weight: 600; color: #495057; }.te-shortcut-body input[type="text"] { width: 40px; padding: 2px 6px; border: 1px solid #dee2e6; border-radius: 3px; font-size: .85rem; }.te-shortcut-body input[type="text"]:focus { outline: none; border-color: #86b7fe; box-shadow: 0 0 0 2px rgba(13,110,253,.25); }.te-shortcut-body label { font-size: .8rem; margin-left: 4px; }',
2967
+ init(e) {
2968
+ if (e.features.shortcutCustomizer) {
2969
+ var t = e.wrapper.querySelector('[data-cmd="customizeShortcuts"]');
2970
+ t && (t.addEventListener("click", function() {
2971
+ var o = e.wrapper.querySelector('[data-te-modal="shortcutCustomizer"]');
2972
+ if (o) {
2973
+ var r = o.querySelector(".te-shortcut-body");
2974
+ if (r) {
2975
+ for (var n = Jt(), a = ["Bold", "Italic", "Underline", "Strike", "Undo", "Redo", "RedoAlt", "Link"], i = "<table><tr><th>Action</th><th>Shortcut</th></tr>", c = 0; c < a.length; c++) {
2976
+ var d = a[c], p = n[d] || { key: "", ctrl: !0, shift: !1 }, s = d === "RedoAlt" ? "Redo (alt)" : d;
2977
+ i += "<tr><td>" + s + '</td><td>Ctrl <input type="checkbox" data-ctrl="' + d + '" ' + (p.ctrl ? "checked" : "") + ' /> Shift <input type="checkbox" data-shift="' + d + '" ' + (p.shift ? "checked" : "") + ' /> <input type="text" class="te-sc-input" data-action="' + d + '" value="' + Le(p.key) + '" placeholder="key" maxlength="1" /></td></tr>';
2978
+ }
2979
+ i += "</table>", r.innerHTML = i, o.classList.add("is-open");
2980
+ }
2981
+ }
2982
+ }), e.wrapper.addEventListener("click", function(o) {
2983
+ var r = o.target.closest("[data-te-shortcut-save]");
2984
+ if (r) {
2985
+ var n = e.wrapper.querySelector('[data-te-modal="shortcutCustomizer"]');
2986
+ if (n) {
2987
+ var a = {};
2988
+ n.querySelectorAll(".te-sc-input").forEach(function(i) {
2989
+ var c = i.getAttribute("data-action"), d = i.value.trim().toLowerCase(), p = n.querySelector('[data-ctrl="' + c + '"]').checked, s = n.querySelector('[data-shift="' + c + '"]').checked;
2990
+ d && (a[c] = { key: d, ctrl: p, shift: s });
2991
+ }), Se(a), n.classList.remove("is-open");
2992
+ }
2993
+ }
2994
+ }), e.wrapper.addEventListener("click", function(o) {
2995
+ var r = o.target.closest("[data-te-sc-reset]");
2996
+ if (r) {
2997
+ var n = e.wrapper.querySelector('[data-te-modal="shortcutCustomizer"]');
2998
+ if (n) {
2999
+ Se(JSON.parse(JSON.stringify(ae)));
3000
+ for (var a = n.querySelector(".te-shortcut-body"), i = ["Bold", "Italic", "Underline", "Strike", "Undo", "Redo", "RedoAlt", "Link"], c = "<table><tr><th>Action</th><th>Shortcut</th></tr>", d = 0; d < i.length; d++) {
3001
+ var p = i[d], s = ae[p], u = p === "RedoAlt" ? "Redo (alt)" : p;
3002
+ c += "<tr><td>" + u + '</td><td>Ctrl <input type="checkbox" data-ctrl="' + p + '" ' + (s.ctrl ? "checked" : "") + ' /> Shift <input type="checkbox" data-shift="' + p + '" ' + (s.shift ? "checked" : "") + ' /> <input type="text" class="te-sc-input" data-action="' + p + '" value="' + Le(s.key) + '" placeholder="key" maxlength="1" /></td></tr>';
3003
+ }
3004
+ c += "</table>", a && (a.innerHTML = c);
3005
+ }
3006
+ }
3007
+ }));
3008
+ }
3009
+ }
3010
+ };
3011
+ function Kt(e) {
3012
+ e.register("block", Oe), e.register("inline", je), e.register("pre", Pe), e.register("inlineCode", Ue), e.register("subSuper", Fe), e.register("keyboardShortcuts", Ke), e.register("readOnly", $e), e.register("linkTooltip", Ye), e.register("emojiAutocomplete", Ze), e.register("statusBar", Qe), e.register("codeBlock", tt), e.register("mediaEmbed", rt), e.register("dragDrop", ot), e.register("pastePlain", nt), e.register("findReplace", at), e.register("indent", it), e.register("list", st), e.register("lineHeight", dt), e.register("fontSize", ut), e.register("fontFamily", ft), e.register("specialChars", mt), e.register("colors", gt), e.register("tableBg", vt), e.register("align", ht), e.register("markdown", yt), e.register("link", wt), e.register("image", kt), e.register("imageProps", St), e.register("imageTools", Lt), e.register("iframe", xt), e.register("table", Et), e.register("tableTools", Tt), e.register("hr", At), e.register("unlink", qt), e.register("emoji", Mt), e.register("direction", Rt), e.register("source", Nt), e.register("history", Bt), e.register("fullscreen", zt), e.register("toolbarCollapse", It), e.register("autosave", Ot), e.register("autoLinkify", jt), e.register("caseTransform", Pt), e.register("shortcutsHelp", Ut), e.register("floatingToolbar", Ft), e.register("darkMode", Wt), e.register("shortcutCustomizer", Xt);
3013
+ }
3014
+ const le = new xe();
3015
+ Kt(le);
3016
+ le.injectAllCSS();
3017
+ (function() {
3018
+ if (typeof document > "u" || document.querySelector('link[href*="tabler-icons"]')) return;
3019
+ const t = document.createElement("link");
3020
+ t.rel = "stylesheet", t.href = "https://cdn.jsdelivr.net/npm/@tabler/icons-webfont@3/dist/tabler-icons.min.css", document.head.appendChild(t);
3021
+ })();
3022
+ const Q = {
3023
+ pluginManager: le,
3024
+ instances: [],
3025
+ onBrowseImage: null,
3026
+ onUploadImage: null,
3027
+ setBrowseImage(e) {
3028
+ this.onBrowseImage = e;
3029
+ },
3030
+ attach(e, t) {
3031
+ const o = typeof e == "string" ? document.querySelector(e) : e;
3032
+ if (!o || String(o.tagName).toUpperCase() !== "TEXTAREA" && !(o.matches && o.matches("textarea[data-tulih-editor]"))) return;
3033
+ const r = o.nextElementSibling;
3034
+ if (!(r && r.querySelector && r.querySelector(".te-editor")))
3035
+ return new Ee(o, t, Q);
3036
+ },
3037
+ create(e, t) {
3038
+ return this.attach(e, t);
3039
+ }
3040
+ };
3041
+ typeof document < "u" && document.addEventListener("DOMContentLoaded", () => {
3042
+ document.querySelectorAll("textarea[data-tulih-editor]").forEach((t) => {
3043
+ Q.attach(t);
3044
+ });
3045
+ });
3046
+ Q.Editor = Ee;
3047
+ Q.PluginManager = xe;
3048
+ export {
3049
+ Q as default
3050
+ };
3051
+ //# sourceMappingURL=tulih-editor.es.js.map