From 0688362cc018e836b8eafbf461993eecbf065c2a Mon Sep 17 00:00:00 2001 From: fantasticit Date: Wed, 11 May 2022 14:05:11 +0800 Subject: [PATCH] tiptap: add drawio flow support --- .eslintignore | 1 + packages/client/global.d.ts | 5 + packages/client/next.config.js | 1 + packages/client/package.json | 1 + packages/client/public/drawio.embed.js | 35878 ++++++++++++++++ .../client/src/components/icons/IconFlow.tsx | 17 + .../client/src/components/icons/index.tsx | 3 +- packages/client/src/pages/_app.tsx | 1 + .../client/src/tiptap/core/extensions/flow.ts | 106 + .../client/src/tiptap/core/styles/node.scss | 1 + .../src/tiptap/core/styles/selection.scss | 1 + .../src/tiptap/core/wrappers/flow/decode.ts | 75 + .../core/wrappers/flow/index.module.scss | 31 + .../src/tiptap/core/wrappers/flow/index.tsx | 120 + .../collaboration/collaboration/menubar.tsx | 2 + .../src/tiptap/editor/collaboration/kit.ts | 2 + .../client/src/tiptap/editor/menus/_event.ts | 6 + .../src/tiptap/editor/menus/flow/bubble.tsx | 47 + .../src/tiptap/editor/menus/flow/index.tsx | 13 + .../src/tiptap/editor/menus/flow/modal.tsx | 63 + .../src/tiptap/editor/menus/insert/index.tsx | 8 + .../src/tiptap/editor/menus/quick-insert.tsx | 12 + .../src/tiptap/editor/menus/text/index.tsx | 2 + packages/config/yaml/dev.yaml | 1 + pnpm-lock.yaml | 6 + 25 files changed, 36401 insertions(+), 2 deletions(-) create mode 100644 packages/client/public/drawio.embed.js create mode 100644 packages/client/src/components/icons/IconFlow.tsx create mode 100644 packages/client/src/tiptap/core/extensions/flow.ts create mode 100644 packages/client/src/tiptap/core/wrappers/flow/decode.ts create mode 100644 packages/client/src/tiptap/core/wrappers/flow/index.module.scss create mode 100644 packages/client/src/tiptap/core/wrappers/flow/index.tsx create mode 100644 packages/client/src/tiptap/editor/menus/flow/bubble.tsx create mode 100644 packages/client/src/tiptap/editor/menus/flow/index.tsx create mode 100644 packages/client/src/tiptap/editor/menus/flow/modal.tsx diff --git a/.eslintignore b/.eslintignore index 6b0e422c..eabd6182 100644 --- a/.eslintignore +++ b/.eslintignore @@ -4,3 +4,4 @@ node_modules **/dist/** .eslintrc.js ./packages/client/src/tiptap/wrappers/mind/mind-elixir/iconfont/iconfont.js +./packages/client/public/drawio.embed.js diff --git a/packages/client/global.d.ts b/packages/client/global.d.ts index 820cc6e9..7e89cbc9 100644 --- a/packages/client/global.d.ts +++ b/packages/client/global.d.ts @@ -1,3 +1,8 @@ interface Window { + // 思维导图 MindElixir: any; + // drawio 绘图 + mxGraph: any; + mxUtils: any; + mxCodec: any; } diff --git a/packages/client/next.config.js b/packages/client/next.config.js index 8609c764..a38d0f6c 100644 --- a/packages/client/next.config.js +++ b/packages/client/next.config.js @@ -11,6 +11,7 @@ const nextConfig = semi({ SERVER_API_URL: config.client.apiUrl, COLLABORATION_API_URL: config.client.collaborationUrl, ENABLE_ALIYUN_OSS: !!config.oss.aliyun.accessKeyId, + DRAWIO_URL: config.client.drawioUrl || 'https://embed.diagrams.net', }, webpack: (config, { dev, isServer }) => { config.resolve.plugins.push(new TsconfigPathsPlugin()); diff --git a/packages/client/package.json b/packages/client/package.json index bfe92824..311d1f84 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -70,6 +70,7 @@ "markdown-it-sub": "^1.0.0", "markdown-it-sup": "^1.0.0", "next": "12.0.10", + "pako": "^2.0.4", "prosemirror-markdown": "^1.7.0", "prosemirror-tables": "^1.1.1", "prosemirror-utils": "^0.9.6", diff --git a/packages/client/public/drawio.embed.js b/packages/client/public/drawio.embed.js new file mode 100644 index 00000000..6be63e96 --- /dev/null +++ b/packages/client/public/drawio.embed.js @@ -0,0 +1,35878 @@ +/* eslint-disable */ +/* + @license DOMPurify 2.3.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.3.6/LICENSE */ +!(function (a, b) { + 'object' == typeof exports && 'undefined' != typeof module + ? (module.exports = b()) + : 'function' == typeof define && define.amd + ? define(b) + : ((a = 'undefined' != typeof globalThis ? globalThis : a || self).DOMPurify = b()); +})(this, function () { + function a(b) { + return (a = + 'function' == typeof Symbol && 'symbol' == typeof Symbol.iterator + ? function (a) { + return typeof a; + } + : function (a) { + return a && 'function' == typeof Symbol && a.constructor === Symbol && a !== Symbol.prototype + ? 'symbol' + : typeof a; + })(b); + } + function b(a, c) { + return (b = + Object.setPrototypeOf || + function (a, b) { + return (a.__proto__ = b), a; + })(a, c); + } + function c() { + if ('undefined' == typeof Reflect || !Reflect.construct || Reflect.construct.sham) return !1; + if ('function' == typeof Proxy) return !0; + try { + return Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})), !0; + } catch (Ca) { + return !1; + } + } + function d(a, e, f) { + return (d = c() + ? Reflect.construct + : function (a, c, d) { + var e = [null]; + e.push.apply(e, c); + a = new (Function.bind.apply(a, e))(); + return d && b(a, d.prototype), a; + }).apply(null, arguments); + } + function e(a) { + var b; + (b = (function (a) { + if (Array.isArray(a)) return f(a); + })(a)) || + (b = + ('undefined' != typeof Symbol && null != a[Symbol.iterator]) || null != a['@@iterator'] + ? Array.from(a) + : void 0); + if ( + !(a = + b || + (function (a, b) { + if (a) { + if ('string' == typeof a) return f(a, b); + var c = Object.prototype.toString.call(a).slice(8, -1); + 'Object' === c && a.constructor && (c = a.constructor.name); + if ('Map' === c || 'Set' === c) return Array.from(a); + if ('Arguments' === c || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(c)) return f(a, b); + } + })(a)) + ) + throw new TypeError( + 'Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.' + ); + return a; + } + function f(a, b) { + (null == b || b > a.length) && (b = a.length); + for (var c = 0, d = Array(b); c < b; c++) d[c] = a[c]; + return d; + } + function g(a) { + return function (b) { + for (var c = arguments.length, d = Array(1 < c ? c - 1 : 0), e = 1; e < c; e++) d[e - 1] = arguments[e]; + return B(a, b, d); + }; + } + function k(a, b) { + n && n(a, null); + for (var c = b.length; c--; ) { + var d = b[c]; + if ('string' == typeof d) { + var e = T(d); + e !== d && (p(b) || (b[c] = e), (d = e)); + } + a[d] = !0; + } + return a; + } + function h(a) { + var b, + c = z(null); + for (b in a) B(m, a, [b]) && (c[b] = a[b]); + return c; + } + function l(a, b) { + for (; null !== a; ) { + var c = t(a, b); + if (c) { + if (c.get) return g(c.get); + if ('function' == typeof c.value) return g(c.value); + } + a = r(a); + } + return function (a) { + return console.warn('fallback value for', a), null; + }; + } + var m = Object.hasOwnProperty, + n = Object.setPrototypeOf, + p = Object.isFrozen, + r = Object.getPrototypeOf, + t = Object.getOwnPropertyDescriptor, + u = Object.freeze, + x = Object.seal, + z = Object.create, + D = 'undefined' != typeof Reflect && Reflect, + B = D.apply, + C = D.construct; + B || + (B = function (a, b, c) { + return a.apply(b, c); + }); + u || + (u = function (a) { + return a; + }); + x || + (x = function (a) { + return a; + }); + C || + (C = function (a, b) { + return d(a, e(b)); + }); + var J, + v = g(Array.prototype.forEach), + K = g(Array.prototype.pop), + O = g(Array.prototype.push), + T = g(String.prototype.toLowerCase), + M = g(String.prototype.match), + U = g(String.prototype.replace), + da = g(String.prototype.indexOf), + ha = g(String.prototype.trim), + Y = g(RegExp.prototype.test), + P = + ((J = TypeError), + function () { + for (var a = arguments.length, b = Array(a), c = 0; c < a; c++) b[c] = arguments[c]; + return C(J, b); + }), + Oa = u( + 'a abbr acronym address area article aside audio b bdi bdo big blink blockquote body br button canvas caption center cite code col colgroup content data datalist dd decorator del details dfn dialog dir div dl dt element em fieldset figcaption figure font footer form h1 h2 h3 h4 h5 h6 head header hgroup hr html i img input ins kbd label legend li main map mark marquee menu menuitem meter nav nobr ol optgroup option output p picture pre progress q rp rt ruby s samp section select shadow small source spacer span strike strong style sub summary sup table tbody td template textarea tfoot th thead time tr track tt u ul var video wbr'.split( + ' ' + ) + ), + Da = u( + 'svg a altglyph altglyphdef altglyphitem animatecolor animatemotion animatetransform circle clippath defs desc ellipse filter font g glyph glyphref hkern image line lineargradient marker mask metadata mpath path pattern polygon polyline radialgradient rect stop style switch symbol text textpath title tref tspan view vkern'.split( + ' ' + ) + ), + Pa = u( + 'feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap feDistantLight feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur feImage feMerge feMergeNode feMorphology feOffset fePointLight feSpecularLighting feSpotLight feTile feTurbulence'.split( + ' ' + ) + ), + Wa = u( + 'animate color-profile cursor discard fedropshadow font-face font-face-format font-face-name font-face-src font-face-uri foreignobject hatch hatchpath mesh meshgradient meshpatch meshrow missing-glyph script set solidcolor unknown use'.split( + ' ' + ) + ), + Ea = u( + 'math menclose merror mfenced mfrac mglyph mi mlabeledtr mmultiscripts mn mo mover mpadded mphantom mroot mrow ms mspace msqrt mstyle msub msup msubsup mtable mtd mtext mtr munder munderover'.split( + ' ' + ) + ), + qa = u( + 'maction maligngroup malignmark mlongdiv mscarries mscarry msgroup mstack msline msrow semantics annotation annotation-xml mprescripts none'.split( + ' ' + ) + ), + ia = u(['#text']), + Ka = u( + 'accept action align alt autocapitalize autocomplete autopictureinpicture autoplay background bgcolor border capture cellpadding cellspacing checked cite class clear color cols colspan controls controlslist coords crossorigin datetime decoding default dir disabled disablepictureinpicture disableremoteplayback download draggable enctype enterkeyhint face for headers height hidden high href hreflang id inputmode integrity ismap kind label lang list loading loop low max maxlength media method min minlength multiple muted name nonce noshade novalidate nowrap open optimum pattern placeholder playsinline poster preload pubdate radiogroup readonly rel required rev reversed role rows rowspan spellcheck scope selected shape size sizes span srclang start src srcset step style summary tabindex title translate type usemap valign value width xmlns slot'.split( + ' ' + ) + ), + ua = u( + 'accent-height accumulate additive alignment-baseline ascent attributename attributetype azimuth basefrequency baseline-shift begin bias by class clip clippathunits clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering cx cy d dx dy diffuseconstant direction display divisor dur edgemode elevation end fill fill-opacity fill-rule filter filterunits flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight fx fy g1 g2 glyph-name glyphref gradientunits gradienttransform height href id image-rendering in in2 k k1 k2 k3 k4 kerning keypoints keysplines keytimes lang lengthadjust letter-spacing kernelmatrix kernelunitlength lighting-color local marker-end marker-mid marker-start markerheight markerunits markerwidth maskcontentunits maskunits max mask media method mode min name numoctaves offset operator opacity order orient orientation origin overflow paint-order path pathlength patterncontentunits patterntransform patternunits points preservealpha preserveaspectratio primitiveunits r rx ry radius refx refy repeatcount repeatdur restart result rotate scale seed shape-rendering specularconstant specularexponent spreadmethod startoffset stddeviation stitchtiles stop-color stop-opacity stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke stroke-width style surfacescale systemlanguage tabindex targetx targety transform transform-origin text-anchor text-decoration text-rendering textlength type u1 u2 unicode values viewbox visibility version vert-adv-y vert-origin-x vert-origin-y width word-spacing wrap writing-mode xchannelselector ychannelselector x x1 x2 xmlns y y1 y2 z zoomandpan'.split( + ' ' + ) + ), + Xa = u( + 'accent accentunder align bevelled close columnsalign columnlines columnspan denomalign depth dir display displaystyle encoding fence frame height href id largeop length linethickness lspace lquote mathbackground mathcolor mathsize mathvariant maxsize minsize movablelimits notation numalign open rowalign rowlines rowspacing rowspan rspace rquote scriptlevel scriptminsize scriptsizemultiplier selection separator separators stretchy subscriptshift supscriptshift symmetric voffset width xmlns'.split( + ' ' + ) + ), + Z = u(['xlink:href', 'xml:id', 'xlink:title', 'xml:space', 'xmlns:xlink']), + ea = x(/\{\{[\s\S]*|[\s\S]*\}\}/gm), + L = x(/<%[\s\S]*|[\s\S]*%>/gm), + db = x(/^data-[\-\w.\u00B7-\uFFFF]/), + sa = x(/^aria-[\-\w]+$/), + eb = x(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i), + ta = x(/^(?:\w+script|data):/i), + Fa = x(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g), + La = x(/^html$/i), + la = function (b, c) { + if ('object' !== a(b) || 'function' != typeof b.createPolicy) return null; + var d = null; + c.currentScript && + c.currentScript.hasAttribute('data-tt-policy-suffix') && + (d = c.currentScript.getAttribute('data-tt-policy-suffix')); + d = 'dompurify' + (d ? '#' + d : ''); + try { + return b.createPolicy(d, { + createHTML: function (a) { + return a; + }, + }); + } catch (ba) { + return console.warn('TrustedTypes policy ' + d + ' could not be created.'), null; + } + }; + return (function pa() { + var b = + 0 < arguments.length && void 0 !== arguments[0] ? arguments[0] : 'undefined' == typeof window ? null : window, + c = function (a) { + return pa(a); + }; + if (((c.version = '2.3.6'), (c.removed = []), !b || !b.document || 9 !== b.document.nodeType)) + return (c.isSupported = !1), c; + var d = b.document, + f = b.document, + g = b.DocumentFragment, + m = b.HTMLTemplateElement, + n = b.Node, + p = b.Element, + r = b.NodeFilter, + t = b.NamedNodeMap, + x = void 0 === t ? b.NamedNodeMap || b.MozNamedAttrMap : t, + C = b.HTMLFormElement, + z = b.DOMParser, + t = b.trustedTypes, + B = p.prototype, + D = l(B, 'cloneNode'), + J = l(B, 'nextSibling'), + fa = l(B, 'childNodes'), + S = l(B, 'parentNode'); + 'function' == typeof m && + ((m = f.createElement('template')), m.content && m.content.ownerDocument && (f = m.content.ownerDocument)); + var ma = la(t, d), + R = ma ? ma.createHTML('') : '', + m = f, + ra = m.implementation, + ib = m.createNodeIterator, + Ta = m.createDocumentFragment, + za = m.getElementsByTagName, + tb = d.importNode, + m = {}; + try { + m = h(f).documentMode ? f.documentMode : {}; + } catch (Jb) {} + var Aa = {}; + c.isSupported = 'function' == typeof S && ra && void 0 !== ra.createHTMLDocument && 9 !== m; + var ab, + Ba, + jb = eb, + ga = null, + kb = k({}, [].concat(e(Oa), e(Da), e(Pa), e(Ea), e(ia))), + aa = null, + Ha = k({}, [].concat(e(Ka), e(ua), e(Xa), e(Z))), + ca = Object.seal( + Object.create(null, { + tagNameCheck: { writable: !0, configurable: !1, enumerable: !0, value: null }, + attributeNameCheck: { writable: !0, configurable: !1, enumerable: !0, value: null }, + allowCustomizedBuiltInElements: { writable: !0, configurable: !1, enumerable: !0, value: !1 }, + }) + ), + Ua = null, + Ya = null, + pb = !0, + Za = !0, + Ia = !1, + W = !1, + va = !1, + qb = !1, + bb = !1, + Na = !1, + fb = !1, + gb = !1, + ub = !0, + q = !0, + w = !1, + y = {}, + A = null, + G = k( + {}, + 'annotation-xml audio colgroup desc foreignobject head iframe math mi mn mo ms mtext noembed noframes noscript plaintext script style svg template thead title video xmp'.split( + ' ' + ) + ), + H = null, + oa = k({}, 'audio video img source image track'.split(' ')), + xa = null, + ka = k({}, 'alt class for id label name pattern placeholder role summary title value style xmlns'.split(' ')), + wa = 'http://www.w3.org/1999/xhtml', + lb = !1, + Db = ['application/xhtml+xml', 'text/html'], + mb = null, + Eb = f.createElement('form'), + yb = function (a) { + return a instanceof RegExp || a instanceof Function; + }, + rb = function (b) { + (mb && mb === b) || + ((b && 'object' === a(b)) || (b = {}), + (b = h(b)), + (ga = 'ALLOWED_TAGS' in b ? k({}, b.ALLOWED_TAGS) : kb), + (aa = 'ALLOWED_ATTR' in b ? k({}, b.ALLOWED_ATTR) : Ha), + (xa = 'ADD_URI_SAFE_ATTR' in b ? k(h(ka), b.ADD_URI_SAFE_ATTR) : ka), + (H = 'ADD_DATA_URI_TAGS' in b ? k(h(oa), b.ADD_DATA_URI_TAGS) : oa), + (A = 'FORBID_CONTENTS' in b ? k({}, b.FORBID_CONTENTS) : G), + (Ua = 'FORBID_TAGS' in b ? k({}, b.FORBID_TAGS) : {}), + (Ya = 'FORBID_ATTR' in b ? k({}, b.FORBID_ATTR) : {}), + (y = 'USE_PROFILES' in b && b.USE_PROFILES), + (pb = !1 !== b.ALLOW_ARIA_ATTR), + (Za = !1 !== b.ALLOW_DATA_ATTR), + (Ia = b.ALLOW_UNKNOWN_PROTOCOLS || !1), + (W = b.SAFE_FOR_TEMPLATES || !1), + (va = b.WHOLE_DOCUMENT || !1), + (Na = b.RETURN_DOM || !1), + (fb = b.RETURN_DOM_FRAGMENT || !1), + (gb = b.RETURN_TRUSTED_TYPE || !1), + (bb = b.FORCE_BODY || !1), + (ub = !1 !== b.SANITIZE_DOM), + (q = !1 !== b.KEEP_CONTENT), + (w = b.IN_PLACE || !1), + (jb = b.ALLOWED_URI_REGEXP || jb), + (wa = b.NAMESPACE || 'http://www.w3.org/1999/xhtml'), + b.CUSTOM_ELEMENT_HANDLING && + yb(b.CUSTOM_ELEMENT_HANDLING.tagNameCheck) && + (ca.tagNameCheck = b.CUSTOM_ELEMENT_HANDLING.tagNameCheck), + b.CUSTOM_ELEMENT_HANDLING && + yb(b.CUSTOM_ELEMENT_HANDLING.attributeNameCheck) && + (ca.attributeNameCheck = b.CUSTOM_ELEMENT_HANDLING.attributeNameCheck), + b.CUSTOM_ELEMENT_HANDLING && + 'boolean' == typeof b.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements && + (ca.allowCustomizedBuiltInElements = b.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements), + (ab = ab = -1 === Db.indexOf(b.PARSER_MEDIA_TYPE) ? 'text/html' : b.PARSER_MEDIA_TYPE), + (Ba = + 'application/xhtml+xml' === ab + ? function (a) { + return a; + } + : T), + W && (Za = !1), + fb && (Na = !0), + y && + ((ga = k({}, e(ia))), + (aa = []), + !0 === y.html && (k(ga, Oa), k(aa, Ka)), + !0 === y.svg && (k(ga, Da), k(aa, ua), k(aa, Z)), + !0 === y.svgFilters && (k(ga, Pa), k(aa, ua), k(aa, Z)), + !0 === y.mathMl && (k(ga, Ea), k(aa, Xa), k(aa, Z))), + b.ADD_TAGS && (ga === kb && (ga = h(ga)), k(ga, b.ADD_TAGS)), + b.ADD_ATTR && (aa === Ha && (aa = h(aa)), k(aa, b.ADD_ATTR)), + b.ADD_URI_SAFE_ATTR && k(xa, b.ADD_URI_SAFE_ATTR), + b.FORBID_CONTENTS && (A === G && (A = h(A)), k(A, b.FORBID_CONTENTS)), + q && (ga['#text'] = !0), + va && k(ga, ['html', 'head', 'body']), + ga.table && (k(ga, ['tbody']), delete Ua.tbody), + u && u(b), + (mb = b)); + }, + vb = k({}, ['mi', 'mo', 'mn', 'ms', 'mtext']), + na = k({}, ['foreignobject', 'desc', 'title', 'annotation-xml']), + sb = k({}, Da); + k(sb, Pa); + k(sb, Wa); + var wb = k({}, Ea); + k(wb, qa); + var Fb = function (a) { + var b = S(a); + (b && b.tagName) || (b = { namespaceURI: 'http://www.w3.org/1999/xhtml', tagName: 'template' }); + var c = T(a.tagName), + d = T(b.tagName); + if ('http://www.w3.org/2000/svg' === a.namespaceURI) + return 'http://www.w3.org/1999/xhtml' === b.namespaceURI + ? 'svg' === c + : 'http://www.w3.org/1998/Math/MathML' === b.namespaceURI + ? 'svg' === c && ('annotation-xml' === d || vb[d]) + : !!sb[c]; + if ('http://www.w3.org/1998/Math/MathML' === a.namespaceURI) + return 'http://www.w3.org/1999/xhtml' === b.namespaceURI + ? 'math' === c + : 'http://www.w3.org/2000/svg' === b.namespaceURI + ? 'math' === c && na[d] + : !!wb[c]; + if ('http://www.w3.org/1999/xhtml' === a.namespaceURI) { + if ( + ('http://www.w3.org/2000/svg' === b.namespaceURI && !na[d]) || + ('http://www.w3.org/1998/Math/MathML' === b.namespaceURI && !vb[d]) + ) + return !1; + a = k({}, ['title', 'style', 'font', 'a', 'script']); + return !wb[c] && (a[c] || !sb[c]); + } + return !1; + }, + cb = function (a) { + O(c.removed, { element: a }); + try { + a.parentNode.removeChild(a); + } catch (zb) { + try { + a.outerHTML = R; + } catch (Ab) { + a.remove(); + } + } + }, + Bb = function (a, b) { + try { + O(c.removed, { attribute: b.getAttributeNode(a), from: b }); + } catch (Ab) { + O(c.removed, { attribute: null, from: b }); + } + if ((b.removeAttribute(a), 'is' === a && !aa[a])) + if (Na || fb) + try { + cb(b); + } catch (Ab) {} + else + try { + b.setAttribute(a, ''); + } catch (Ab) {} + }, + Va = function (a) { + var b, c; + bb ? (a = '' + a) : (c = (c = M(a, /^[\r\n\t ]+/)) && c[0]); + 'application/xhtml+xml' === ab && + (a = '' + a + ''); + var d = ma ? ma.createHTML(a) : a; + if ('http://www.w3.org/1999/xhtml' === wa) + try { + b = new z().parseFromString(d, ab); + } catch (Gb) {} + if (!b || !b.documentElement) { + b = ra.createDocument(wa, 'template', null); + try { + b.documentElement.innerHTML = lb ? '' : d; + } catch (Gb) {} + } + d = b.body || b.documentElement; + return ( + a && c && d.insertBefore(f.createTextNode(c), d.childNodes[0] || null), + 'http://www.w3.org/1999/xhtml' === wa ? za.call(b, va ? 'html' : 'body')[0] : va ? b.documentElement : d + ); + }, + Hb = function (a) { + return ib.call(a.ownerDocument || a, a, r.SHOW_ELEMENT | r.SHOW_COMMENT | r.SHOW_TEXT, null, !1); + }, + nb = function (b) { + return 'object' === a(n) + ? b instanceof n + : b && 'object' === a(b) && 'number' == typeof b.nodeType && 'string' == typeof b.nodeName; + }, + $a = function (a, b, d) { + Aa[a] && + v(Aa[a], function (a) { + a.call(c, b, d, mb); + }); + }, + Ib = function (a) { + var b; + if ( + ($a('beforeSanitizeElements', a, null), + a instanceof C && + ('string' != typeof a.nodeName || + 'string' != typeof a.textContent || + 'function' != typeof a.removeChild || + !(a.attributes instanceof x) || + 'function' != typeof a.removeAttribute || + 'function' != typeof a.setAttribute || + 'string' != typeof a.namespaceURI || + 'function' != typeof a.insertBefore)) || + M(a.nodeName, /[\u0080-\uFFFF]/) + ) + return cb(a), !0; + var d = Ba(a.nodeName); + if ( + ($a('uponSanitizeElement', a, { tagName: d, allowedTags: ga }), + !(nb(a.firstElementChild) || (nb(a.content) && nb(a.content.firstElementChild))) && + Y(/<[/\w]/g, a.innerHTML) && + Y(/<[/\w]/g, a.textContent)) || + ('select' === d && Y(/