PageSourceSearch

https://silentsherpa.com/global/tinymce/tinymce.js

js silentsherpa.com collected 2026-10-06 01:29:10 UTC 1,055,682 bytes, 29,448 lines download raw bytes

1/**
2 * Copyright (c) Tiny Technologies, Inc. All rights reserved.
3 * Licensed under the LGPL or a commercial license.
4 * For LGPL see License.txt in the project root for license information.
5 * For commercial licenses see https://www.tiny.cloud/
6 *
7 * Version: 5.5.1 (2020-10-01)
8 */
9(function () {
10    'use strict';
11
12    var typeOf = function (x) {
13      if (x === null) {
14        return 'null';
15      }
16      if (x === undefined) {
17        return 'undefined';
18      }
19      var t = typeof x;
20      if (t === 'object' && (Array.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'Array')) {
21        return 'array';
22      }
23      if (t === 'object' && (String.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'String')) {
24        return 'string';
25      }
26      return t;
27    };
28    var isEquatableType = function (x) {
29      return [
30        'undefined',
31        'boolean',
32        'number',
33        'string',
34        'function',
35        'xml',
36        'null'
37      ].indexOf(x) !== -1;
38    };
39
40    var sort = function (xs, compareFn) {
41      var clone = Array.prototype.slice.call(xs);
42      return clone.sort(compareFn);
43    };
44
45    var contramap = function (eqa, f) {
46      return eq(function (x, y) {
47        return eqa.eq(f(x), f(y));
48      });
49    };
50    var eq = function (f) {
51      return { eq: f };
52    };
53    var tripleEq = eq(function (x, y) {
54      return x === y;
55    });
56    var eqString = tripleEq;
57    var eqArray = function (eqa) {
58      return eq(function (x, y) {
59        if (x.length !== y.length) {
60          return false;
61        }
62        var len = x.length;
63        for (var i = 0; i < len; i++) {
64          if (!eqa.eq(x[i], y[i])) {
65            return false;
66          }
67        }
68        return true;
69      });
70    };
71    var eqSortedArray = function (eqa, compareFn) {
72      return contramap(eqArray(eqa), function (xs) {
73        return sort(xs, compareFn);
74      });
75    };
76    var eqRecord = function (eqa) {
77      return eq(function (x, y) {
78        var kx = Object.keys(x);
79        var ky = Object.keys(y);
80        if (!eqSortedArray(eqString).eq(kx, ky)) {
81          return false;
82        }
83        var len = kx.length;
84        for (var i = 0; i < len; i++) {
85          var q = kx[i];
86          if (!eqa.eq(x[q], y[q])) {
87            return false;
88          }
89        }
90        return true;
91      });
92    };
93    var eqAny = eq(function (x, y) {
94      if (x === y) {
95        return true;
96      }
97      var tx = typeOf(x);
98      var ty = typeOf(y);
99      if (tx !== ty) {
100        return false;
101      }
102      if (isEquatableType(tx)) {
103        return x === y;
104      } else if (tx === 'array') {
105        return eqArray(eqAny).eq(x, y);
106      } else if (tx === 'object') {
107        return eqRecord(eqAny).eq(x, y);
108      }
109      return false;
110    });
111
112    var noop = function () {
113    };
114    var compose = function (fa, fb) {
115      return function () {
116        var args = [];
117        for (var _i = 0; _i < arguments.length; _i++) {
118          args[_i] = arguments[_i];
119        }
120        return fa(fb.apply(null, args));
121      };
122    };
123    var compose1 = function (fbc, fab) {
124      return function (a) {
125        return fbc(fab(a));
126      };
127    };
128    var constant = function (value) {
129      return function () {
130        return value;
131      };
132    };
133    var identity = function (x) {
134      return x;
135    };
136    function curry(fn) {
137      var initialArgs = [];
138      for (var _i = 1; _i < arguments.length; _i++) {
139        initialArgs[_i - 1] = arguments[_i];
140      }
141      return function () {
142        var restArgs = [];
143        for (var _i = 0; _i < arguments.length; _i++) {
144          restArgs[_i] = arguments[_i];
145        }
146        var all = initialArgs.concat(restArgs);
147        return fn.apply(null, all);
148      };
149    }
150    var not = function (f) {
151      return function (t) {
152        return !f(t);
153      };
154    };
155    var die = function (msg) {
156      return function () {
157        throw new Error(msg);
158      };
159    };
160    var never = constant(false);
161    var always = constant(true);
162
163    var none = function () {
164      return NONE;
165    };
166    var NONE = function () {
167      var eq = function (o) {
168        return o.isNone();
169      };
170      var call = function (thunk) {
171        return thunk();
172      };
173      var id = function (n) {
174        return n;
175      };
176      var me = {
177        fold: function (n, _s) {
178          return n();
179        },
180        is: never,
181        isSome: never,
182        isNone: always,
183        getOr: id,
184        getOrThunk: call,
185        getOrDie: function (msg) {
186          throw new Error(msg || 'error: getOrDie called on none.');
187        },
188        getOrNull: constant(null),
189        getOrUndefined: constant(undefined),
190        or: id,
191        orThunk: call,
192        map: none,
193        each: noop,
194        bind: none,
195        exists: never,
196        forall: always,
197        filter: none,
198        equals: eq,
199        equals_: eq,
200        toArray: function () {
201          return [];
202        },
203        toString: constant('none()')
204      };
205      return me;
206    }();
207    var some = function (a) {
208      var constant_a = constant(a);
209      var self = function () {
210        return me;
211      };
212      var bind = function (f) {
213        return f(a);
214      };
215      var me = {
216        fold: function (n, s) {
217          return s(a);
218        },
219        is: function (v) {
220          return a === v;
221        },
222        isSome: always,
223        isNone: never,
224        getOr: constant_a,
225        getOrThunk: constant_a,
226        getOrDie: constant_a,
227        getOrNull: constant_a,
228        getOrUndefined: constant_a,
229        or: self,
230        orThunk: self,
231        map: function (f) {
232          return some(f(a));
233        },
234        each: function (f) {
235          f(a);
236        },
237        bind: bind,
238        exists: bind,
239        forall: bind,
240        filter: function (f) {
241          return f(a) ? me : NONE;
242        },
243        toArray: function () {
244          return [a];
245        },
246        toString: function () {
247          return 'some(' + a + ')';
248        },
249        equals: function (o) {
250          return o.is(a);
251        },
252        equals_: function (o, elementEq) {
253          return o.fold(never, function (b) {
254            return elementEq(a, b);
255          });
256        }
257      };
258      return me;
259    };
260    var from = function (value) {
261      return value === null || value === undefined ? NONE : some(value);
262    };
263    var Optional = {
264      some: some,
265      none: none,
266      from: from
267    };
268
269    var typeOf$1 = function (x) {
270      var t = typeof x;
271      if (x === null) {
272        return 'null';
273      } else if (t === 'object' && (Array.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'Array')) {
274        return 'array';
275      } else if (t === 'object' && (String.prototype.isPrototypeOf(x) || x.constructor && x.constructor.name === 'String')) {
276        return 'string';
277      } else {
278        return t;
279      }
280    };
281    var isType = function (type) {
282      return function (value) {
283        return typeOf$1(value) === type;
284      };
285    };
286    var isSimpleType = function (type) {
287      return function (value) {
288        return typeof value === type;
289      };
290    };
291    var eq$1 = function (t) {
292      return function (a) {
293        return t === a;
294      };
295    };
296    var isString = isType('string');
297    var isObject = isType('object');
298    var isArray = isType('array');
299    var isNull = eq$1(null);
300    var isBoolean = isSimpleType('boolean');
301    var isUndefined = eq$1(undefined);
302    var isNullable = function (a) {
303      return a === null || a === undefined;
304    };
305    var isNonNullable = function (a) {
306      return !isNullable(a);
307    };
308    var isFunction = isSimpleType('function');
309    var isNumber = isSimpleType('number');
310
311    var nativeSlice = Array.prototype.slice;
312    var nativeIndexOf = Array.prototype.indexOf;
313    var nativePush = Array.prototype.push;
314    var rawIndexOf = function (ts, t) {
315      return nativeIndexOf.call(ts, t);
316    };
317    var indexOf = function (xs, x) {
318      var r = rawIndexOf(xs, x);
319      return r === -1 ? Optional.none() : Optional.some(r);
320    };
321    var contains = function (xs, x) {
322      return rawIndexOf(xs, x) > -1;
323    };
324    var exists = function (xs, pred) {
325      for (var i = 0, len = xs.length; i < len; i++) {
326        var x = xs[i];
327        if (pred(x, i)) {
328          return true;
329        }
330      }
331      return false;
332    };
333    var map = function (xs, f) {
334      var len = xs.length;
335      var r = new Array(len);
336      for (var i = 0; i < len; i++) {
337        var x = xs[i];
338        r[i] = f(x, i);
339      }
340      return r;
341    };
342    var each = function (xs, f) {
343      for (var i = 0, len = xs.length; i < len; i++) {
344        var x = xs[i];
345        f(x, i);
346      }
347    };
348    var eachr = function (xs, f) {
349      for (var i = xs.length - 1; i >= 0; i--) {
350        var x = xs[i];
351        f(x, i);
352      }
353    };
354    var partition = function (xs, pred) {
355      var pass = [];
356      var fail = [];
357      for (var i = 0, len = xs.length; i < len; i++) {
358        var x = xs[i];
359        var arr = pred(x, i) ? pass : fail;
360        arr.push(x);
361      }
362      return {
363        pass: pass,
364        fail: fail
365      };
366    };
367    var filter = function (xs, pred) {
368      var r = [];
369      for (var i = 0, len = xs.length; i < len; i++) {
370        var x = xs[i];
371        if (pred(x, i)) {
372          r.push(x);
373        }
374      }
375      return r;
376    };
377    var foldr = function (xs, f, acc) {
378      eachr(xs, function (x) {
379        acc = f(acc, x);
380      });
381      return acc;
382    };
383    var foldl = function (xs, f, acc) {
384      each(xs, function (x) {
385        acc = f(acc, x);
386      });
387      return acc;
388    };
389    var findUntil = function (xs, pred, until) {
390      for (var i = 0, len = xs.length; i < len; i++) {
391        var x = xs[i];
392        if (pred(x, i)) {
393          return Optional.some(x);
394        } else if (until(x, i)) {
395          break;
396        }
397      }
398      return Optional.none();
399    };
400    var find = function (xs, pred) {
401      return findUntil(xs, pred, never);
402    };
403    var findIndex = function (xs, pred) {
404      for (var i = 0, len = xs.length; i < len; i++) {
405        var x = xs[i];
406        if (pred(x, i)) {
407          return Optional.some(i);
408        }
409      }
410      return Optional.none();
411    };
412    var flatten = function (xs) {
413      var r = [];
414      for (var i = 0, len = xs.length; i < len; ++i) {
415        if (!isArray(xs[i])) {
416          throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs);
417        }
418        nativePush.apply(r, xs[i]);
419      }
420      return r;
421    };
422    var bind = function (xs, f) {
423      return flatten(map(xs, f));
424    };
425    var forall = function (xs, pred) {
426      for (var i = 0, len = xs.length; i < len; ++i) {
427        var x = xs[i];
428        if (pred(x, i) !== true) {
429          return false;
430        }
431      }
432      return true;
433    };
434    var reverse = function (xs) {
435      var r = nativeSlice.call(xs, 0);
436      r.reverse();
437      return r;
438    };
439    var difference = function (a1, a2) {
440      return filter(a1, function (x) {
441        return !contains(a2, x);
442      });
443    };
444    var mapToObject = function (xs, f) {
445      var r = {};
446      for (var i = 0, len = xs.length; i < len; i++) {
447        var x = xs[i];
448        r[String(x)] = f(x, i);
449      }
450      return r;
451    };
452    var sort$1 = function (xs, comparator) {
453      var copy = nativeSlice.call(xs, 0);
454      copy.sort(comparator);
455      return copy;
456    };
457    var head = function (xs) {
458      return xs.length === 0 ? Optional.none() : Optional.some(xs[0]);
459    };
460    var last = function (xs) {
461      return xs.length === 0 ? Optional.none() : Optional.some(xs[xs.length - 1]);
462    };
463    var from$1 = isFunction(Array.from) ? Array.from : function (x) {
464      return nativeSlice.call(x);
465    };
466
467    var keys = Object.keys;
468    var hasOwnProperty = Object.hasOwnProperty;
469    var each$1 = function (obj, f) {
470      var props = keys(obj);
471      for (var k = 0, len = props.length; k < len; k++) {
472        var i = props[k];
473        var x = obj[i];
474        f(x, i);
475      }
476    };
477    var map$1 = function (obj, f) {
478      return tupleMap(obj, function (x, i) {
479        return {
480          k: i,
481          v: f(x, i)
482        };
483      });
484    };
485    var tupleMap = function (obj, f) {
486      var r = {};
487      each$1(obj, function (x, i) {
488        var tuple = f(x, i);
489        r[tuple.k] = tuple.v;
490      });
491      return r;
492    };
493    var objAcc = function (r) {
494      return function (x, i) {
495        r[i] = x;
496      };
497    };
498    var internalFilter = function (obj, pred, onTrue, onFalse) {
499      var r = {};
500      each$1(obj, function (x, i) {
501        (pred(x, i) ? onTrue : onFalse)(x, i);
502      });
503      return r;
504    };
505    var bifilter = function (obj, pred) {
506      var t = {};
507      var f = {};
508      internalFilter(obj, pred, objAcc(t), objAcc(f));
509      return {
510        t: t,
511        f: f
512      };
513    };
514    var filter$1 = function (obj, pred) {
515      var t = {};
516      internalFilter(obj, pred, objAcc(t), noop);
517      return t;
518    };
519    var mapToArray = function (obj, f) {
520      var r = [];
521      each$1(obj, function (value, name) {
522        r.push(f(value, name));
523      });
524      return r;
525    };
526    var values = function (obj) {
527      return mapToArray(obj, function (v) {
528        return v;
529      });
530    };
531    var get = function (obj, key) {
532      return has(obj, key) ? Optional.from(obj[key]) : Optional.none();
533    };
534    var has = function (obj, key) {
535      return hasOwnProperty.call(obj, key);
536    };
537    var equal = function (a1, a2, eq) {
538      if (eq === void 0) {
539        eq = eqAny;
540      }
541      return eqRecord(eq).eq(a1, a2);
542    };
543
544    var isArray$1 = Array.isArray;
545    var toArray = function (obj) {
546      if (!isArray$1(obj)) {
547        var array = [];
548        for (var i = 0, l = obj.length; i < l; i++) {
549          array[i] = obj[i];
550        }
551        return array;
552      } else {
553        return obj;
554      }
555    };
556    var each$2 = function (o, cb, s) {
557      var n, l;
558      if (!o) {
559        return false;
560      }
561      s = s || o;
562      if (o.length !== undefined) {
563        for (n = 0, l = o.length; n < l; n++) {
564          if (cb.call(s, o[n], n, o) === false) {
565            return false;
566          }
567        }
568      } else {
569        for (n in o) {
570          if (o.hasOwnProperty(n)) {
571            if (cb.call(s, o[n], n, o) === false) {
572              return false;
573            }
574          }
575        }
576      }
577      return true;
578    };
579    var map$2 = function (array, callback) {
580      var out = [];
581      each$2(array, function (item, index) {
582        out.push(callback(item, index, array));
583      });
584      return out;
585    };
586    var filter$2 = function (a, f) {
587      var o = [];
588      each$2(a, function (v, index) {
589        if (!f || f(v, index, a)) {
590          o.push(v);
591        }
592      });
593      return o;
594    };
595    var indexOf$1 = function (a, v) {
596      if (a) {
597        for (var i = 0, l = a.length; i < l; i++) {
598          if (a[i] === v) {
599            return i;
600          }
601        }
602      }
603      return -1;
604    };
605    var reduce = function (collection, iteratee, accumulator, thisArg) {
606      var acc = isUndefined(accumulator) ? collection[0] : accumulator;
607      for (var i = 0; i < collection.length; i++) {
608        acc = iteratee.call(thisArg, acc, collection[i], i);
609      }
610      return acc;
611    };
612    var findIndex$1 = function (array, predicate, thisArg) {
613      var i, l;
614      for (i = 0, l = array.length; i < l; i++) {
615        if (predicate.call(thisArg, array[i], i, array)) {
616          return i;
617        }
618      }
619      return -1;
620    };
621    var last$1 = function (collection) {
622      return collection[collection.length - 1];
623    };
624
625    var __assign = function () {
626      __assign = Object.assign || function __assign(t) {
627        for (var s, i = 1, n = arguments.length; i < n; i++) {
628          s = arguments[i];
629          for (var p in s)
630            if (Object.prototype.hasOwnProperty.call(s, p))
631              t[p] = s[p];
632        }
633        return t;
634      };
635      return __assign.apply(this, arguments);
636    };
637    function __rest(s, e) {
638      var t = {};
639      for (var p in s)
640        if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
641          t[p] = s[p];
642      if (s != null && typeof Object.getOwnPropertySymbols === 'function')
643        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
644          if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
645            t[p[i]] = s[p[i]];
646        }
647      return t;
648    }
649    function __spreadArrays() {
650      for (var s = 0, i = 0, il = arguments.length; i < il; i++)
651        s += arguments[i].length;
652      for (var r = Array(s), k = 0, i = 0; i < il; i++)
653        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
654          r[k] = a[j];
655      return r;
656    }
657
658    var cached = function (f) {
659      var called = false;
660      var r;
661      return function () {
662        var args = [];
663        for (var _i = 0; _i < arguments.length; _i++) {
664          args[_i] = arguments[_i];
665        }
666        if (!called) {
667          called = true;
668          r = f.apply(null, args);
669        }
670        return r;
671      };
672    };
673
674    var DeviceType = function (os, browser, userAgent, mediaMatch) {
675      var isiPad = os.isiOS() && /ipad/i.test(userAgent) === true;
676      var isiPhone = os.isiOS() && !isiPad;
677      var isMobile = os.isiOS() || os.isAndroid();
678      var isTouch = isMobile || mediaMatch('(pointer:coarse)');
679      var isTablet = isiPad || !isiPhone && isMobile && mediaMatch('(min-device-width:768px)');
680      var isPhone = isiPhone || isMobile && !isTablet;
681      var iOSwebview = browser.isSafari() && os.isiOS() && /safari/i.test(userAgent) === false;
682      var isDesktop = !isPhone && !isTablet && !iOSwebview;
683      return {
684        isiPad: constant(isiPad),
685        isiPhone: constant(isiPhone),
686        isTablet: constant(isTablet),
687        isPhone: constant(isPhone),
688        isTouch: constant(isTouch),
689        isAndroid: os.isAndroid,
690        isiOS: os.isiOS,
691        isWebView: constant(iOSwebview),
692        isDesktop: constant(isDesktop)
693      };
694    };
695
696    var firstMatch = function (regexes, s) {
697      for (var i = 0; i < regexes.length; i++) {
698        var x = regexes[i];
699        if (x.test(s)) {
700          return x;
701        }
702      }
703      return undefined;
704    };
705    var find$1 = function (regexes, agent) {
706      var r = firstMatch(regexes, agent);
707      if (!r) {
708        return {
709          major: 0,
710          minor: 0
711        };
712      }
713      var group = function (i) {
714        return Number(agent.replace(r, '$' + i));
715      };
716      return nu(group(1), group(2));
717    };
718    var detect = function (versionRegexes, agent) {
719      var cleanedAgent = String(agent).toLowerCase();
720      if (versionRegexes.length === 0) {
721        return unknown();
722      }
723      return find$1(versionRegexes, cleanedAgent);
724    };
725    var unknown = function () {
726      return nu(0, 0);
727    };
728    var nu = function (major, minor) {
729      return {
730        major: major,
731        minor: minor
732      };
733    };
734    var Version = {
735      nu: nu,
736      detect: detect,
737      unknown: unknown
738    };
739
740    var detect$1 = function (candidates, userAgent) {
741      var agent = String(userAgent).toLowerCase();
742      return find(candidates, function (candidate) {
743        return candidate.search(agent);
744      });
745    };
746    var detectBrowser = function (browsers, userAgent) {
747      return detect$1(browsers, userAgent).map(function (browser) {
748        var version = Version.detect(browser.versionRegexes, userAgent);
749        return {
750          current: browser.name,
751          version: version
752        };
753      });
754    };
755    var detectOs = function (oses, userAgent) {
756      return detect$1(oses, userAgent).map(function (os) {
757        var version = Version.detect(os.versionRegexes, userAgent);
758        return {
759          current: os.name,
760          version: version
761        };
762      });
763    };
764    var UaString = {
765      detectBrowser: detectBrowser,
766      detectOs: detectOs
767    };
768
769    var checkRange = function (str, substr, start) {
770      return substr === '' || str.length >= substr.length && str.substr(start, start + substr.length) === substr;
771    };
772    var contains$1 = function (str, substr) {
773      return str.indexOf(substr) !== -1;
774    };
775    var startsWith = function (str, prefix) {
776      return checkRange(str, prefix, 0);
777    };
778    var blank = function (r) {
779      return function (s) {
780        return s.replace(r, '');
781      };
782    };
783    var trim = blank(/^\s+|\s+$/g);
784    var lTrim = blank(/^\s+/g);
785    var rTrim = blank(/\s+$/g);
786
787    var normalVersionRegex = /.*?version\/\ ?([0-9]+)\.([0-9]+).*/;
788    var checkContains = function (target) {
789      return function (uastring) {
790        return contains$1(uastring, target);
791      };
792    };
793    var browsers = [
794      {
795        name: 'Edge',
796        versionRegexes: [/.*?edge\/ ?([0-9]+)\.([0-9]+)$/],
797        search: function (uastring) {
798          return contains$1(uastring, 'edge/') && contains$1(uastring, 'chrome') && contains$1(uastring, 'safari') && contains$1(uastring, 'applewebkit');
799        }
800      },
801      {
802        name: 'Chrome',
803        versionRegexes: [
804          /.*?chrome\/([0-9]+)\.([0-9]+).*/,
805          normalVersionRegex
806        ],
807        search: function (uastring) {
808          return contains$1(uastring, 'chrome') && !contains$1(uastring, 'chromeframe');
809        }
810      },
811      {
812        name: 'IE',
813        versionRegexes: [
814          /.*?msie\ ?([0-9]+)\.([0-9]+).*/,
815          /.*?rv:([0-9]+)\.([0-9]+).*/
816        ],
817        search: function (uastring) {
818          return contains$1(uastring, 'msie') || contains$1(uastring, 'trident');
819        }
820      },
821      {
822        name: 'Opera',
823        versionRegexes: [
824          normalVersionRegex,
825          /.*?opera\/([0-9]+)\.([0-9]+).*/
826        ],
827        search: checkContains('opera')
828      },
829      {
830        name: 'Firefox',
831        versionRegexes: [/.*?firefox\/\ ?([0-9]+)\.([0-9]+).*/],
832        search: checkContains('firefox')
833      },
834      {
835        name: 'Safari',
836        versionRegexes: [
837          normalVersionRegex,
838          /.*?cpu os ([0-9]+)_([0-9]+).*/
839        ],
840        search: function (uastring) {
841          return (contains$1(uastring, 'safari') || contains$1(uastring, 'mobile/')) && contains$1(uastring, 'applewebkit');
842        }
843      }
844    ];
845    var oses = [
846      {
847        name: 'Windows',
848        search: checkContains('win'),
849        versionRegexes: [/.*?windows\ nt\ ?([0-9]+)\.([0-9]+).*/]
850      },
851      {
852        name: 'iOS',
853        search: function (uastring) {
854          return contains$1(uastring, 'iphone') || contains$1(uastring, 'ipad');
855        },
856        versionRegexes: [
857          /.*?version\/\ ?([0-9]+)\.([0-9]+).*/,
858          /.*cpu os ([0-9]+)_([0-9]+).*/,
859          /.*cpu iphone os ([0-9]+)_([0-9]+).*/
860        ]
861      },
862      {
863        name: 'Android',
864        search: checkContains('android'),
865        versionRegexes: [/.*?android\ ?([0-9]+)\.([0-9]+).*/]
866      },
867      {
868        name: 'OSX',
869        search: checkContains('mac os x'),
870        versionRegexes: [/.*?mac\ os\ x\ ?([0-9]+)_([0-9]+).*/]
871      },
872      {
873        name: 'Linux',
874        search: checkContains('linux'),
875        versionRegexes: []
876      },
877      {
878        name: 'Solaris',
879        search: checkContains('sunos'),
880        versionRegexes: []
881      },
882      {
883        name: 'FreeBSD',
884        search: checkContains('freebsd'),
885        versionRegexes: []
886      },
887      {
888        name: 'ChromeOS',
889        search: checkContains('cros'),
890        versionRegexes: [/.*?chrome\/([0-9]+)\.([0-9]+).*/]
891      }
892    ];
893    var PlatformInfo = {
894      browsers: constant(browsers),
895      oses: constant(oses)
896    };
897
898    var edge = 'Edge';
899    var chrome = 'Chrome';
900    var ie = 'IE';
901    var opera = 'Opera';
902    var firefox = 'Firefox';
903    var safari = 'Safari';
904    var unknown$1 = function () {
905      return nu$1({
906        current: undefined,
907        version: Version.unknown()
908      });
909    };
910    var nu$1 = function (info) {
911      var current = info.current;
912      var version = info.version;
913      var isBrowser = function (name) {
914        return function () {
915          return current === name;
916        };
917      };
918      return {
919        current: current,
920        version: version,
921        isEdge: isBrowser(edge),
922        isChrome: isBrowser(chrome),
923        isIE: isBrowser(ie),
924        isOpera: isBrowser(opera),
925        isFirefox: isBrowser(firefox),
926        isSafari: isBrowser(safari)
927      };
928    };
929    var Browser = {
930      unknown: unknown$1,
931      nu: nu$1,
932      edge: constant(edge),
933      chrome: constant(chrome),
934      ie: constant(ie),
935      opera: constant(opera),
936      firefox: constant(firefox),
937      safari: constant(safari)
938    };
939
940    var windows = 'Windows';
941    var ios = 'iOS';
942    var android = 'Android';
943    var linux = 'Linux';
944    var osx = 'OSX';
945    var solaris = 'Solaris';
946    var freebsd = 'FreeBSD';
947    var chromeos = 'ChromeOS';
948    var unknown$2 = function () {
949      return nu$2({
950        current: undefined,
951        version: Version.unknown()
952      });
953    };
954    var nu$2 = function (info) {
955      var current = info.current;
956      var version = info.version;
957      var isOS = function (name) {
958        return function () {
959          return current === name;
960        };
961      };
962      return {
963        current: current,
964        version: version,
965        isWindows: isOS(windows),
966        isiOS: isOS(ios),
967        isAndroid: isOS(android),
968        isOSX: isOS(osx),
969        isLinux: isOS(linux),
970        isSolaris: isOS(solaris),
971        isFreeBSD: isOS(freebsd),
972        isChromeOS: isOS(chromeos)
973      };
974    };
975    var OperatingSystem = {
976      unknown: unknown$2,
977      nu: nu$2,
978      windows: constant(windows),
979      ios: constant(ios),
980      android: constant(android),
981      linux: constant(linux),
982      osx: constant(osx),
983      solaris: constant(solaris),
984      freebsd: constant(freebsd),
985      chromeos: constant(chromeos)
986    };
987
988    var detect$2 = function (userAgent, mediaMatch) {
989      var browsers = PlatformInfo.browsers();
990      var oses = PlatformInfo.oses();
991      var browser = UaString.detectBrowser(browsers, userAgent).fold(Browser.unknown, Browser.nu);
992      var os = UaString.detectOs(oses, userAgent).fold(OperatingSystem.unknown, OperatingSystem.nu);
993      var deviceType = DeviceType(os, browser, userAgent, mediaMatch);
994      return {
995        browser: browser,
996        os: os,
997        deviceType: deviceType
998      };
999    };
1000    var PlatformDetection = { detect: detect$2 };
1001
1002    var mediaMatch = function (query) {
1003      return window.matchMedia(query).matches;
1004    };
1005    var platform = cached(function () {
1006      return PlatformDetection.detect(navigator.userAgent, mediaMatch);
1007    });
1008    var detect$3 = function () {
1009      return platform();
1010    };
1011
1012    var userAgent = navigator.userAgent;
1013    var platform$1 = detect$3();
1014    var browser = platform$1.browser;
1015    var os = platform$1.os;
1016    var deviceType = platform$1.deviceType;
1017    var webkit = /WebKit/.test(userAgent) && !browser.isEdge();
1018    var fileApi = 'FormData' in window && 'FileReader' in window && 'URL' in window && !!URL.createObjectURL;
1019    var windowsPhone = userAgent.indexOf('Windows Phone') !== -1;
1020    var Env = {
1021      opera: browser.isOpera(),
1022      webkit: webkit,
1023      ie: browser.isIE() || browser.isEdge() ? browser.version.major : false,
1024      gecko: browser.isFirefox(),
1025      mac: os.isOSX() || os.isiOS(),
1026      iOS: deviceType.isiPad() || deviceType.isiPhone(),
1027      android: os.isAndroid(),
1028      contentEditable: true,
1029      transparentSrc: 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',
1030      caretAfter: true,
1031      range: window.getSelection && 'Range' in window,
1032      documentMode: browser.isIE() ? document.documentMode || 7 : 10,
1033      fileApi: fileApi,
1034      ceFalse: true,
1035      cacheSuffix: null,
1036      container: null,
1037      experimentalShadowDom: false,
1038      canHaveCSP: !browser.isIE(),
1039      desktop: deviceType.isDesktop(),
1040      windowsPhone: windowsPhone,
1041      browser: {
1042        current: browser.current,
1043        version: browser.version,
1044        isChrome: browser.isChrome,
1045        isEdge: browser.isEdge,
1046        isFirefox: browser.isFirefox,
1047        isIE: browser.isIE,
1048        isOpera: browser.isOpera,
1049        isSafari: browser.isSafari
1050      },
1051      os: {
1052        current: os.current,
1053        version: os.version,
1054        isAndroid: os.isAndroid,
1055        isChromeOS: os.isChromeOS,
1056        isFreeBSD: os.isFreeBSD,
1057        isiOS: os.isiOS,
1058        isLinux: os.isLinux,
1059        isOSX: os.isOSX,
1060        isSolaris: os.isSolaris,
1061        isWindows: os.isWindows
1062      },
1063      deviceType: {
1064        isDesktop: deviceType.isDesktop,
1065        isiPad: deviceType.isiPad,
1066        isiPhone: deviceType.isiPhone,
1067        isPhone: deviceType.isPhone,
1068        isTablet: deviceType.isTablet,
1069        isTouch: deviceType.isTouch,
1070        isWebView: deviceType.isWebView
1071      }
1072    };
1073
1074    var whiteSpaceRegExp = /^\s*|\s*$/g;
1075    var trim$1 = function (str) {
1076      return str === null || str === undefined ? '' : ('' + str).replace(whiteSpaceRegExp, '');
1077    };
1078    var is = function (obj, type) {
1079      if (!type) {
1080        return obj !== undefined;
1081      }
1082      if (type === 'array' && isArray$1(obj)) {
1083        return true;
1084      }
1085      return typeof obj === type;
1086    };
1087    var makeMap = function (items, delim, map) {
1088      var i;
1089      items = items || [];
1090      delim = delim || ',';
1091      if (typeof items === 'string') {
1092        items = items.split(delim);
1093      }
1094      map = map || {};
1095      i = items.length;
1096      while (i--) {
1097        map[items[i]] = {};
1098      }
1099      return map;
1100    };
1101    var hasOwnProperty$1 = function (obj, prop) {
1102      return Object.prototype.hasOwnProperty.call(obj, prop);
1103    };
1104    var create = function (s, p, root) {
1105      var self = this;
1106      var sp, scn, c, de = 0;
1107      s = /^((static) )?([\w.]+)(:([\w.]+))?/.exec(s);
1108      var cn = s[3].match(/(^|\.)(\w+)$/i)[2];
1109      var ns = self.createNS(s[3].replace(/\.\w+$/, ''), root);
1110      if (ns[cn]) {
1111        return;
1112      }
1113      if (s[2] === 'static') {
1114        ns[cn] = p;
1115        if (this.onCreate) {
1116          this.onCreate(s[2], s[3], ns[cn]);
1117        }
1118        return;
1119      }
1120      if (!p[cn]) {
1121        p[cn] = function () {
1122        };
1123        de = 1;
1124      }
1125      ns[cn] = p[cn];
1126      self.extend(ns[cn].prototype, p);
1127      if (s[5]) {
1128        sp = self.resolve(s[5]).prototype;
1129        scn = s[5].match(/\.(\w+)$/i)[1];
1130        c = ns[cn];
1131        if (de) {
1132          ns[cn] = function () {
1133            return sp[scn].apply(this, arguments);
1134          };
1135        } else {
1136          ns[cn] = function () {
1137            this.parent = sp[scn];
1138            return c.apply(this, arguments);
1139          };
1140        }
1141        ns[cn].prototype[cn] = ns[cn];
1142        self.each(sp, function (f, n) {
1143          ns[cn].prototype[n] = sp[n];
1144        });
1145        self.each(p, function (f, n) {
1146          if (sp[n]) {
1147            ns[cn].prototype[n] = function () {
1148              this.parent = sp[n];
1149              return f.apply(this, arguments);
1150            };
1151          } else {
1152            if (n !== cn) {
1153              ns[cn].prototype[n] = f;
1154            }
1155          }
1156        });
1157      }
1158      self.each(p.static, function (f, n) {
1159        ns[cn][n] = f;
1160      });
1161    };
1162    var extend = function (obj) {
1163      var exts = [];
1164      for (var _i = 1; _i < arguments.length; _i++) {
1165        exts[_i - 1] = arguments[_i];
1166      }
1167      for (var i = 0; i < exts.length; i++) {
1168        var ext = exts[i];
1169        for (var name_1 in ext) {
1170          if (ext.hasOwnProperty(name_1)) {
1171            var value = ext[name_1];
1172            if (value !== undefined) {
1173              obj[name_1] = value;
1174            }
1175          }
1176        }
1177      }
1178      return obj;
1179    };
1180    var walk = function (o, f, n, s) {
1181      s = s || this;
1182      if (o) {
1183        if (n) {
1184          o = o[n];
1185        }
1186        each$2(o, function (o, i) {
1187          if (f.call(s, o, i, n) === false) {
1188            return false;
1189          }
1190          walk(o, f, n, s);
1191        });
1192      }
1193    };
1194    var createNS = function (n, o) {
1195      var i, v;
1196      o = o || window;
1197      n = n.split('.');
1198      for (i = 0; i < n.length; i++) {
1199        v = n[i];
1200        if (!o[v]) {
1201          o[v] = {};
1202        }
1203        o = o[v];
1204      }
1205      return o;
1206    };
1207    var resolve = function (n, o) {
1208      var i, l;
1209      o = o || window;
1210      n = n.split('.');
1211      for (i = 0, l = n.length; i < l; i++) {
1212        o = o[n[i]];
1213        if (!o) {
1214          break;
1215        }
1216      }
1217      return o;
1218    };
1219    var explode = function (s, d) {
1220      if (!s || is(s, 'array')) {
1221        return s;
1222      }
1223      return map$2(s.split(d || ','), trim$1);
1224    };
1225    var _addCacheSuffix = function (url) {
1226      var cacheSuffix = Env.cacheSuffix;
1227      if (cacheSuffix) {
1228        url += (url.indexOf('?') === -1 ? '?' : '&') + cacheSuffix;
1229      }
1230      return url;
1231    };
1232    var Tools = {
1233      trim: trim$1,
1234      isArray: isArray$1,
1235      is: is,
1236      toArray: toArray,
1237      makeMap: makeMap,
1238      each: each$2,
1239      map: map$2,
1240      grep: filter$2,
1241      inArray: indexOf$1,
1242      hasOwn: hasOwnProperty$1,
1243      extend: extend,
1244      create: create,
1245      walk: walk,
1246      createNS: createNS,
1247      resolve: resolve,
1248      explode: explode,
1249      _addCacheSuffix: _addCacheSuffix
1250    };
1251
1252    var fromHtml = function (html, scope) {
1253      var doc = scope || document;
1254      var div = doc.createElement('div');
1255      div.innerHTML = html;
1256      if (!div.hasChildNodes() || div.childNodes.length > 1) {
1257        console.error('HTML does not have a single root node', html);
1258        throw new Error('HTML must have a single root node');
1259      }
1260      return fromDom(div.childNodes[0]);
1261    };
1262    var fromTag = function (tag, scope) {
1263      var doc = scope || document;
1264      var node = doc.createElement(tag);
1265      return fromDom(node);
1266    };
1267    var fromText = function (text, scope) {
1268      var doc = scope || document;
1269      var node = doc.createTextNode(text);
1270      return fromDom(node);
1271    };
1272    var fromDom = function (node) {
1273      if (node === null || node === undefined) {
1274        throw new Error('Node cannot be null or undefined');
1275      }
1276      return { dom: node };
1277    };
1278    var fromPoint = function (docElm, x, y) {
1279      return Optional.from(docElm.dom.elementFromPoint(x, y)).map(fromDom);
1280    };
1281    var SugarElement = {
1282      fromHtml: fromHtml,
1283      fromTag: fromTag,
1284      fromText: fromText,
1285      fromDom: fromDom,
1286      fromPoint: fromPoint
1287    };
1288
1289    var toArray$1 = function (target, f) {
1290      var r = [];
1291      var recurse = function (e) {
1292        r.push(e);
1293        return f(e);
1294      };
1295      var cur = f(target);
1296      do {
1297        cur = cur.bind(recurse);
1298      } while (cur.isSome());
1299      return r;
1300    };
1301
1302    var compareDocumentPosition = function (a, b, match) {
1303      return (a.compareDocumentPosition(b) & match) !== 0;
1304    };
1305    var documentPositionContainedBy = function (a, b) {
1306      return compareDocumentPosition(a, b, Node.DOCUMENT_POSITION_CONTAINED_BY);
1307    };
1308
1309    var COMMENT = 8;
1310    var DOCUMENT = 9;
1311    var DOCUMENT_FRAGMENT = 11;
1312    var ELEMENT = 1;
1313    var TEXT = 3;
1314
1315    var is$1 = function (element, selector) {
1316      var dom = element.dom;
1317      if (dom.nodeType !== ELEMENT) {
1318        return false;
1319      } else {
1320        var elem = dom;
1321        if (elem.matches !== undefined) {
1322          return elem.matches(selector);
1323        } else if (elem.msMatchesSelector !== undefined) {
1324          return elem.msMatchesSelector(selector);
1325        } else if (elem.webkitMatchesSelector !== undefined) {
1326          return elem.webkitMatchesSelector(selector);
1327        } else if (elem.mozMatchesSelector !== undefined) {
1328          return elem.mozMatchesSelector(selector);
1329        } else {
1330          throw new Error('Browser lacks native selectors');
1331        }
1332      }
1333    };
1334    var bypassSelector = function (dom) {
1335      return dom.nodeType !== ELEMENT && dom.nodeType !== DOCUMENT && dom.nodeType !== DOCUMENT_FRAGMENT || dom.childElementCount === 0;
1336    };
1337    var all = function (selector, scope) {
1338      var base = scope === undefined ? document : scope.dom;
1339      return bypassSelector(base) ? [] : map(base.querySelectorAll(selector), SugarElement.fromDom);
1340    };
1341    var one = function (selector, scope) {
1342      var base = scope === undefined ? document : scope.dom;
1343      return bypassSelector(base) ? Optional.none() : Optional.from(base.querySelector(selector)).map(SugarElement.fromDom);
1344    };
1345
1346    var eq$2 = function (e1, e2) {
1347      return e1.dom === e2.dom;
1348    };
1349    var regularContains = function (e1, e2) {
1350      var d1 = e1.dom;
1351      var d2 = e2.dom;
1352      return d1 === d2 ? false : d1.contains(d2);
1353    };
1354    var ieContains = function (e1, e2) {
1355      return documentPositionContainedBy(e1.dom, e2.dom);
1356    };
1357    var contains$2 = function (e1, e2) {
1358      return detect$3().browser.isIE() ? ieContains(e1, e2) : regularContains(e1, e2);
1359    };
1360
1361    var Global = typeof window !== 'undefined' ? window : Function('return this;')();
1362
1363    var name = function (element) {
1364      var r = element.dom.nodeName;
1365      return r.toLowerCase();
1366    };
1367    var type = function (element) {
1368      return element.dom.nodeType;
1369    };
1370    var isType$1 = function (t) {
1371      return function (element) {
1372        return type(element) === t;
1373      };
1374    };
1375    var isComment = function (element) {
1376      return type(element) === COMMENT || name(element) === '#comment';
1377    };
1378    var isElement = isType$1(ELEMENT);
1379    var isText = isType$1(TEXT);
1380    var isDocument = isType$1(DOCUMENT);
1381    var isDocumentFragment = isType$1(DOCUMENT_FRAGMENT);
1382
1383    var owner = function (element) {
1384      return SugarElement.fromDom(element.dom.ownerDocument);
1385    };
1386    var documentOrOwner = function (dos) {
1387      return isDocument(dos) ? dos : owner(dos);
1388    };
1389    var documentElement = function (element) {
1390      return SugarElement.fromDom(documentOrOwner(element).dom.documentElement);
1391    };
1392    var defaultView = function (element) {
1393      return SugarElement.fromDom(documentOrOwner(element).dom.defaultView);
1394    };
1395    var parent = function (element) {
1396      return Optional.from(element.dom.parentNode).map(SugarElement.fromDom);
1397    };
1398    var parents = function (element, isRoot) {
1399      var stop = isFunction(isRoot) ? isRoot : never;
1400      var dom = element.dom;
1401      var ret = [];
1402      while (dom.parentNode !== null && dom.parentNode !== undefined) {
1403        var rawParent = dom.parentNode;
1404        var p = SugarElement.fromDom(rawParent);
1405        ret.push(p);
1406        if (stop(p) === true) {
1407          break;
1408        } else {
1409          dom = rawParent;
1410        }
1411      }
1412      return ret;
1413    };
1414    var siblings = function (element) {
1415      var filterSelf = function (elements) {
1416        return filter(elements, function (x) {
1417          return !eq$2(element, x);
1418        });
1419      };
1420      return parent(element).map(children).map(filterSelf).getOr([]);
1421    };
1422    var prevSibling = function (element) {
1423      return Optional.from(element.dom.previousSibling).map(SugarElement.fromDom);
1424    };
1425    var nextSibling = function (element) {
1426      return Optional.from(element.dom.nextSibling).map(SugarElement.fromDom);
1427    };
1428    var prevSiblings = function (element) {
1429      return reverse(toArray$1(element, prevSibling));
1430    };
1431    var nextSiblings = function (element) {
1432      return toArray$1(element, nextSibling);
1433    };
1434    var children = function (element) {
1435      return map(element.dom.childNodes, SugarElement.fromDom);
1436    };
1437    var child = function (element, index) {
1438      var cs = element.dom.childNodes;
1439      return Optional.from(cs[index]).map(SugarElement.fromDom);
1440    };
1441    var firstChild = function (element) {
1442      return child(element, 0);
1443    };
1444    var lastChild = function (element) {
1445      return child(element, element.dom.childNodes.length - 1);
1446    };
1447    var childNodesCount = function (element) {
1448      return element.dom.childNodes.length;
1449    };
1450
1451    var getHead = function (doc) {
1452      var b = doc.dom.head;
1453      if (b === null || b === undefined) {
1454        throw new Error('Head is not available yet');
1455      }
1456      return SugarElement.fromDom(b);
1457    };
1458
1459    var isShadowRoot = function (dos) {
1460      return isDocumentFragment(dos);
1461    };
1462    var supported = isFunction(Element.prototype.attachShadow) && isFunction(Node.prototype.getRootNode);
1463    var isSupported = constant(supported);
1464    var getRootNode = supported ? function (e) {
1465      return SugarElement.fromDom(e.dom.getRootNode());
1466    } : documentOrOwner;
1467    var getStyleContainer = function (dos) {
1468      return isShadowRoot(dos) ? dos : getHead(documentOrOwner(dos));
1469    };
1470    var getShadowRoot = function (e) {
1471      var r = getRootNode(e);
1472      return isShadowRoot(r) ? Optional.some(r) : Optional.none();
1473    };
1474    var getShadowHost = function (e) {
1475      return SugarElement.fromDom(e.dom.host);
1476    };
1477    var getOriginalEventTarget = function (event) {
1478      if (isSupported() && isNonNullable(event.target)) {
1479        var el = SugarElement.fromDom(event.target);
1480        if (isElement(el) && isOpenShadowHost(el)) {
1481          if (event.composed && event.composedPath) {
1482            var composedPath = event.composedPath();
1483            if (composedPath) {
1484              return head(composedPath);
1485            }
1486          }
1487        }
1488      }
1489      return Optional.from(event.target);
1490    };
1491    var isOpenShadowHost = function (element) {
1492      return isNonNullable(element.dom.shadowRoot);
1493    };
1494
1495    var before = function (marker, element) {
1496      var parent$1 = parent(marker);
1497      parent$1.each(function (v) {
1498        v.dom.insertBefore(element.dom, marker.dom);
1499      });
1500    };
1501    var after = function (marker, element) {
1502      var sibling = nextSibling(marker);
1503      sibling.fold(function () {
1504        var parent$1 = parent(marker);
1505        parent$1.each(function (v) {
1506          append(v, element);
1507        });
1508      }, function (v) {
1509        before(v, element);
1510      });
1511    };
1512    var prepend = function (parent, element) {
1513      var firstChild$1 = firstChild(parent);
1514      firstChild$1.fold(function () {
1515        append(parent, element);
1516      }, function (v) {
1517        parent.dom.insertBefore(element.dom, v.dom);
1518      });
1519    };
1520    var append = function (parent, element) {
1521      parent.dom.appendChild(element.dom);
1522    };
1523    var wrap = function (element, wrapper) {
1524      before(element, wrapper);
1525      append(wrapper, element);
1526    };
1527
1528    var before$1 = function (marker, elements) {
1529      each(elements, function (x) {
1530        before(marker, x);
1531      });
1532    };
1533    var append$1 = function (parent, elements) {
1534      each(elements, function (x) {
1535        append(parent, x);
1536      });
1537    };
1538
1539    var empty = function (element) {
1540      element.dom.textContent = '';
1541      each(children(element), function (rogue) {
1542        remove(rogue);
1543      });
1544    };
1545    var remove = function (element) {
1546      var dom = element.dom;
1547      if (dom.parentNode !== null) {
1548        dom.parentNode.removeChild(dom);
1549      }
1550    };
1551    var unwrap = function (wrapper) {
1552      var children$1 = children(wrapper);
1553      if (children$1.length > 0) {
1554        before$1(wrapper, children$1);
1555      }
1556      remove(wrapper);
1557    };
1558
1559    var inBody = function (element) {
1560      var dom = isText(element) ? element.dom.parentNode : element.dom;
1561      if (dom === undefined || dom === null || dom.ownerDocument === null) {
1562        return false;
1563      }
1564      var doc = dom.ownerDocument;
1565      return getShadowRoot(SugarElement.fromDom(dom)).fold(function () {
1566        return doc.body.contains(dom);
1567      }, compose1(inBody, getShadowHost));
1568    };
1569
1570    var r = function (left, top) {
1571      var translate = function (x, y) {
1572        return r(left + x, top + y);
1573      };
1574      return {
1575        left: left,
1576        top: top,
1577        translate: translate
1578      };
1579    };
1580    var SugarPosition = r;
1581
1582    var boxPosition = function (dom) {
1583      var box = dom.getBoundingClientRect();
1584      return SugarPosition(box.left, box.top);
1585    };
1586    var firstDefinedOrZero = function (a, b) {
1587      if (a !== undefined) {
1588        return a;
1589      } else {
1590        return b !== undefined ? b : 0;
1591      }
1592    };
1593    var absolute = function (element) {
1594      var doc = element.dom.ownerDocument;
1595      var body = doc.body;
1596      var win = doc.defaultView;
1597      var html = doc.documentElement;
1598      if (body === element.dom) {
1599        return SugarPosition(body.offsetLeft, body.offsetTop);
1600      }
1601      var scrollTop = firstDefinedOrZero(win === null || win === void 0 ? void 0 : win.pageYOffset, html.scrollTop);
1602      var scrollLeft = firstDefinedOrZero(win === null || win === void 0 ? void 0 : win.pageXOffset, html.scrollLeft);
1603      var clientTop = firstDefinedOrZero(html.clientTop, body.clientTop);
1604      var clientLeft = firstDefinedOrZero(html.clientLeft, body.clientLeft);
1605      return viewport(element).translate(scrollLeft - clientLeft, scrollTop - clientTop);
1606    };
1607    var viewport = function (element) {
1608      var dom = element.dom;
1609      var doc = dom.ownerDocument;
1610      var body = doc.body;
1611      if (body === dom) {
1612        return SugarPosition(body.offsetLeft, body.offsetTop);
1613      }
1614      if (!inBody(element)) {
1615        return SugarPosition(0, 0);
1616      }
1617      return boxPosition(dom);
1618    };
1619
1620    var get$1 = function (_DOC) {
1621      var doc = _DOC !== undefined ? _DOC.dom : document;
1622      var x = doc.body.scrollLeft || doc.documentElement.scrollLeft;
1623      var y = doc.body.scrollTop || doc.documentElement.scrollTop;
1624      return SugarPosition(x, y);
1625    };
1626    var to = function (x, y, _DOC) {
1627      var doc = _DOC !== undefined ? _DOC.dom : document;
1628      var win = doc.defaultView;
1629      if (win) {
1630        win.scrollTo(x, y);
1631      }
1632    };
1633    var intoView = function (element, alignToTop) {
1634      var isSafari = detect$3().browser.isSafari();
1635      if (isSafari && isFunction(element.dom.scrollIntoViewIfNeeded)) {
1636        element.dom.scrollIntoViewIfNeeded(false);
1637      } else {
1638        element.dom.scrollIntoView(alignToTop);
1639      }
1640    };
1641
1642    var get$2 = function (_win) {
1643      var win = _win === undefined ? window : _win;
1644      return Optional.from(win['visualViewport']);
1645    };
1646    var bounds = function (x, y, width, height) {
1647      return {
1648        x: x,
1649        y: y,
1650        width: width,
1651        height: height,
1652        right: x + width,
1653        bottom: y + height
1654      };
1655    };
1656    var getBounds = function (_win) {
1657      var win = _win === undefined ? window : _win;
1658      var doc = win.document;
1659      var scroll = get$1(SugarElement.fromDom(doc));
1660      return get$2(win).fold(function () {
1661        var html = win.document.documentElement;
1662        var width = html.clientWidth;
1663        var height = html.clientHeight;
1664        return bounds(scroll.left, scroll.top, width, height);
1665      }, function (visualViewport) {
1666        return bounds(Math.max(visualViewport.pageLeft, scroll.left), Math.max(visualViewport.pageTop, scroll.top), visualViewport.width, visualViewport.height);
1667      });
1668    };
1669
1670    var isNodeType = function (type) {
1671      return function (node) {
1672        return !!node && node.nodeType === type;
1673      };
1674    };
1675    var isRestrictedNode = function (node) {
1676      return !!node && !Object.getPrototypeOf(node);
1677    };
1678    var isElement$1 = isNodeType(1);
1679    var matchNodeNames = function (names) {
1680      var lowercasedNames = names.map(function (s) {
1681        return s.toLowerCase();
1682      });
1683      return function (node) {
1684        if (node && node.nodeName) {
1685          var nodeName = node.nodeName.toLowerCase();
1686          return contains(lowercasedNames, nodeName);
1687        }
1688        return false;
1689      };
1690    };
1691    var matchStyleValues = function (name, values) {
1692      var items = values.toLowerCase().split(' ');
1693      return function (node) {
1694        var i, cssValue;
1695        if (isElement$1(node)) {
1696          for (i = 0; i < items.length; i++) {
1697            var computed = node.ownerDocument.defaultView.getComputedStyle(node, null);
1698            cssValue = computed ? computed.getPropertyValue(name) : null;
1699            if (cssValue === items[i]) {
1700              return true;
1701            }
1702          }
1703        }
1704        return false;
1705      };
1706    };
1707    var hasAttribute = function (attrName) {
1708      return function (node) {
1709        return isElement$1(node) && node.hasAttribute(attrName);
1710      };
1711    };
1712    var hasAttributeValue = function (attrName, attrValue) {
1713      return function (node) {
1714        return isElement$1(node) && node.getAttribute(attrName) === attrValue;
1715      };
1716    };
1717    var isBogus = function (node) {
1718      return isElement$1(node) && node.hasAttribute('data-mce-bogus');
1719    };
1720    var isBogusAll = function (node) {
1721      return isElement$1(node) && node.getAttribute('data-mce-bogus') === 'all';
1722    };
1723    var isTable = function (node) {
1724      return isElement$1(node) && node.tagName === 'TABLE';
1725    };
1726    var hasContentEditableState = function (value) {
1727      return function (node) {
1728        if (isElement$1(node)) {
1729          if (node.contentEditable === value) {
1730            return true;
1731          }
1732          if (node.getAttribute('data-mce-contenteditable') === value) {
1733            return true;
1734          }
1735        }
1736        return false;
1737      };
1738    };
1739    var isTextareaOrInput = matchNodeNames([
1740      'textarea',
1741      'input'
1742    ]);
1743    var isText$1 = isNodeType(3);
1744    var isComment$1 = isNodeType(8);
1745    var isDocument$1 = isNodeType(9);
1746    var isDocumentFragment$1 = isNodeType(11);
1747    var isBr = matchNodeNames(['br']);
1748    var isImg = matchNodeNames(['img']);
1749    var isContentEditableTrue = hasContentEditableState('true');
1750    var isContentEditableFalse = hasContentEditableState('false');
1751    var isTableCell = matchNodeNames([
1752      'td',
1753      'th'
1754    ]);
1755    var isMedia = matchNodeNames([
1756      'video',
1757      'audio',
1758      'object',
1759      'embed'
1760    ]);
1761
1762    var isSupported$1 = function (dom) {
1763      return dom.style !== undefined && isFunction(dom.style.getPropertyValue);
1764    };
1765
1766    var rawSet = function (dom, key, value) {
1767      if (isString(value) || isBoolean(value) || isNumber(value)) {
1768        dom.setAttribute(key, value + '');
1769      } else {
1770        console.error('Invalid call to Attribute.set. Key ', key, ':: Value ', value, ':: Element ', dom);
1771        throw new Error('Attribute value was not simple');
1772      }
1773    };
1774    var set = function (element, key, value) {
1775      rawSet(element.dom, key, value);
1776    };
1777    var setAll = function (element, attrs) {
1778      var dom = element.dom;
1779      each$1(attrs, function (v, k) {
1780        rawSet(dom, k, v);
1781      });
1782    };
1783    var get$3 = function (element, key) {
1784      var v = element.dom.getAttribute(key);
1785      return v === null ? undefined : v;
1786    };
1787    var getOpt = function (element, key) {
1788      return Optional.from(get$3(element, key));
1789    };
1790    var has$1 = function (element, key) {
1791      var dom = element.dom;
1792      return dom && dom.hasAttribute ? dom.hasAttribute(key) : false;
1793    };
1794    var remove$1 = function (element, key) {
1795      element.dom.removeAttribute(key);
1796    };
1797    var clone = function (element) {
1798      return foldl(element.dom.attributes, function (acc, attr) {
1799        acc[attr.name] = attr.value;
1800        return acc;
1801      }, {});
1802    };
1803
1804    var internalSet = function (dom, property, value) {
1805      if (!isString(value)) {
1806        console.error('Invalid call to CSS.set. Property ', property, ':: Value ', value, ':: Element ', dom);
1807        throw new Error('CSS value must be a string: ' + value);
1808      }
1809      if (isSupported$1(dom)) {
1810        dom.style.setProperty(property, value);
1811      }
1812    };
1813    var setAll$1 = function (element, css) {
1814      var dom = element.dom;
1815      each$1(css, function (v, k) {
1816        internalSet(dom, k, v);
1817      });
1818    };
1819    var get$4 = function (element, property) {
1820      var dom = element.dom;
1821      var styles = window.getComputedStyle(dom);
1822      var r = styles.getPropertyValue(property);
1823      return r === '' && !inBody(element) ? getUnsafeProperty(dom, property) : r;
1824    };
1825    var getUnsafeProperty = function (dom, property) {
1826      return isSupported$1(dom) ? dom.style.getPropertyValue(property) : '';
1827    };
1828    var getRaw = function (element, property) {
1829      var dom = element.dom;
1830      var raw = getUnsafeProperty(dom, property);
1831      return Optional.from(raw).filter(function (r) {
1832        return r.length > 0;
1833      });
1834    };
1835    var getAllRaw = function (element) {
1836      var css = {};
1837      var dom = element.dom;
1838      if (isSupported$1(dom)) {
1839        for (var i = 0; i < dom.style.length; i++) {
1840          var ruleName = dom.style.item(i);
1841          css[ruleName] = dom.style[ruleName];
1842        }
1843      }
1844      return css;
1845    };
1846    var reflow = function (e) {
1847      return e.dom.offsetWidth;
1848    };
1849
1850    var browser$1 = detect$3().browser;
1851    var firstElement = function (nodes) {
1852      return find(nodes, isElement);
1853    };
1854    var getTableCaptionDeltaY = function (elm) {
1855      if (browser$1.isFirefox() && name(elm) === 'table') {
1856        return firstElement(children(elm)).filter(function (elm) {
1857          return name(elm) === 'caption';
1858        }).bind(function (caption) {
1859          return firstElement(nextSiblings(caption)).map(function (body) {
1860            var bodyTop = body.dom.offsetTop;
1861            var captionTop = caption.dom.offsetTop;
1862            var captionHeight = caption.dom.offsetHeight;
1863            return bodyTop <= captionTop ? -captionHeight : 0;
1864          });
1865        }).getOr(0);
1866      } else {
1867        return 0;
1868      }
1869    };
1870    var hasChild = function (elm, child) {
1871      return elm.children && contains(elm.children, child);
1872    };
1873    var getPos = function (body, elm, rootElm) {
1874      var x = 0, y = 0, offsetParent;
1875      var doc = body.ownerDocument;
1876      var pos;
1877      rootElm = rootElm ? rootElm : body;
1878      if (elm) {
1879        if (rootElm === body && elm.getBoundingClientRect && get$4(SugarElement.fromDom(body), 'position') === 'static') {
1880          pos = elm.getBoundingClientRect();
1881          x = pos.left + (doc.documentElement.scrollLeft || body.scrollLeft) - doc.documentElement.clientLeft;
1882          y = pos.top + (doc.documentElement.scrollTop || body.scrollTop) - doc.documentElement.clientTop;
1883          return {
1884            x: x,
1885            y: y
1886          };
1887        }
1888        offsetParent = elm;
1889        while (offsetParent && offsetParent !== rootElm && offsetParent.
1889nodeType && !hasChild(offsetParent, rootElm)) {
1890          x += offsetParent.offsetLeft || 0;
1891          y += offsetParent.offsetTop || 0;
1892          offsetParent = offsetParent.offsetParent;
1893        }
1894        offsetParent = elm.parentNode;
1895        while (offsetParent && offsetParent !== rootElm && offsetParent.nodeType && !hasChild(offsetParent, rootElm)) {
1896          x -= offsetParent.scrollLeft || 0;
1897          y -= offsetParent.scrollTop || 0;
1898          offsetParent = offsetParent.parentNode;
1899        }
1900        y += getTableCaptionDeltaY(SugarElement.fromDom(elm));
1901      }
1902      return {
1903        x: x,
1904        y: y
1905      };
1906    };
1907
1908    var exports$1 = {}, module$1 = { exports: exports$1 };
1909    (function (define, exports, module, require) {
1910      (function (f) {
1911        if (typeof exports === 'object' && typeof module !== 'undefined') {
1912          module.exports = f();
1913        } else if (typeof define === 'function' && define.amd) {
1914          define([], f);
1915        } else {
1916          var g;
1917          if (typeof window !== 'undefined') {
1918            g = window;
1919          } else if (typeof global !== 'undefined') {
1920            g = global;
1921          } else if (typeof self !== 'undefined') {
1922            g = self;
1923          } else {
1924            g = this;
1925          }
1926          g.EphoxContactWrapper = f();
1927        }
1928      }(function () {
1929        return function () {
1930          function r(e, n, t) {
1931            function o(i, f) {
1932              if (!n[i]) {
1933                if (!e[i]) {
1934                  var c = 'function' == typeof require && require;
1935                  if (!f && c)
1936                    return c(i, !0);
1937                  if (u)
1938                    return u(i, !0);
1939                  var a = new Error('Cannot find module \'' + i + '\'');
1940                  throw a.code = 'MODULE_NOT_FOUND', a;
1941                }
1942                var p = n[i] = { exports: {} };
1943                e[i][0].call(p.exports, function (r) {
1944                  var n = e[i][1][r];
1945                  return o(n || r);
1946                }, p, p.exports, r, e, n, t);
1947              }
1948              return n[i].exports;
1949            }
1950            for (var u = 'function' == typeof require && require, i = 0; i < t.length; i++)
1951              o(t[i]);
1952            return o;
1953          }
1954          return r;
1955        }()({
1956          1: [
1957            function (require, module, exports) {
1958              var process = module.exports = {};
1959              var cachedSetTimeout;
1960              var cachedClearTimeout;
1961              function defaultSetTimout() {
1962                throw new Error('setTimeout has not been defined');
1963              }
1964              function defaultClearTimeout() {
1965                throw new Error('clearTimeout has not been defined');
1966              }
1967              (function () {
1968                try {
1969                  if (typeof setTimeout === 'function') {
1970                    cachedSetTimeout = setTimeout;
1971                  } else {
1972                    cachedSetTimeout = defaultSetTimout;
1973                  }
1974                } catch (e) {
1975                  cachedSetTimeout = defaultSetTimout;
1976                }
1977                try {
1978                  if (typeof clearTimeout === 'function') {
1979                    cachedClearTimeout = clearTimeout;
1980                  } else {
1981                    cachedClearTimeout = defaultClearTimeout;
1982                  }
1983                } catch (e) {
1984                  cachedClearTimeout = defaultClearTimeout;
1985                }
1986              }());
1987              function runTimeout(fun) {
1988                if (cachedSetTimeout === setTimeout) {
1989                  return setTimeout(fun, 0);
1990                }
1991                if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
1992                  cachedSetTimeout = setTimeout;
1993                  return setTimeout(fun, 0);
1994                }
1995                try {
1996                  return cachedSetTimeout(fun, 0);
1997                } catch (e) {
1998                  try {
1999                    return cachedSetTimeout.call(null, fun, 0);
2000                  } catch (e) {
2001                    return cachedSetTimeout.call(this, fun, 0);
2002                  }
2003                }
2004              }
2005              function runClearTimeout(marker) {
2006                if (cachedClearTimeout === clearTimeout) {
2007                  return clearTimeout(marker);
2008                }
2009                if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
2010                  cachedClearTimeout = clearTimeout;
2011                  return clearTimeout(marker);
2012                }
2013                try {
2014                  return cachedClearTimeout(marker);
2015                } catch (e) {
2016                  try {
2017                    return cachedClearTimeout.call(null, marker);
2018                  } catch (e) {
2019                    return cachedClearTimeout.call(this, marker);
2020                  }
2021                }
2022              }
2023              var queue = [];
2024              var draining = false;
vendor: 7,428 bytes, lines 2025-2212
2025              var currentQueue;
2026              var queueIndex = -1;
2027              function cleanUpNextTick() {
2028                if (!draining || !currentQueue) {
2029                  return;
2030                }
2031                draining = false;
2032                if (currentQueue.length) {
2033                  queue = currentQueue.concat(queue);
2034                } else {
2035                  queueIndex = -1;
2036                }
2037                if (queue.length) {
2038                  drainQueue();
2039                }
2040              }
2041              function drainQueue() {
2042                if (draining) {
2043                  return;
2044                }
2045                var timeout = runTimeout(cleanUpNextTick);
2046                draining = true;
2047                var len = queue.length;
2048                while (len) {
2049                  currentQueue = queue;
2050                  queue = [];
2051                  while (++queueIndex < len) {
2052                    if (currentQueue) {
2053                      currentQueue[queueIndex].run();
2054                    }
2055                  }
2056                  queueIndex = -1;
2057                  len = queue.length;
2058                }
2059                currentQueue = null;
2060                draining = false;
2061                runClearTimeout(timeout);
2062              }
2063              process.nextTick = function (fun) {
2064                var args = new Array(arguments.length - 1);
2065                if (arguments.length > 1) {
2066                  for (var i = 1; i < arguments.length; i++) {
2067                    args[i - 1] = arguments[i];
2068                  }
2069                }
2070                queue.push(new Item(fun, args));
2071                if (queue.length === 1 && !draining) {
2072                  runTimeout(drainQueue);
2073                }
2074              };
2075              function Item(fun, array) {
2076                this.fun = fun;
2077                this.array = array;
2078              }
2079              Item.prototype.run = function () {
2080                this.fun.apply(null, this.array);
2081              };
2082              process.title = 'browser';
2083              process.browser = true;
2084              process.env = {};
2085              process.argv = [];
2086              process.version = '';
2087              process.versions = {};
2088              function noop() {
2089              }
2090              process.on = noop;
2091              process.addListener = noop;
2092              process.once = noop;
2093              process.off = noop;
2094              process.removeListener = noop;
2095              process.removeAllListeners = noop;
2096              process.emit = noop;
2097              process.prependListener = noop;
2098              process.prependOnceListener = noop;
2099              process.listeners = function (name) {
2100                return [];
2101              };
2102              process.binding = function (name) {
2103                throw new Error('process.binding is not supported');
2104              };
2105              process.cwd = function () {
2106                return '/';
2107              };
2108              process.chdir = function (dir) {
2109                throw new Error('process.chdir is not supported');
2110              };
2111              process.umask = function () {
2112                return 0;
2113              };
2114            },
2115            {}
2116          ],
2117          2: [
2118            function (require, module, exports) {
2119              (function (setImmediate) {
2120                (function (root) {
2121                  var setTimeoutFunc = setTimeout;
2122                  function noop() {
2123                  }
2124                  function bind(fn, thisArg) {
2125                    return function () {
2126                      fn.apply(thisArg, arguments);
2127                    };
2128                  }
2129                  function Promise(fn) {
2130                    if (typeof this !== 'object')
2131                      throw new TypeError('Promises must be constructed via new');
2132                    if (typeof fn !== 'function')
2133                      throw new TypeError('not a function');
2134                    this._state = 0;
2135                    this._handled = false;
2136                    this._value = undefined;
2137                    this._deferreds = [];
2138                    doResolve(fn, this);
2139                  }
2140                  function handle(self, deferred) {
2141                    while (self._state === 3) {
2142                      self = self._value;
2143                    }
2144                    if (self._state === 0) {
2145                      self._deferreds.push(deferred);
2146                      return;
2147                    }
2148                    self._handled = true;
2149                    Promise._immediateFn(function () {
2150                      var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;
2151                      if (cb === null) {
2152                        (self._state === 1 ? resolve : reject)(deferred.promise, self._value);
2153                        return;
2154                      }
2155                      var ret;
2156                      try {
2157                        ret = cb(self._value);
2158                      } catch (e) {
2159                        reject(deferred.promise, e);
2160                        return;
2161                      }
2162                      resolve(deferred.promise, ret);
2163                    });
2164                  }
2165                  function resolve(self, newValue) {
2166                    try {
2167                      if (newValue === self)
2168                        throw new TypeError('A promise cannot be resolved with itself.');
2169                      if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {
2170                        var then = newValue.then;
2171                        if (newValue instanceof Promise) {
2172                          self._state = 3;
2173                          self._value = newValue;
2174                          finale(self);
2175                          return;
2176                        } else if (typeof then === 'function') {
2177                          doResolve(bind(then, newValue), self);
2178                          return;
2179                        }
2180                      }
2181                      self._state = 1;
2182                      self._value = newValue;
2183                      finale(self);
2184                    } catch (e) {
2185                      reject(self, e);
2186                    }
2187                  }
2188                  function reject(self, newValue) {
2189                    self._state = 2;
2190                    self._value = newValue;
2191                    finale(self);
2192                  }
2193                  function finale(self) {
2194                    if (self._state === 2 && self._deferreds.length === 0) {
2195                      Promise._immediateFn(function () {
2196                        if (!self._handled) {
2197                          Promise._unhandledRejectionFn(self._value);
2198                        }
2199                      });
2200                    }
2201                    for (var i = 0, len = self._deferreds.length; i < len; i++) {
2202                      handle(self, self._deferreds[i]);
2203                    }
2204                    self._deferreds = null;
2205                  }
2206                  function Handler(onFulfilled, onRejected, promise) {
2207                    this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
2208                    this.onRejected = typeof onRejected === 'function' ? onRejected : null;
2209                    this.promise = promise;
2210                  }
2211                  function doResolve(fn, self) {
2212                    var done = false;
2213                    try {
2214                      fn(function (value) {
2215                        if (done)
2216                          return;
2217                        done = true;
2218                        resolve(self, value);
2219                      }, function (reason) {
2220                        if (done)
2221                          return;
2222                        done = true;
2223                        reject(self, reason);
2224                      });
2225                    } catch (ex) {
2226                      if (done)
2227                        return;
2228                      done = true;
2229                      reject(self, ex);
2230                    }
2231                  }
2232                  Promise.prototype['catch'] = function (onRejected) {
2233                    return this.then(null, onRejected);
2234                  };
2235                  Promise.prototype.then = function (onFulfilled, onRejected) {
2236                    var prom = new this.constructor(noop);
2237                    handle(this, new Handler(onFulfilled, onRejected, prom));
2238                    return prom;
2239                  };
2240                  Promise.all = function (arr) {
2241                    var args = Array.prototype.slice.call(arr);
2242                    return new Promise(function (resolve, reject) {
2243                      if (args.length === 0)
2244                        return resolve([]);
2245                      var remaining = args.length;
2246                      function res(i, val) {
2247                        try {
2248                          if (val && (typeof val === 'object' || typeof val === 'function')) {
2249                            var then = val.then;
2250                            if (typeof then === 'function') {
2251                              then.call(val, function (val) {
2252                                res(i, val);
2253                              }, reject);
2254                              return;
2255                            }
2256                          }
2257                          args[i] = val;
2258                          if (--remaining === 0) {
2259                            resolve(args);
2260                          }
2261                        } catch (ex) {
2262                          reject(ex);
2263                        }
2264                      }
2265                      for (var i = 0; i < args.length; i++) {
2266                        res(i, args[i]);
2267                      }
2268                    });
2269                  };
2270                  Promise.resolve = function (value) {
2271                    if (value && typeof value === 'object' && value.constructor === Promise) {
2272                      return value;
2273                    }
2274                    return new Promise(function (resolve) {
2275                      resolve(value);
2276                    });
2277                  };
2278                  Promise.reject = function (value) {
2279                    return new Promise(function (resolve, reject) {
2280                      reject(value);
2281                    });
2282                  };
2283                  Promise.race = function (values) {
2284                    return new Promise(function (resolve, reject) {
2285                      for (var i = 0, len = values.length; i < len; i++) {
2286                        values[i].then(resolve, reject);
2287                      }
2288                    });
2289                  };
2290                  Promise._immediateFn = typeof setImmediate === 'function' ? function (fn) {
2291                    setImmediate(fn);
2292                  } : function (fn) {
2293                    setTimeoutFunc(fn, 0);
2294                  };
2295                  Promise._unhandledRejectionFn = function _unhandledRejectionFn(err) {
2296                    if (typeof console !== 'undefined' && console) {
2297                      console.warn('Possible Unhandled Promise Rejection:', err);
2298                    }
2299                  };
2300                  Promise._setImmediateFn = function _setImmediateFn(fn) {
2301                    Promise._immediateFn = fn;
2302                  };
2303                  Promise._setUnhandledRejectionFn = function _setUnhandledRejectionFn(fn) {
2304                    Promise._unhandledRejectionFn = fn;
2305                  };
2306                  if (typeof module !== 'undefined' && module.exports) {
2307                    module.exports = Promise;
2308                  } else if (!root.Promise) {
2309                    root.Promise = Promise;
2310                  }
2311                }(this));
2312              }.call(this, require('timers').setImmediate));
2313            },
2314            { 'timers': 3 }
2315          ],
2316          3: [
2317            function (require, module, exports) {
2318              (function (setImmediate, clearImmediate) {
2319                var nextTick = require('process/browser.js').nextTick;
2320                var apply = Function.prototype.apply;
2321                var slice = Array.prototype.slice;
2322                var immediateIds = {};
2323                var nextImmediateId = 0;
2324                exports.setTimeout = function () {
2325                  return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout);
2326                };
2327                exports.setInterval = function () {
2328                  return new Timeout(apply.call(setInterval, window, arguments), clearInterval);
2329                };
2330                exports.clearTimeout = exports.clearInterval = function (timeout) {
2331                  timeout.close();
2332                };
2333                function Timeout(id, clearFn) {
2334                  this._id = id;
2335                  this._clearFn = clearFn;
2336                }
2337                Timeout.prototype.unref = Timeout.prototype.ref = function () {
2338                };
2339                Timeout.prototype.close = function () {
2340                  this._clearFn.call(window, this._id);
2341                };
2342                exports.enroll = function (item, msecs) {
2343                  clearTimeout(item._idleTimeoutId);
2344                  item._idleTimeout = msecs;
2345                };
2346                exports.unenroll = function (item) {
2347                  clearTimeout(item._idleTimeoutId);
2348                  item._idleTimeout = -1;
2349                };
2350                exports._unrefActive = exports.active = function (item) {
2351                  clearTimeout(item._idleTimeoutId);
2352                  var msecs = item._idleTimeout;
2353                  if (msecs >= 0) {
2354                    item._idleTimeoutId = setTimeout(function onTimeout() {
2355                      if (item._onTimeout)
2356                        item._onTimeout();
2357                    }, msecs);
2358                  }
2359                };
2360                exports.setImmediate = typeof setImmediate === 'function' ? setImmediate : function (fn) {
2361                  var id = nextImmediateId++;
2362                  var args = arguments.length < 2 ? false : slice.call(arguments, 1);
2363                  immediateIds[id] = true;
2364                  nextTick(function onNextTick() {
2365                    if (immediateIds[id]) {
2366                      if (args) {
2367                        fn.apply(null, args);
2368                      } else {
2369                        fn.call(null);
2370                      }
2371                      exports.clearImmediate(id);
2372                    }
2373                  });
2374                  return id;
2375                };
2376                exports.clearImmediate = typeof clearImmediate === 'function' ? clearImmediate : function (id) {
2377                  delete immediateIds[id];
2378                };
2379              }.call(this, require('timers').setImmediate, require('timers').clearImmediate));
2380            },
2381            {
2382              'process/browser.js': 1,
2383              'timers': 3
2384            }
2385          ],
2386          4: [
2387            function (require, module, exports) {
2388              var promisePolyfill = require('promise-polyfill');
2389              var Global = function () {
2390                if (typeof window !== 'undefined') {
2391                  return window;
2392                } else {
2393                  return Function('return this;')();
2394                }
2395              }();
2396              module.exports = { boltExport: Global.Promise || promisePolyfill };
2397            },
2398            { 'promise-polyfill': 2 }
2399          ]
2400        }, {}, [4])(4);
2401      }));
2402    }(undefined, exports$1, module$1, undefined));
2403    var Promise = module$1.exports.boltExport;
2404
2405    var nu$3 = function (baseFn) {
2406      var data = Optional.none();
2407      var callbacks = [];
2408      var map = function (f) {
2409        return nu$3(function (nCallback) {
2410          get(function (data) {
2411            nCallback(f(data));
2412          });
2413        });
2414      };
2415      var get = function (nCallback) {
2416        if (isReady()) {
2417          call(nCallback);
2418        } else {
2419          callbacks.push(nCallback);
2420        }
2421      };
2422      var set = function (x) {
2423        if (!isReady()) {
2424          data = Optional.some(x);
2425          run(callbacks);
2426          callbacks = [];
2427        }
2428      };
2429      var isReady = function () {
2430        return data.isSome();
2431      };
2432      var run = function (cbs) {
2433        each(cbs, call);
2434      };
2435      var call = function (cb) {
2436        data.each(function (x) {
2437          setTimeout(function () {
2438            cb(x);
2439          }, 0);
2440        });
2441      };
2442      baseFn(set);
2443      return {
2444        get: get,
2445        map: map,
2446        isReady: isReady
2447      };
2448    };
2449    var pure = function (a) {
2450      return nu$3(function (callback) {
2451        callback(a);
2452      });
2453    };
2454    var LazyValue = {
2455      nu: nu$3,
2456      pure: pure
2457    };
2458
2459    var errorReporter = function (err) {
2460      setTimeout(function () {
2461        throw err;
2462      }, 0);
2463    };
2464    var make = function (run) {
2465      var get = function (callback) {
2466        run().then(callback, errorReporter);
2467      };
2468      var map = function (fab) {
2469        return make(function () {
2470          return run().then(fab);
2471        });
2472      };
2473      var bind = function (aFutureB) {
2474        return make(function () {
2475          return run().then(function (v) {
2476            return aFutureB(v).toPromise();
2477          });
2478        });
2479      };
2480      var anonBind = function (futureB) {
2481        return make(function () {
2482          return run().then(function () {
2483            return futureB.toPromise();
2484          });
2485        });
2486      };
2487      var toLazy = function () {
2488        return LazyValue.nu(get);
2489      };
2490      var toCached = function () {
2491        var cache = null;
2492        return make(function () {
2493          if (cache === null) {
2494            cache = run();
2495          }
2496          return cache;
2497        });
2498      };
2499      var toPromise = run;
2500      return {
2501        map: map,
2502        bind: bind,
2503        anonBind: anonBind,
2504        toLazy: toLazy,
2505        toCached: toCached,
2506        toPromise: toPromise,
2507        get: get
2508      };
2509    };
2510    var nu$4 = function (baseFn) {
2511      return make(function () {
2512        return new Promise(baseFn);
2513      });
2514    };
2515    var pure$1 = function (a) {
2516      return make(function () {
2517        return Promise.resolve(a);
2518      });
2519    };
2520    var Future = {
2521      nu: nu$4,
2522      pure: pure$1
2523    };
2524
2525    var par = function (asyncValues, nu) {
2526      return nu(function (callback) {
2527        var r = [];
2528        var count = 0;
2529        var cb = function (i) {
2530          return function (value) {
2531            r[i] = value;
2532            count++;
2533            if (count >= asyncValues.length) {
2534              callback(r);
2535            }
2536          };
2537        };
2538        if (asyncValues.length === 0) {
2539          callback([]);
2540        } else {
2541          each(asyncValues, function (asyncValue, i) {
2542            asyncValue.get(cb(i));
2543          });
2544        }
2545      });
2546    };
2547
2548    var par$1 = function (futures) {
2549      return par(futures, Future.nu);
2550    };
2551
2552    var value = function (o) {
2553      var is = function (v) {
2554        return o === v;
2555      };
2556      var or = function (_opt) {
2557        return value(o);
2558      };
2559      var orThunk = function (_f) {
2560        return value(o);
2561      };
2562      var map = function (f) {
2563        return value(f(o));
2564      };
2565      var mapError = function (_f) {
2566        return value(o);
2567      };
2568      var each = function (f) {
2569        f(o);
2570      };
2571      var bind = function (f) {
2572        return f(o);
2573      };
2574      var fold = function (_, onValue) {
2575        return onValue(o);
2576      };
2577      var exists = function (f) {
2578        return f(o);
2579      };
2580      var forall = function (f) {
2581        return f(o);
2582      };
2583      var toOptional = function () {
2584        return Optional.some(o);
2585      };
2586      return {
2587        is: is,
2588        isValue: always,
2589        isError: never,
2590        getOr: constant(o),
2591        getOrThunk: constant(o),
2592        getOrDie: constant(o),
2593        or: or,
2594        orThunk: orThunk,
2595        fold: fold,
2596        map: map,
2597        mapError: mapError,
2598        each: each,
2599        bind: bind,
2600        exists: exists,
2601        forall: forall,
2602        toOptional: toOptional
2603      };
2604    };
2605    var error = function (message) {
2606      var getOrThunk = function (f) {
2607        return f();
2608      };
2609      var getOrDie = function () {
2610        return die(String(message))();
2611      };
2612      var or = function (opt) {
2613        return opt;
2614      };
2615      var orThunk = function (f) {
2616        return f();
2617      };
2618      var map = function (_f) {
2619        return error(message);
2620      };
2621      var mapError = function (f) {
2622        return error(f(message));
2623      };
2624      var bind = function (_f) {
2625        return error(message);
2626      };
2627      var fold = function (onError, _) {
2628        return onError(message);
2629      };
2630      return {
2631        is: never,
2632        isValue: never,
2633        isError: always,
2634        getOr: identity,
2635        getOrThunk: getOrThunk,
2636        getOrDie: getOrDie,
2637        or: or,
2638        orThunk: orThunk,
2639        fold: fold,
2640        map: map,
2641        mapError: mapError,
2642        each: noop,
2643        bind: bind,
2644        exists: never,
2645        forall: always,
2646        toOptional: Optional.none
2647      };
2648    };
2649    var fromOption = function (opt, err) {
2650      return opt.fold(function () {
2651        return error(err);
2652      }, value);
2653    };
2654    var Result = {
2655      value: value,
2656      error: error,
2657      fromOption: fromOption
2658    };
2659
2660    var generate = function (cases) {
2661      if (!isArray(cases)) {
2662        throw new Error('cases must be an array');
2663      }
2664      if (cases.length === 0) {
2665        throw new Error('there must be at least one case');
2666      }
2667      var constructors = [];
2668      var adt = {};
2669      each(cases, function (acase, count) {
2670        var keys$1 = keys(acase);
2671        if (keys$1.length !== 1) {
2672          throw new Error('one and only one name per case');
2673        }
2674        var key = keys$1[0];
2675        var value = acase[key];
2676        if (adt[key] !== undefined) {
2677          throw new Error('duplicate key detected:' + key);
2678        } else if (key === 'cata') {
2679          throw new Error('cannot have a case named cata (sorry)');
2680        } else if (!isArray(value)) {
2681          throw new Error('case arguments must be an array');
2682        }
2683        constructors.push(key);
2684        adt[key] = function () {
2685          var argLength = arguments.length;
2686          if (argLength !== value.length) {
2687            throw new Error('Wrong number of arguments to case ' + key + '. Expected ' + value.length + ' (' + value + '), got ' + argLength);
2688          }
2689          var args = new Array(argLength);
2690          for (var i = 0; i < args.length; i++) {
2691            args[i] = arguments[i];
2692          }
2693          var match = function (branches) {
2694            var branchKeys = keys(branches);
2695            if (constructors.length !== branchKeys.length) {
2696              throw new Error('Wrong number of arguments to match. Expected: ' + constructors.join(',') + '\nActual: ' + branchKeys.join(','));
2697            }
2698            var allReqd = forall(constructors, function (reqKey) {
2699              return contains(branchKeys, reqKey);
2700            });
2701            if (!allReqd) {
2702              throw new Error('Not all branches were specified when using match. Specified: ' + branchKeys.join(', ') + '\nRequired: ' + constructors.join(', '));
2703            }
2704            return branches[key].apply(null, args);
2705          };
2706          return {
2707            fold: function () {
2708              if (arguments.length !== cases.length) {
2709                throw new Error('Wrong number of arguments to fold. Expected ' + cases.length + ', got ' + arguments.length);
2710              }
2711              var target = arguments[count];
2712              return target.apply(null, args);
2713            },
2714            match: match,
2715            log: function (label) {
2716              console.log(label, {
2717                constructors: constructors,
2718                constructor: key,
2719                params: args
2720              });
2721            }
2722          };
2723        };
2724      });
2725      return adt;
2726    };
2727    var Adt = { generate: generate };
2728
2729    var comparison = Adt.generate([
2730      {
2731        bothErrors: [
2732          'error1',
2733          'error2'
2734        ]
2735      },
2736      {
2737        firstError: [
2738          'error1',
2739          'value2'
2740        ]
2741      },
2742      {
2743        secondError: [
2744          'value1',
2745          'error2'
2746        ]
2747      },
2748      {
2749        bothValues: [
2750          'value1',
2751          'value2'
2752        ]
2753      }
2754    ]);
2755    var unite = function (result) {
2756      return result.fold(identity, identity);
2757    };
2758
2759    function ClosestOrAncestor (is, ancestor, scope, a, isRoot) {
2760      return is(scope, a) ? Optional.some(scope) : isFunction(isRoot) && isRoot(scope) ? Optional.none() : ancestor(scope, a, isRoot);
2761    }
2762
2763    var ancestor = function (scope, predicate, isRoot) {
2764      var element = scope.dom;
2765      var stop = isFunction(isRoot) ? isRoot : never;
2766      while (element.parentNode) {
2767        element = element.parentNode;
2768        var el = SugarElement.fromDom(element);
2769        if (predicate(el)) {
2770          return Optional.some(el);
2771        } else if (stop(el)) {
2772          break;
2773        }
2774      }
2775      return Optional.none();
2776    };
2777    var closest = function (scope, predicate, isRoot) {
2778      var is = function (s, test) {
2779        return test(s);
2780      };
2781      return ClosestOrAncestor(is, ancestor, scope, predicate, isRoot);
2782    };
2783
2784    var ancestor$1 = function (scope, selector, isRoot) {
2785      return ancestor(scope, function (e) {
2786        return is$1(e, selector);
2787      }, isRoot);
2788    };
2789    var descendant = function (scope, selector) {
2790      return one(selector, scope);
2791    };
2792    var closest$1 = function (scope, selector, isRoot) {
2793      var is = function (element, selector) {
2794        return is$1(element, selector);
2795      };
2796      return ClosestOrAncestor(is, ancestor$1, scope, selector, isRoot);
2797    };
2798
2799    var promise = function () {
2800      function bind(fn, thisArg) {
2801        return function () {
2802          fn.apply(thisArg, arguments);
2803        };
2804      }
2805      var isArray = Array.isArray || function (value) {
2806        return Object.prototype.toString.call(value) === '[object Array]';
2807      };
2808      var Promise = function (fn) {
2809        if (typeof this !== 'object') {
2810          throw new TypeError('Promises must be constructed via new');
2811        }
2812        if (typeof fn !== 'function') {
2813          throw new TypeError('not a function');
2814        }
2815        this._state = null;
2816        this._value = null;
2817        this._deferreds = [];
2818        doResolve(fn, bind(resolve, this), bind(reject, this));
2819      };
2820      var asap = Promise.immediateFn || typeof setImmediate === 'function' && setImmediate || function (fn) {
2821        setTimeout(fn, 1);
2822      };
2823      function handle(deferred) {
2824        var me = this;
2825        if (this._state === null) {
2826          this._deferreds.push(deferred);
2827          return;
2828        }
2829        asap(function () {
2830          var cb = me._state ? deferred.onFulfilled : deferred.onRejected;
2831          if (cb === null) {
2832            (me._state ? deferred.resolve : deferred.reject)(me._value);
2833            return;
2834          }
2835          var ret;
2836          try {
2837            ret = cb(me._value);
2838          } catch (e) {
2839            deferred.reject(e);
2840            return;
2841          }
2842          deferred.resolve(ret);
2843        });
2844      }
2845      function resolve(newValue) {
2846        try {
2847          if (newValue === this) {
2848            throw new TypeError('A promise cannot be resolved with itself.');
2849          }
2850          if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {
2851            var then = newValue.then;
2852            if (typeof then === 'function') {
2853              doResolve(bind(then, newValue), bind(resolve, this), bind(reject, this));
2854              return;
2855            }
2856          }
2857          this._state = true;
2858          this._value = newValue;
2859          finale.call(this);
2860        } catch (e) {
2861          reject.call(this, e);
2862        }
2863      }
2864      function reject(newValue) {
2865        this._state = false;
2866        this._value = newValue;
2867        finale.call(this);
2868      }
2869      function finale() {
2870        for (var i = 0, len = this._deferreds.length; i < len; i++) {
2871          handle.call(this, this._deferreds[i]);
2872        }
2873        this._deferreds = null;
2874      }
2875      function Handler(onFulfilled, onRejected, resolve, reject) {
2876        this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
2877        this.onRejected = typeof onRejected === 'function' ? onRejected : null;
2878        this.resolve = resolve;
2879        this.reject = reject;
2880      }
2881      function doResolve(fn, onFulfilled, onRejected) {
2882        var done = false;
2883        try {
2884          fn(function (value) {
2885            if (done) {
2886              return;
2887            }
2888            done = true;
2889            onFulfilled(value);
2890          }, function (reason) {
2891            if (done) {
2892              return;
2893            }
2894            done = true;
2895            onRejected(reason);
2896          });
2897        } catch (ex) {
2898          if (done) {
2899            return;
2900          }
2901          done = true;
2902          onRejected(ex);
2903        }
2904      }
2905      Promise.prototype.catch = function (onRejected) {
2906        return this.then(null, onRejected);
2907      };
2908      Promise.prototype.then = function (onFulfilled, onRejected) {
2909        var me = this;
2910        return new Promise(function (resolve, reject) {
2911          handle.call(me, new Handler(onFulfilled, onRejected, resolve, reject));
2912        });
2913      };
2914      Promise.all = function () {
2915        var args = Array.prototype.slice.call(arguments.length === 1 && isArray(arguments[0]) ? arguments[0] : arguments);
2916        return new Promise(function (resolve, reject) {
2917          if (args.length === 0) {
2918            return resolve([]);
2919          }
2920          var remaining = args.length;
2921          function res(i, val) {
2922            try {
2923              if (val && (typeof val === 'object' || typeof val === 'function')) {
2924                var then = val.then;
2925                if (typeof then === 'function') {
2926                  then.call(val, function (val) {
2927                    res(i, val);
2928                  }, reject);
2929                  return;
2930                }
2931              }
2932              args[i] = val;
2933              if (--remaining === 0) {
2934                resolve(args);
2935              }
2936            } catch (ex) {
2937              reject(ex);
2938            }
2939          }
2940          for (var i = 0; i < args.length; i++) {
2941            res(i, args[i]);
2942          }
2943        });
2944      };
2945      Promise.resolve = function (value) {
2946        if (value && typeof value === 'object' && value.constructor === Promise) {
2947          return value;
2948        }
2949        return new Promise(function (resolve) {
2950          resolve(value);
2951        });
2952      };
2953      Promise.reject = function (value) {
2954        return new Promise(function (resolve, reject) {
2955          reject(value);
2956        });
2957      };
2958      Promise.race = function (values) {
2959        return new Promise(function (resolve, reject) {
2960          for (var i = 0, len = values.length; i < len; i++) {
2961            values[i].then(resolve, reject);
2962          }
2963        });
2964      };
2965      return Promise;
2966    };
2967    var promiseObj = window.Promise ? window.Promise : promise();
2968
2969    var requestAnimationFramePromise;
2970    var requestAnimationFrame = function (callback, element) {
2971      var i, requestAnimationFrameFunc = window.requestAnimationFrame;
2972      var vendors = [
2973        'ms',
2974        'moz',
2975        'webkit'
2976      ];
2977      var featurefill = function (callback) {
2978        window.setTimeout(callback, 0);
2979      };
2980      for (i = 0; i < vendors.length && !requestAnimationFrameFunc; i++) {
2981        requestAnimationFrameFunc = window[vendors[i] + 'RequestAnimationFrame'];
2982      }
2983      if (!requestAnimationFrameFunc) {
2984        requestAnimationFrameFunc = featurefill;
2985      }
2986      requestAnimationFrameFunc(callback, element);
2987    };
2988    var wrappedSetTimeout = function (callback, time) {
2989      if (typeof time !== 'number') {
2990        time = 0;
2991      }
2992      return setTimeout(callback, time);
2993    };
2994    var wrappedSetInterval = function (callback, time) {
2995      if (typeof time !== 'number') {
2996        time = 1;
2997      }
2998      return setInterval(callback, time);
2999    };
3000    var wrappedClearTimeout = function (id) {
3001      return clearTimeout(id);
3002    };
3003    var wrappedClearInterval = function (id) {
3004      return clearInterval(id);
3005    };
3006    var debounce = function (callback, time) {
3007      var timer;
3008      var func = function () {
3009        var args = [];
3010        for (var _i = 0; _i < arguments.length; _i++) {
3011          args[_i] = arguments[_i];
3012        }
3013        clearTimeout(timer);
3014        timer = wrappedSetTimeout(function () {
3015          callback.apply(this, args);
3016        }, time);
3017      };
3018      func.stop = function () {
3019        clearTimeout(timer);
3020      };
3021      return func;
3022    };
3023    var Delay = {
3024      requestAnimationFrame: function (callback, element) {
3025        if (requestAnimationFramePromise) {
3026          requestAnimationFramePromise.then(callback);
3027          return;
3028        }
3029        requestAnimationFramePromise = new promiseObj(function (resolve) {
3030          if (!element) {
3031            element = document.body;
3032          }
3033          requestAnimationFrame(resolve, element);
3034        }).then(callback);
3035      },
3036      setTimeout: wrappedSetTimeout,
3037      setInterval: wrappedSetInterval,
3038      setEditorTimeout: function (editor, callback, time) {
3039        return wrappedSetTimeout(function () {
3040          if (!editor.removed) {
3041            callback();
3042          }
3043        }, time);
3044      },
3045      setEditorInterval: function (editor, callback, time) {
3046        var timer = wrappedSetInterval(function () {
3047          if (!editor.removed) {
3048            callback();
3049          } else {
3050            clearInterval(timer);
3051          }
3052        }, time);
3053        return timer;
3054      },
3055      debounce: debounce,
3056      throttle: debounce,
3057      clearInterval: wrappedClearInterval,
3058      clearTimeout: wrappedClearTimeout
3059    };
3060
3061    function StyleSheetLoader(documentOrShadowRoot, settings) {
3062      if (settings === void 0) {
3063        settings = {};
3064      }
3065      var idCount = 0;
3066      var loadedStates = {};
3067      var edos = SugarElement.fromDom(documentOrShadowRoot);
3068      var doc = documentOrOwner(edos);
3069      var maxLoadTime = settings.maxLoadTime || 5000;
3070      var _setReferrerPolicy = function (referrerPolicy) {
3071        settings.referrerPolicy = referrerPolicy;
3072      };
3073      var addStyle = function (element) {
3074        append(getStyleContainer(edos), element);
3075      };
3076      var removeStyle = function (id) {
3077        var styleContainer = getStyleContainer(edos);
3078        descendant(styleContainer, '#' + id).each(remove);
3079      };
3080      var getOrCreateState = function (url) {
3081        return get(loadedStates, url).getOrThunk(function () {
3082          return {
3083            id: 'mce-u' + idCount++,
3084            passed: [],
3085            failed: [],
3086            count: 0
3087          };
3088        });
3089      };
3090      var load = function (url, success, failure) {
3091        var link;
3092        var urlWithSuffix = Tools._addCacheSuffix(url);
3093        var state = getOrCreateState(urlWithSuffix);
3094        loadedStates[urlWithSuffix] = state;
3095        state.count++;
3096        var resolve = function (callbacks, status) {
3097          var i = callbacks.length;
3098          while (i--) {
3099            callbacks[i]();
3100          }
3101          state.status = status;
3102          state.passed = [];
3103          state.failed = [];
3104          if (link) {
3105            link.onload = null;
3106            link.onerror = null;
3107            link = null;
3108          }
3109        };
3110        var passed = function () {
3111          return resolve(state.passed, 2);
3112        };
3113        var failed = function () {
3114          return resolve(state.failed, 3);
3115        };
3116        var wait = function (testCallback, waitCallback) {
3117          if (!testCallback()) {
3118            if (Date.now() - startTime < maxLoadTime) {
3119              Delay.setTimeout(waitCallback);
3120            } else {
3121              failed();
3122            }
3123          }
3124        };
3125        var waitForWebKitLinkLoaded = function () {
3126          wait(function () {
3127            var styleSheets = documentOrShadowRoot.styleSheets;
3128            var i = styleSheets.length;
3129            while (i--) {
3130              var styleSheet = styleSheets[i];
3131              var owner = styleSheet.ownerNode;
3132              if (owner && owner.id === link.id) {
3133                passed();
3134                return true;
3135              }
3136            }
3137            return false;
3138          }, waitForWebKitLinkLoaded);
3139        };
3140        if (success) {
3141          state.passed.push(success);
3142        }
3143        if (failure) {
3144          state.failed.push(failure);
3145        }
3146        if (state.status === 1) {
3147          return;
3148        }
3149        if (state.status === 2) {
3150          passed();
3151          return;
3152        }
3153        if (state.status === 3) {
3154          failed();
3155          return;
3156        }
3157        state.status = 1;
3158        var linkElem = SugarElement.fromTag('link', doc.dom);
3159        setAll(linkElem, {
3160          rel: 'stylesheet',
3161          type: 'text/css',
3162          id: state.id
3163        });
3164        var startTime = Date.now();
3165        if (settings.contentCssCors) {
3166          set(linkElem, 'crossOrigin', 'anonymous');
3167        }
3168        if (settings.referrerPolicy) {
3169          set(linkElem, 'referrerpolicy', settings.referrerPolicy);
3170        }
3171        link = linkElem.dom;
3172        link.onload = waitForWebKitLinkLoaded;
3173        link.onerror = failed;
3174        addStyle(linkElem);
3175        set(linkElem, 'href', urlWithSuffix);
3176      };
3177      var loadF = function (url) {
3178        return Future.nu(function (resolve) {
3179          load(url, compose(resolve, constant(Result.value(url))), compose(resolve, constant(Result.error(url))));
3180        });
3181      };
3182      var loadAll = function (urls, success, failure) {
3183        par$1(map(urls, loadF)).get(function (result) {
3184          var parts = partition(result, function (r) {
3185            return r.isValue();
3186          });
3187          if (parts.fail.length > 0) {
3188            failure(parts.fail.map(unite));
3189          } else {
3190            success(parts.pass.map(unite));
3191          }
3192        });
3193      };
3194      var unload = function (url) {
3195        var urlWithSuffix = Tools._addCacheSuffix(url);
3196        get(loadedStates, urlWithSuffix).each(function (state) {
3197          var count = --state.count;
3198          if (count === 0) {
3199            delete loadedStates[urlWithSuffix];
3200            removeStyle(state.id);
3201          }
3202        });
3203      };
3204      var unloadAll = function (urls) {
3205        each(urls, function (url) {
3206          unload(url);
3207        });
3208      };
3209      return {
3210        load: load,
3211        loadAll: loadAll,
3212        unload: unload,
3213        unloadAll: unloadAll,
3214        _setReferrerPolicy: _setReferrerPolicy
3215      };
3216    }
3217
3218    var create$1 = function () {
3219      var map = new WeakMap();
3220      var forElement = function (referenceElement, settings) {
3221        var root = getRootNode(referenceElement);
3222        var rootDom = root.dom;
3223        return Optional.from(map.get(rootDom)).getOrThunk(function () {
3224          var sl = StyleSheetLoader(rootDom, settings);
3225          map.set(rootDom, sl);
3226          return sl;
3227        });
3228      };
3229      return { forElement: forElement };
3230    };
3231    var instance = create$1();
3232
3233    var DomTreeWalker = function () {
3234      function DomTreeWalker(startNode, rootNode) {
3235        this.node = startNode;
3236        this.rootNode = rootNode;
3237        this.current = this.current.bind(this);
3238        this.next = this.next.bind(this);
3239        this.prev = this.prev.bind(this);
3240        this.prev2 = this.prev2.bind(this);
3241      }
3242      DomTreeWalker.prototype.current = function () {
3243        return this.node;
3244      };
3245      DomTreeWalker.prototype.next = function (shallow) {
3246        this.node = this.findSibling(this.node, 'firstChild', 'nextSibling', shallow);
3247        return this.node;
3248      };
3249      DomTreeWalker.prototype.prev = function (shallow) {
3250        this.node = this.findSibling(this.node, 'lastChild', 'previousSibling', shallow);
3251        return this.node;
3252      };
3253      DomTreeWalker.prototype.prev2 = function (shallow) {
3254        this.node = this.findPreviousNode(this.node, 'lastChild', 'previousSibling', shallow);
3255        return this.node;
3256      };
3257      DomTreeWalker.prototype.findSibling = function (node, startName, siblingName, shallow) {
3258        var sibling, parent;
3259        if (node) {
3260          if (!shallow && node[startName]) {
3261            return node[startName];
3262          }
3263          if (node !== this.rootNode) {
3264            sibling = node[siblingName];
3265            if (sibling) {
3266              return sibling;
3267            }
3268            for (parent = node.parentNode; parent && parent !== this.rootNode; parent = parent.parentNode) {
3269              sibling = parent[siblingName];
3270              if (sibling) {
3271                return sibling;
3272              }
3273            }
3274          }
3275        }
3276      };
3277      DomTreeWalker.prototype.findPreviousNode = function (node, startName, siblingName, shallow) {
3278        var sibling, parent, child;
3279        if (node) {
3280          sibling = node[siblingName];
3281          if (this.rootNode && sibling === this.rootNode) {
3282            return;
3283          }
3284          if (sibling) {
3285            if (!shallow) {
3286              for (child = sibling[startName]; child; child = child[startName]) {
3287                if (!child[startName]) {
3288                  return child;
3289                }
3290              }
3291            }
3292            return sibling;
3293          }
3294          parent = node.parentNode;
3295          if (parent && parent !== this.rootNode) {
3296            return parent;
3297          }
3298        }
3299      };
3300      return DomTreeWalker;
3301    }();
3302
3303    var blocks = [
3304      'article',
3305      'aside',
3306      'details',
3307      'div',
3308      'dt',
3309      'figcaption',
3310      'footer',
3311      'form',
3312      'fieldset',
3313      'header',
3314      'hgroup',
3315      'html',
3316      'main',
3317      'nav',
3318      'section',
3319      'summary',
3320      'body',
3321      'p',
3322      'dl',
3323      'multicol',
3324      'dd',
3325      'figure',
3326      'address',
3327      'center',
3328      'blockquote',
3329      'h1',
3330      'h2',
3331      'h3',
3332      'h4',
3333      'h5',
3334      'h6',
3335      'listing',
3336      'xmp',
3337      'pre',
3338      'plaintext',
3339      'menu',
3340      'dir',
3341      'ul',
3342      'ol',
3343      'li',
3344      'hr',
3345      'table',
3346      'tbody',
3347      'thead',
3348      'tfoot',
3349      'th',
3350      'tr',
3351      'td',
3352      'caption'
3353    ];
3354    var tableCells = [
3355      'td',
3356      'th'
3357    ];
3358    var tableSections = [
3359      'thead',
3360      'tbody',
3361      'tfoot'
3362    ];
3363    var textBlocks = [
3364      'h1',
3365      'h2',
3366      'h3',
3367      'h4',
3368      'h5',
3369      'h6',
3370      'p',
3371      'div',
3372      'address',
3373      'pre',
3374      'form',
3375      'blockquote',
3376      'center',
3377      'dir',
3378      'fieldset',
3379      'header',
3380      'footer',
3381      'article',
3382      'section',
3383      'hgroup',
3384      'aside',
3385      'nav',
3386      'figure'
3387    ];
3388    var headings = [
3389      'h1',
3390      'h2',
3391      'h3',
3392      'h4',
3393      'h5',
3394      'h6'
3395    ];
3396    var listItems = [
3397      'li',
3398      'dd',
3399      'dt'
3400    ];
3401    var lists = [
3402      'ul',
3403      'ol',
3404      'dl'
3405    ];
3406    var wsElements = [
3407      'pre',
3408      'script',
3409      'textarea',
3410      'style'
3411    ];
3412    var lazyLookup = function (items) {
3413      var lookup;
3414      return function (node) {
3415        lookup = lookup ? lookup : mapToObject(items, always);
3416        return lookup.hasOwnProperty(name(node));
3417      };
3418    };
3419    var isHeading = lazyLookup(headings);
3420    var isBlock = lazyLookup(blocks);
3421    var isTable$1 = function (node) {
3422      return name(node) === 'table';
3423    };
3424    var isInline = function (node) {
3425      return isElement(node) && !isBlock(node);
3426    };
3427    var isBr$1 = function (node) {
3428      return isElement(node) && name(node) === 'br';
3429    };
3430    var isTextBlock = lazyLookup(textBlocks);
3431    var isList = lazyLookup(lists);
3432    var isListItem = lazyLookup(listItems);
3433    var isTableSection = lazyLookup(tableSections);
3434    var isTableCell$1 = lazyLookup(tableCells);
3435    var isWsPreserveElement = lazyLookup(wsElements);
3436
3437    var ancestor$2 = function (scope, selector, isRoot) {
3438      return ancestor$1(scope, selector, isRoot).isSome();
3439    };
3440
3441    var zeroWidth = '\uFEFF';
3442    var nbsp = '\xA0';
3443    var isZwsp = function (char) {
3444      return char === zeroWidth;
3445    };
3446    var removeZwsp = function (s) {
3447      return s.replace(/\uFEFF/g, '');
3448    };
3449
3450    var ZWSP = zeroWidth;
3451    var isZwsp$1 = isZwsp;
3452    var trim$2 = removeZwsp;
3453
3454    var isElement$2 = isElement$1;
3455    var isText$2 = isText$1;
3456    var isCaretContainerBlock = function (node) {
3457      if (isText$2(node)) {
3458        node = node.parentNode;
3459      }
3460      return isElement$2(node) && node.hasAttribute('data-mce-caret');
3461    };
3462    var isCaretContainerInline = function (node) {
3463      return isText$2(node) && isZwsp$1(node.data);
3464    };
3465    var isCaretContainer = function (node) {
3466      return isCaretContainerBlock(node) || isCaretContainerInline(node);
3467    };
3468    var hasContent = function (node) {
3469      return node.firstChild !== node.lastChild || !isBr(node.firstChild);
3470    };
3471    var insertInline = function (node, before) {
3472      var sibling;
3473      var doc = node.ownerDocument;
3474      var textNode = doc.createTextNode(ZWSP);
3475      var parentNode = node.parentNode;
3476      if (!before) {
3477        sibling = node.nextSibling;
3478        if (isText$2(sibling)) {
3479          if (isCaretContainer(sibling)) {
3480            return sibling;
3481          }
3482          if (startsWithCaretContainer(sibling)) {
3483            sibling.splitText(1);
3484            return sibling;
3485          }
3486        }
3487        if (node.nextSibling) {
3488          parentNode.insertBefore(textNode, node.nextSibling);
3489        } else {
3490          parentNode.appendChild(textNode);
3491        }
3492      } else {
3493        sibling = node.previousSibling;
3494        if (isText$2(sibling)) {
3495          if (isCaretContainer(sibling)) {
3496            return sibling;
3497          }
3498          if (endsWithCaretContainer(sibling)) {
3499            return sibling.splitText(sibling.data.length - 1);
3500          }
3501        }
3502        parentNode.insertBefore(textNode, node);
3503      }
3504      return textNode;
3505    };
3506    var isBeforeInline = function (pos) {
3507      var container = pos.container();
3508      if (!isText$1(container)) {
3509        return false;
3510      }
3511      return container.data.charAt(pos.offset()) === ZWSP || pos.isAtStart() && isCaretContainerInline(container.previousSibling);
3512    };
3513    var isAfterInline = function (pos) {
3514      var container = pos.container();
3515      if (!isText$1(container)) {
3516        return false;
3517      }
3518      return container.data.charAt(pos.offset() - 1) === ZWSP || pos.isAtEnd() && isCaretContainerInline(container.nextSibling);
3519    };
3520    var createBogusBr = function () {
3521      var br = document.createElement('br');
3522      br.setAttribute('data-mce-bogus', '1');
3523      return br;
3524    };
3525    var insertBlock = function (blockName, node, before) {
3526      var doc = node.ownerDocument;
3527      var blockNode = doc.createElement(blockName);
3528      blockNode.setAttribute('data-mce-caret', before ? 'before' : 'after');
3529      blockNode.setAttribute('data-mce-bogus', 'all');
3530      blockNode.appendChild(createBogusBr());
3531      var parentNode = node.parentNode;
3532      if (!before) {
3533        if (node.nextSibling) {
3534          parentNode.insertBefore(blockNode, node.nextSibling);
3535        } else {
3536          parentNode.appendChild(blockNode);
3537        }
3538      } else {
3539        parentNode.insertBefore(blockNode, node);
3540      }
3541      return blockNode;
3542    };
3543    var startsWithCaretContainer = function (node) {
3544      return isText$2(node) && node.data[0] === ZWSP;
3545    };
3546    var endsWithCaretContainer = function (node) {
3547      return isText$2(node) && node.data[node.data.length - 1] === ZWSP;
3548    };
3549    var trimBogusBr = function (elm) {
3550      var brs = elm.getElementsByTagName('br');
3551      var lastBr = brs[brs.length - 1];
3552      if (isBogus(lastBr)) {
3553        lastBr.parentNode.removeChild(lastBr);
3554      }
3555    };
3556    var showCaretContainerBlock = function (caretContainer) {
3557      if (caretContainer && caretContainer.hasAttribute('data-mce-caret')) {
3558        trimBogusBr(caretContainer);
3559        caretContainer.removeAttribute('data-mce-caret');
3560        caretContainer.removeAttribute('data-mce-bogus');
3561        caretContainer.removeAttribute('style');
3562        caretContainer.removeAttribute('_moz_abspos');
3563        return caretContainer;
3564      }
3565      return null;
3566    };
3567    var isRangeInCaretContainerBlock = function (range) {
3568      return isCaretContainerBlock(range.startContainer);
3569    };
3570
3571    var isContentEditableTrue$1 = isContentEditableTrue;
3572    var isContentEditableFalse$1 = isContentEditableFalse;
3573    var isBr$2 = isBr;
3574    var isText$3 = isText$1;
3575    var isInvalidTextElement = matchNodeNames([
3576      'script',
3577      'style',
3578      'textarea'
3579    ]);
3580    var isAtomicInline = matchNodeNames([
3581      'img',
3582      'input',
3583      'textarea',
3584      'hr',
3585      'iframe',
3586      'video',
3587      'audio',
3588      'object',
3589      'embed'
3590    ]);
3591    var isTable$2 = matchNodeNames(['table']);
3592    var isCaretContainer$1 = isCaretContainer;
3593    var isCaretCandidate = function (node) {
3594      if (isCaretContainer$1(node)) {
3595        return false;
3596      }
3597      if (isText$3(node)) {
3598        return !isInvalidTextElement(node.parentNode);
3599      }
3600      return isAtomicInline(node) || isBr$2(node) || isTable$2(node) || isNonUiContentEditableFalse(node);
3601    };
3602    var isUnselectable = function (node) {
3603      return isElement$1(node) && node.getAttribute('unselectable') === 'true';
3604    };
3605    var isNonUiContentEditableFalse = function (node) {
3606      return isUnselectable(node) === false && isContentEditableFalse$1(node);
3607    };
3608    var isInEditable = function (node, root) {
3609      for (node = node.parentNode; node && node !== root; node = node.parentNode) {
3610        if (isNonUiContentEditableFalse(node)) {
3611          return false;
3612        }
3613        if (isContentEditableTrue$1(node)) {
3614          return true;
3615        }
3616      }
3617      return true;
3618    };
3619    var isAtomicContentEditableFalse = function (node) {
3620      if (!isNonUiContentEditableFalse(node)) {
3621        return false;
3622      }
3623      return foldl(from$1(node.getElementsByTagName('*')), function (result, elm) {
3624        return result || isContentEditableTrue$1(elm);
3625      }, false) !== true;
3626    };
3627    var isAtomic = function (node) {
3628      return isAtomicInline(node) || isAtomicContentEditableFalse(node);
3629    };
3630    var isEditableCaretCandidate = function (node, root) {
3631      return isCaretCandidate(node) && isInEditable(node, root);
3632    };
3633
3634    var whiteSpaceRegExp$1 = /^[ \t\r\n]*$/;
3635    var isWhitespaceText = function (text) {
3636      return whiteSpaceRegExp$1.test(text);
3637    };
3638
3639    var hasWhitespacePreserveParent = function (node, rootNode) {
3640      var rootElement = SugarElement.fromDom(rootNode);
3641      var startNode = SugarElement.fromDom(node);
3642      return ancestor$2(startNode, 'pre,code', curry(eq$2, rootElement));
3643    };
3644    var isWhitespace = function (node, rootNode) {
3645      return isText$1(node) && isWhitespaceText(node.data) && hasWhitespacePreserveParent(node, rootNode) === false;
3646    };
3647    var isNamedAnchor = function (node) {
3648      return isElement$1(node) && node.nodeName === 'A' && !node.hasAttribute('href') && (node.hasAttribute('name') || node.hasAttribute('id'));
3649    };
3650    var isContent = function (node, rootNode) {
3651      return isCaretCandidate(node) && isWhitespace(node, rootNode) === false || isNamedAnchor(node) || isBookmark(node);
3652    };
3653    var isBookmark = hasAttribute('data-mce-bookmark');
3654    var isBogus$1 = hasAttribute('data-mce-bogus');
3655    var isBogusAll$1 = hasAttributeValue('data-mce-bogus', 'all');
3656    var isEmptyNode = function (targetNode, skipBogus) {
3657      var node, brCount = 0;
3658      if (isContent(targetNode, targetNode)) {
3659        return false;
3660      } else {
3661        node = targetNode.firstChild;
3662        if (!node) {
3663          return true;
3664        }
3665        var walker = new DomTreeWalker(node, targetNode);
3666        do {
3667          if (skipBogus) {
3668            if (isBogusAll$1(node)) {
3669              node = walker.next(true);
3670              continue;
3671            }
3672            if (isBogus$1(node)) {
3673              node = walker.next();
3674              continue;
3675            }
3676          }
3677          if (isBr(node)) {
3678            brCount++;
3679            node = walker.next();
3680            continue;
3681          }
3682          if (isContent(node, targetNode)) {
3683            return false;
3684          }
3685          node = walker.next();
3686        } while (node);
3687        return brCount <= 1;
3688      }
3689    };
3690    var isEmpty = function (elm, skipBogus) {
3691      if (skipBogus === void 0) {
3692        skipBogus = true;
3693      }
3694      return isEmptyNode(elm.dom, skipBogus);
3695    };
3696
3697    var isSpan = function (node) {
3698      return node.nodeName.toLowerCase() === 'span';
3699    };
3700    var isInlineContent = function (node, root) {
3701      return isNonNullable(node) && (isContent(node, root) || isInline(SugarElement.fromDom(node)));
3702    };
3703    var surroundedByInlineContent = function (node, root) {
3704      var prev = new DomTreeWalker(node, root).prev(false);
3705      var next = new DomTreeWalker(node, root).next(false);
3706      var prevIsInline = isUndefined(prev) || isInlineContent(prev, root);
3707      var nextIsInline = isUndefined(next) || isInlineContent(next, root);
3708      return prevIsInline && nextIsInline;
3709    };
3710    var isBookmarkNode = function (node) {
3711      return isSpan(node) && node.getAttribute('data-mce-type') === 'bookmark';
3712    };
3713    var isKeepTextNode = function (node, root) {
3714      return isText$1(node) && node.data.length > 0 && surroundedByInlineContent(node, root);
3715    };
3716    var isKeepElement = function (node) {
3717      return isElement$1(node) ? node.childNodes.length > 0 : false;
3718    };
3719    var isDocument$2 = function (node) {
3720      return isDocumentFragment$1(node) || isDocument$1(node);
3721    };
3722    var trimNode = function (dom, node, root) {
3723      var rootNode = root || node;
3724      if (isElement$1(node) && isBookmarkNode(node)) {
3725        return node;
3726      }
3727      var children = node.childNodes;
3728      for (var i = children.length - 1; i >= 0; i--) {
3729        trimNode(dom, children[i], rootNode);
3730      }
3731      if (isElement$1(node)) {
3732        var currentChildren = node.childNodes;
3733        if (currentChildren.length === 1 && isBookmarkNode(currentChildren[0])) {
3734          node.parentNode.insertBefore(currentChildren[0], node);
3735        }
3736      }
3737      if (!isDocument$2(node) && !isContent(node, rootNode) && !isKeepElement(node) && !isKeepTextNode(node, rootNode)) {
3738        dom.remove(node);
3739      }
3740      return node;
3741    };
3742
3743    var makeMap$1 = Tools.makeMap;
3744    var attrsCharsRegExp = /[&<>\"\u0060\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
3745    var textCharsRegExp = /[<>&\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
3746    var rawCharsRegExp = /[<>&\"\']/g;
3747    var entityRegExp = /&#([a-z0-9]+);?|&([a-z0-9]+);/gi;
3748    var asciiMap = {
3749      128: '\u20AC',
3750      130: '\u201A',
3751      131: '\u0192',
3752      132: '\u201E',
3753      133: '\u2026',
3754      134: '\u2020',
3755      135: '\u2021',
3756      136: '\u02c6',
3757      137: '\u2030',
3758      138: '\u0160',
3759      139: '\u2039',
3760      140: '\u0152',
3761      142: '\u017d',
3762      145: '\u2018',
3763      146: '\u2019',
3764      147: '\u201C',
3765      148: '\u201D',
3766      149: '\u2022',
3767      150: '\u2013',
3768      151: '\u2014',
3769      152: '\u02DC',
3770      153: '\u2122',
3771      154: '\u0161',
3772      155: '\u203A',
3773      156: '\u0153',
3774      158: '\u017e',
3775      159: '\u0178'
3776    };
3777    var baseEntities = {
3778      '"': '&quot;',
3779      '\'': '&#39;',
3780      '<': '&lt;',
3781      '>': '&gt;',
3782      '&': '&amp;',
3783      '`': '&#96;'
3784    };
3785    var reverseEntities = {
3786      '&lt;': '<',
3787      '&gt;': '>',
3788      '&amp;': '&',
3789      '&quot;': '"',
3790      '&apos;': '\''
3791    };
3792    var nativeDecode = function (text) {
3793      var elm = SugarElement.fromTag('div').dom;
3794      elm.innerHTML = text;
3795      return elm.textContent || elm.innerText || text;
3796    };
3797    var buildEntitiesLookup = function (items, radix) {
3798      var i, chr, entity;
3799      var lookup = {};
3800      if (items) {
3801        items = items.split(',');
3802        radix = radix || 10;
3803        for (i = 0; i < items.length; i += 2) {
3804          chr = String.fromCharCode(parseInt(items[i], radix));
3805          if (!baseEntities[chr]) {
3806            entity = '&' + items[i + 1] + ';';
3807            lookup[chr] = entity;
3808            lookup[entity] = chr;
3809          }
3810        }
3811        return lookup;
3812      }
3813    };
3814    var namedEntities = buildEntitiesLookup('50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy,' + '5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute,' + '5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34,' + '5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil,' + '68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde,' + '6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute,' + '6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml,' + '75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc,' + '7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash,' + '7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta,' + 'sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu,' + 'st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi,' + 't9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota,' + 'tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau,' + 'u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip,' + '81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym,' + '8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr,' + '8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod,' + '8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup,' + '8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8
3814k4,' + 'nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob,' + 'rfloor,8p9,lang,8pa,rang,9ea,loz,9j0,spades,9j3,clubs,9j5,hearts,9j6,diams,ai,OElig,aj,oelig,b0,' + 'Scaron,b1,scaron,bo,Yuml,m6,circ,ms,tilde,802,ensp,803,emsp,809,thinsp,80c,zwnj,80d,zwj,80e,lrm,' + '80f,rlm,80j,ndash,80k,mdash,80o,lsquo,80p,rsquo,80q,sbquo,80s,ldquo,80t,rdquo,80u,bdquo,810,dagger,' + '811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro', 32);
3815    var encodeRaw = function (text, attr) {
3816      return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function (chr) {
3817        return baseEntities[chr] || chr;
3818      });
3819    };
3820    var encodeAllRaw = function (text) {
3821      return ('' + text).replace(rawCharsRegExp, function (chr) {
3822        return baseEntities[chr] || chr;
3823      });
3824    };
3825    var encodeNumeric = function (text, attr) {
3826      return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function (chr) {
3827        if (chr.length > 1) {
3828          return '&#' + ((chr.charCodeAt(0) - 55296) * 1024 + (chr.charCodeAt(1) - 56320) + 65536) + ';';
3829        }
3830        return baseEntities[chr] || '&#' + chr.charCodeAt(0) + ';';
3831      });
3832    };
3833    var encodeNamed = function (text, attr, entities) {
3834      entities = entities || namedEntities;
3835      return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function (chr) {
3836        return baseEntities[chr] || entities[chr] || chr;
3837      });
3838    };
3839    var getEncodeFunc = function (name, entities) {
3840      var entitiesMap = buildEntitiesLookup(entities) || namedEntities;
3841      var encodeNamedAndNumeric = function (text, attr) {
3842        return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function (chr) {
3843          if (baseEntities[chr] !== undefined) {
3844            return baseEntities[chr];
3845          }
3846          if (entitiesMap[chr] !== undefined) {
3847            return entitiesMap[chr];
3848          }
3849          if (chr.length > 1) {
3850            return '&#' + ((chr.charCodeAt(0) - 55296) * 1024 + (chr.charCodeAt(1) - 56320) + 65536) + ';';
3851          }
3852          return '&#' + chr.charCodeAt(0) + ';';
3853        });
3854      };
3855      var encodeCustomNamed = function (text, attr) {
3856        return encodeNamed(text, attr, entitiesMap);
3857      };
3858      var nameMap = makeMap$1(name.replace(/\+/g, ','));
3859      if (nameMap.named && nameMap.numeric) {
3860        return encodeNamedAndNumeric;
3861      }
3862      if (nameMap.named) {
3863        if (entities) {
3864          return encodeCustomNamed;
3865        }
3866        return encodeNamed;
3867      }
3868      if (nameMap.numeric) {
3869        return encodeNumeric;
3870      }
3871      return encodeRaw;
3872    };
3873    var decode = function (text) {
3874      return text.replace(entityRegExp, function (all, numeric) {
3875        if (numeric) {
3876          if (numeric.charAt(0).toLowerCase() === 'x') {
3877            numeric = parseInt(numeric.substr(1), 16);
3878          } else {
3879            numeric = parseInt(numeric, 10);
3880          }
3881          if (numeric > 65535) {
3882            numeric -= 65536;
3883            return String.fromCharCode(55296 + (numeric >> 10), 56320 + (numeric & 1023));
3884          }
3885          return asciiMap[numeric] || String.fromCharCode(numeric);
3886        }
3887        return reverseEntities[all] || namedEntities[all] || nativeDecode(all);
3888      });
3889    };
3890    var Entities = {
3891      encodeRaw: encodeRaw,
3892      encodeAllRaw: encodeAllRaw,
3893      encodeNumeric: encodeNumeric,
3894      encodeNamed: encodeNamed,
3895      getEncodeFunc: getEncodeFunc,
3896      decode: decode
3897    };
3898
3899    var mapCache = {}, dummyObj = {};
3900    var makeMap$2 = Tools.makeMap, each$3 = Tools.each, extend$1 = Tools.extend, explode$1 = Tools.explode, inArray = Tools.inArray;
3901    var split = function (items, delim) {
3902      items = Tools.trim(items);
3903      return items ? items.split(delim || ' ') : [];
3904    };
3905    var compileSchema = function (type) {
3906      var schema = {};
3907      var globalAttributes, blockContent;
3908      var phrasingContent, flowContent, html4BlockContent, html4PhrasingContent;
3909      var add = function (name, attributes, children) {
3910        var ni, attributesOrder, element;
3911        var arrayToMap = function (array, obj) {
3912          var map = {};
3913          var i, l;
3914          for (i = 0, l = array.length; i < l; i++) {
3915            map[array[i]] = obj || {};
3916          }
3917          return map;
3918        };
3919        children = children || [];
3920        attributes = attributes || '';
3921        if (typeof children === 'string') {
3922          children = split(children);
3923        }
3924        var names = split(name);
3925        ni = names.length;
3926        while (ni--) {
3927          attributesOrder = split([
3928            globalAttributes,
3929            attributes
3930          ].join(' '));
3931          element = {
3932            attributes: arrayToMap(attributesOrder),
3933            attributesOrder: attributesOrder,
3934            children: arrayToMap(children, dummyObj)
3935          };
3936          schema[names[ni]] = element;
3937        }
3938      };
3939      var addAttrs = function (name, attributes) {
3940        var ni, schemaItem, i, l;
3941        var names = split(name);
3942        ni = names.length;
3943        var attrs = split(attributes);
3944        while (ni--) {
3945          schemaItem = schema[names[ni]];
3946          for (i = 0, l = attrs.length; i < l; i++) {
3947            schemaItem.attributes[attrs[i]] = {};
3948            schemaItem.attributesOrder.push(attrs[i]);
3949          }
3950        }
3951      };
3952      if (mapCache[type]) {
3953        return mapCache[type];
3954      }
3955      globalAttributes = 'id accesskey class dir lang style tabindex title role';
3956      blockContent = 'address blockquote div dl fieldset form h1 h2 h3 h4 h5 h6 hr menu ol p pre table ul';
3957      phrasingContent = 'a abbr b bdo br button cite code del dfn em embed i iframe img input ins kbd ' + 'label map noscript object q s samp script select small span strong sub sup ' + 'textarea u var #text #comment';
3958      if (type !== 'html4') {
3959        globalAttributes += ' contenteditable contextmenu draggable dropzone ' + 'hidden spellcheck translate';
3960        blockContent += ' article aside details dialog figure main header footer hgroup section nav';
3961        phrasingContent += ' audio canvas command datalist mark meter output picture ' + 'progress time wbr video ruby bdi keygen';
3962      }
3963      if (type !== 'html5-strict') {
3964        globalAttributes += ' xml:lang';
3965        html4PhrasingContent = 'acronym applet basefont big font strike tt';
3966        phrasingContent = [
3967          phrasingContent,
3968          html4PhrasingContent
3969        ].join(' ');
3970        each$3(split(html4PhrasingContent), function (name) {
3971          add(name, '', phrasingContent);
3972        });
3973        html4BlockContent = 'center dir isindex noframes';
3974        blockContent = [
3975          blockContent,
3976          html4BlockContent
3977        ].join(' ');
3978        flowContent = [
3979          blockContent,
3980          phrasingContent
3981        ].join(' ');
3982        each$3(split(html4BlockContent), function (name) {
3983          add(name, '', flowContent);
3984        });
3985      }
3986      flowContent = flowContent || [
3987        blockContent,
3988        phrasingContent
3989      ].join(' ');
3990      add('html', 'manifest', 'head body');
3991      add('head', '', 'base command link meta noscript script style title');
3992      add('title hr noscript br');
3993      add('base', 'href target');
3994      add('link', 'href rel media hreflang type sizes hreflang');
3995      add('meta', 'name http-equiv content charset');
3996      add('style', 'media type scoped');
3997      add('script', 'src async defer type charset');
3998      add('body', 'onafterprint onbeforeprint onbeforeunload onblur onerror onfocus ' + 'onhashchange onload onmessage onoffline ononline onpagehide onpageshow ' + 'onpopstate onresize onscroll onstorage onunload', flowContent);
3999      add('address dt dd div caption', '', flowContent);
4000      add('h1 h2 h3 h4 h5 h6 pre p abbr code var samp kbd sub sup i b u bdo span legend em strong small s cite dfn', '', phrasingContent);
4001      add('blockquote', 'cite', flowContent);
4002      add('ol', 'reversed start type', 'li');
4003      add('ul', '', 'li');
4004      add('li', 'value', flowContent);
4005      add('dl', '', 'dt dd');
4006      add('a', 'href target rel media hreflang type', phrasingContent);
4007      add('q', 'cite', phrasingContent);
4008      add('ins del', 'cite datetime', flowContent);
4009      add('img', 'src sizes srcset alt usemap ismap width height');
4010      add('iframe', 'src name width height', flowContent);
4011      add('embed', 'src type width height');
4012      add('object', 'data type typemustmatch name usemap form width height', [
4013        flowContent,
4014        'param'
4015      ].join(' '));
4016      add('param', 'name value');
4017      add('map', 'name', [
4018        flowContent,
4019        'area'
4020      ].join(' '));
4021      add('area', 'alt coords shape href target rel media hreflang type');
4022      add('table', 'border', 'caption colgroup thead tfoot tbody tr' + (type === 'html4' ? ' col' : ''));
4023      add('colgroup', 'span', 'col');
4024      add('col', 'span');
4025      add('tbody thead tfoot', '', 'tr');
4026      add('tr', '', 'td th');
4027      add('td', 'colspan rowspan headers', flowContent);
4028      add('th', 'colspan rowspan headers scope abbr', flowContent);
4029      add('form', 'accept-charset action autocomplete enctype method name novalidate target', flowContent);
4030      add('fieldset', 'disabled form name', [
4031        flowContent,
4032        'legend'
4033      ].join(' '));
4034      add('label', 'form for', phrasingContent);
4035      add('input', 'accept alt autocomplete checked dirname disabled form formaction formenctype formmethod formnovalidate ' + 'formtarget height list max maxlength min multiple name pattern readonly required size src step type value width');
4036      add('button', 'disabled form formaction formenctype formmethod formnovalidate formtarget name type value', type === 'html4' ? flowContent : phrasingContent);
4037      add('select', 'disabled form multiple name required size', 'option optgroup');
4038      add('optgroup', 'disabled label', 'option');
4039      add('option', 'disabled label selected value');
4040      add('textarea', 'cols dirname disabled form maxlength name readonly required rows wrap');
4041      add('menu', 'type label', [
4042        flowContent,
4043        'li'
4044      ].join(' '));
4045      add('noscript', '', flowContent);
4046      if (type !== 'html4') {
4047        add('wbr');
4048        add('ruby', '', [
4049          phrasingContent,
4050          'rt rp'
4051        ].join(' '));
4052        add('figcaption', '', flowContent);
4053        add('mark rt rp summary bdi', '', phrasingContent);
4054        add('canvas', 'width height', flowContent);
4055        add('video', 'src crossorigin poster preload autoplay mediagroup loop ' + 'muted controls width height buffered', [
4056          flowContent,
4057          'track source'
4058        ].join(' '));
4059        add('audio', 'src crossorigin preload autoplay mediagroup loop muted controls ' + 'buffered volume', [
4060          flowContent,
4061          'track source'
4062        ].join(' '));
4063        add('picture', '', 'img source');
4064        add('source', 'src srcset type media sizes');
4065        add('track', 'kind src srclang label default');
4066        add('datalist', '', [
4067          phrasingContent,
4068          'option'
4069        ].join(' '));
4070        add('article section nav aside main header footer', '', flowContent);
4071        add('hgroup', '', 'h1 h2 h3 h4 h5 h6');
4072        add('figure', '', [
4073          flowContent,
4074          'figcaption'
4075        ].join(' '));
4076        add('time', 'datetime', phrasingContent);
4077        add('dialog', 'open', flowContent);
4078        add('command', 'type label icon disabled checked radiogroup command');
4079        add('output', 'for form name', phrasingContent);
4080        add('progress', 'value max', phrasingContent);
4081        add('meter', 'value min max low high optimum', phrasingContent);
4082        add('details', 'open', [
4083          flowContent,
4084          'summary'
4085        ].join(' '));
4086        add('keygen', 'autofocus challenge disabled form keytype name');
4087      }
4088      if (type !== 'html5-strict') {
4089        addAttrs('script', 'language xml:space');
4090        addAttrs('style', 'xml:space');
4091        addAttrs('object', 'declare classid code codebase codetype archive standby align border hspace vspace');
4092        addAttrs('embed', 'align name hspace vspace');
4093        addAttrs('param', 'valuetype type');
4094        addAttrs('a', 'charset name rev shape coords');
4095        addAttrs('br', 'clear');
4096        addAttrs('applet', 'codebase archive code object alt name width height align hspace vspace');
4097        addAttrs('img', 'name longdesc align border hspace vspace');
4098        addAttrs('iframe', 'longdesc frameborder marginwidth marginheight scrolling align');
4099        addAttrs('font basefont', 'size color face');
4100        addAttrs('input', 'usemap align');
4101        addAttrs('select');
4102        addAttrs('textarea');
4103        addAttrs('h1 h2 h3 h4 h5 h6 div p legend caption', 'align');
4104        addAttrs('ul', 'type compact');
4105        addAttrs('li', 'type');
4106        addAttrs('ol dl menu dir', 'compact');
4107        addAttrs('pre', 'width xml:space');
4108        addAttrs('hr', 'align noshade size width');
4109        addAttrs('isindex', 'prompt');
4110        addAttrs('table', 'summary width frame rules cellspacing cellpadding align bgcolor');
4111        addAttrs('col', 'width align char charoff valign');
4112        addAttrs('colgroup', 'width align char charoff valign');
4113        addAttrs('thead', 'align char charoff valign');
4114        addAttrs('tr', 'align char charoff valign bgcolor');
4115        addAttrs('th', 'axis align char charoff valign nowrap bgcolor width height');
4116        addAttrs('form', 'accept');
4117        addAttrs('td', 'abbr axis scope align char charoff valign nowrap bgcolor width height');
4118        addAttrs('tfoot', 'align char charoff valign');
4119        addAttrs('tbody', 'align char charoff valign');
4120        addAttrs('area', 'nohref');
4121        addAttrs('body', 'background bgcolor text link vlink alink');
4122      }
4123      if (type !== 'html4') {
4124        addAttrs('input button select textarea', 'autofocus');
4125        addAttrs('input textarea', 'placeholder');
4126        addAttrs('a', 'download');
4127        addAttrs('link script img', 'crossorigin');
4128        addAttrs('img', 'loading');
4129        addAttrs('iframe', 'sandbox seamless allowfullscreen loading');
4130      }
4131      each$3(split('a form meter progress dfn'), function (name) {
4132        if (schema[name]) {
4133          delete schema[name].children[name];
4134        }
4135      });
4136      delete schema.caption.children.table;
4137      delete schema.script;
4138      mapCache[type] = schema;
4139      return schema;
4140    };
4141    var compileElementMap = function (value, mode) {
4142      var styles;
4143      if (value) {
4144        styles = {};
4145        if (typeof value === 'string') {
4146          value = { '*': value };
4147        }
4148        each$3(value, function (value, key) {
4149          styles[key] = styles[key.toUpperCase()] = mode === 'map' ? makeMap$2(value, /[, ]/) : explode$1(value, /[, ]/);
4150        });
4151      }
4152      return styles;
4153    };
4154    function Schema(settings) {
4155      var elements = {};
4156      var children = {};
4157      var patternElements = [];
4158      var customElementsMap = {}, specialElements = {};
4159      var createLookupTable = function (option, defaultValue, extendWith) {
4160        var value = settings[option];
4161        if (!value) {
4162          value = mapCache[option];
4163          if (!value) {
4164            value = makeMap$2(defaultValue, ' ', makeMap$2(defaultValue.toUpperCase(), ' '));
4165            value = extend$1(value, extendWith);
4166            mapCache[option] = value;
4167          }
4168        } else {
4169          value = makeMap$2(value, /[, ]/, makeMap$2(value.toUpperCase(), /[, ]/));
4170        }
4171        return value;
4172      };
4173      settings = settings || {};
4174      var schemaItems = compileSchema(settings.schema);
4175      if (settings.verify_html === false) {
4176        settings.valid_elements = '*[*]';
4177      }
4178      var validStyles = compileElementMap(settings.valid_styles);
4179      var invalidStyles = compileElementMap(settings.invalid_styles, 'map');
4180      var validClasses = compileElementMap(settings.valid_classes, 'map');
4181      var whiteSpaceElementsMap = createLookupTable('whitespace_elements', 'pre script noscript style textarea video audio iframe object code');
4182      var selfClosingElementsMap = createLookupTable('self_closing_elements', 'colgroup dd dt li option p td tfoot th thead tr');
4183      var shortEndedElementsMap = createLookupTable('short_ended_elements', 'area base basefont br col frame hr img input isindex link ' + 'meta param embed source wbr track');
4184      var boolAttrMap = createLookupTable('boolean_attributes', 'checked compact declare defer disabled ismap multiple nohref noresize ' + 'noshade nowrap readonly selected autoplay loop controls');
4185      var nonEmptyOrMoveCaretBeforeOnEnter = 'td th iframe video audio object script code';
4186      var nonEmptyElementsMap = createLookupTable('non_empty_elements', nonEmptyOrMoveCaretBeforeOnEnter + ' pre', shortEndedElementsMap);
4187      var moveCaretBeforeOnEnterElementsMap = createLookupTable('move_caret_before_on_enter_elements', nonEmptyOrMoveCaretBeforeOnEnter + ' table', shortEndedElementsMap);
4188      var textBlockElementsMap = createLookupTable('text_block_elements', 'h1 h2 h3 h4 h5 h6 p div address pre form ' + 'blockquote center dir fieldset header footer article section hgroup aside main nav figure');
4189      var blockElementsMap = createLookupTable('block_elements', 'hr table tbody thead tfoot ' + 'th tr td li ol ul caption dl dt dd noscript menu isindex option ' + 'datalist select optgroup figcaption details summary', textBlockElementsMap);
4190      var textInlineElementsMap = createLookupTable('text_inline_elements', 'span strong b em i font strike u var cite ' + 'dfn code mark q sup sub samp');
4191      each$3((settings.special || 'script noscript iframe noframes noembed title style textarea xmp').split(' '), function (name) {
4192        specialElements[name] = new RegExp('</' + name + '[^>]*>', 'gi');
4193      });
4194      var patternToRegExp = function (str) {
4195        return new RegExp('^' + str.replace(/([?+*])/g, '.$1') + '$');
4196      };
4197      var addValidElements = function (validElements) {
4198        var ei, el, ai, al, matches, element, attr, attrData, elementName, attrName, attrType, attributes, attributesOrder, prefix, outputName, globalAttributes, globalAttributesOrder, value;
4199        var elementRuleRegExp = /^([#+\-])?([^\[!\/]+)(?:\/([^\[!]+))?(?:(!?)\[([^\]]+)])?$/, attrRuleRegExp = /^([!\-])?(\w+[\\:]:\w+|[^=:<]+)?(?:([=:<])(.*))?$/, hasPatternsRegExp = /[*?+]/;
4200        if (validElements) {
4201          var validElementsArr = split(validElements, ',');
4202          if (elements['@']) {
4203            globalAttributes = elements['@'].attributes;
4204            globalAttributesOrder = elements['@'].attributesOrder;
4205          }
4206          for (ei = 0, el = validElementsArr.length; ei < el; ei++) {
4207            matches = elementRuleRegExp.exec(validElementsArr[ei]);
4208            if (matches) {
4209              prefix = matches[1];
4210              elementName = matches[2];
4211              outputName = matches[3];
4212              attrData = matches[5];
4213              attributes = {};
4214              attributesOrder = [];
4215              element = {
4216                attributes: attributes,
4217                attributesOrder: attributesOrder
4218              };
4219              if (prefix === '#') {
4220                element.paddEmpty = true;
4221              }
4222              if (prefix === '-') {
4223                element.removeEmpty = true;
4224              }
4225              if (matches[4] === '!') {
4226                element.removeEmptyAttrs = true;
4227              }
4228              if (globalAttributes) {
4229                each$1(globalAttributes, function (value, key) {
4230                  attributes[key] = value;
4231                });
4232                attributesOrder.push.apply(attributesOrder, globalAttributesOrder);
4233              }
4234              if (attrData) {
4235                attrData = split(attrData, '|');
4236                for (ai = 0, al = attrData.length; ai < al; ai++) {
4237                  matches = attrRuleRegExp.exec(attrData[ai]);
4238                  if (matches) {
4239                    attr = {};
4240                    attrType = matches[1];
4241                    attrName = matches[2].replace(/[\\:]:/g, ':');
4242                    prefix = matches[3];
4243                    value = matches[4];
4244                    if (attrType === '!') {
4245                      element.attributesRequired = element.attributesRequired || [];
4246                      element.attributesRequired.push(attrName);
4247                      attr.required = true;
4248                    }
4249                    if (attrType === '-') {
4250                      delete attributes[attrName];
4251                      attributesOrder.splice(inArray(attributesOrder, attrName), 1);
4252                      continue;
4253                    }
4254                    if (prefix) {
4255                      if (prefix === '=') {
4256                        element.attributesDefault = element.attributesDefault || [];
4257                        element.attributesDefault.push({
4258                          name: attrName,
4259                          value: value
4260                        });
4261                        attr.defaultValue = value;
4262                      }
4263                      if (prefix === ':') {
4264                        element.attributesForced = element.attributesForced || [];
4265                        element.attributesForced.push({
4266                          name: attrName,
4267                          value: value
4268                        });
4269                        attr.forcedValue = value;
4270                      }
4271                      if (prefix === '<') {
4272                        attr.validValues = makeMap$2(value, '?');
4273                      }
4274                    }
4275                    if (hasPatternsRegExp.test(attrName)) {
4276                      element.attributePatterns = element.attributePatterns || [];
4277                      attr.pattern = patternToRegExp(attrName);
4278                      element.attributePatterns.push(attr);
4279                    } else {
4280                      if (!attributes[attrName]) {
4281                        attributesOrder.push(attrName);
4282                      }
4283                      attributes[attrName] = attr;
4284                    }
4285                  }
4286                }
4287              }
4288              if (!globalAttributes && elementName === '@') {
4289                globalAttributes = attributes;
4290                globalAttributesOrder = attributesOrder;
4291              }
4292              if (outputName) {
4293                element.outputName = elementName;
4294                elements[outputName] = element;
4295              }
4296              if (hasPatternsRegExp.test(elementName)) {
4297                element.pattern = patternToRegExp(elementName);
4298                patternElements.push(element);
4299              } else {
4300                elements[elementName] = element;
4301              }
4302            }
4303          }
4304        }
4305      };
4306      var setValidElements = function (validElements) {
4307        elements = {};
4308        patternElements = [];
4309        addValidElements(validElements);
4310        each$3(schemaItems, function (element, name) {
4311          children[name] = element.children;
4312        });
4313      };
4314      var addCustomElements = function (customElements) {
4315        var customElementRegExp = /^(~)?(.+)$/;
4316        if (customElements) {
4317          mapCache.text_block_elements = mapCache.block_elements = null;
4318          each$3(split(customElements, ','), function (rule) {
4319            var matches = customElementRegExp.exec(rule), inline = matches[1] === '~', cloneName = inline ? 'span' : 'div', name = matches[2];
4320            children[name] = children[cloneName];
4321            customElementsMap[name] = cloneName;
4322            if (!inline) {
4323              blockElementsMap[name.toUpperCase()] = {};
4324              blockElementsMap[name] = {};
4325            }
4326            if (!elements[name]) {
4327              var customRule = elements[cloneName];
4328              customRule = extend$1({}, customRule);
4329              delete customRule.removeEmptyAttrs;
4330              delete customRule.removeEmpty;
4331              elements[name] = customRule;
4332            }
4333            each$3(children, function (element, elmName) {
4334              if (element[cloneName]) {
4335                children[elmName] = element = extend$1({}, children[elmName]);
4336                element[name] = element[cloneName];
4337              }
4338            });
4339          });
4340        }
4341      };
4342      var addValidChildren = function (validChildren) {
4343        var childRuleRegExp = /^([+\-]?)([A-Za-z0-9_\-.\u00b7\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u037d\u037f-\u1fff\u200c-\u200d\u203f-\u2040\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]+)\[([^\]]+)]$/;
4344        mapCache[settings.schema] = null;
4345        if (validChildren) {
4346          each$3(split(validChildren, ','), function (rule) {
4347            var matches = childRuleRegExp.exec(rule);
4348            var parent, prefix;
4349            if (matches) {
4350              prefix = matches[1];
4351              if (prefix) {
4352                parent = children[matches[2]];
4353              } else {
4354                parent = children[matches[2]] = { '#comment': {} };
4355              }
4356              parent = children[matches[2]];
4357              each$3(split(matches[3], '|'), function (child) {
4358                if (prefix === '-') {
4359                  delete parent[child];
4360                } else {
4361                  parent[child] = {};
4362                }
4363              });
4364            }
4365          });
4366        }
4367      };
4368      var getElementRule = function (name) {
4369        var element = elements[name], i;
4370        if (element) {
4371          return element;
4372        }
4373        i = patternElements.length;
4374        while (i--) {
4375          element = patternElements[i];
4376          if (element.pattern.test(name)) {
4377            return element;
4378          }
4379        }
4380      };
4381      if (!settings.valid_elements) {
4382        each$3(schemaItems, function (element, name) {
4383          elements[name] = {
4384            attributes: element.attributes,
4385            attributesOrder: element.attributesOrder
4386          };
4387          children[name] = element.children;
4388        });
4389        if (settings.schema !== 'html5') {
4390          each$3(split('strong/b em/i'), function (item) {
4391            var items = split(item, '/');
4392            elements[items[1]].outputName = items[0];
4393          });
4394        }
4395        each$3(split('ol ul sub sup blockquote span font a table tbody tr strong em b i'), function (name) {
4396          if (elements[name]) {
4397            elements[name].removeEmpty = true;
4398          }
4399        });
4400        each$3(split('p h1 h2 h3 h4 h5 h6 th td pre div address caption li'), function (name) {
4401          elements[name].paddEmpty = true;
4402        });
4403        each$3(split('span'), function (name) {
4404          elements[name].removeEmptyAttrs = true;
4405        });
4406      } else {
4407        setValidElements(settings.valid_elements);
4408      }
4409      addCustomElements(settings.custom_elements);
4410      addValidChildren(settings.valid_children);
4411      addValidElements(settings.extended_valid_elements);
4412      addValidChildren('+ol[ul|ol],+ul[ul|ol]');
4413      each$3({
4414        dd: 'dl',
4415        dt: 'dl',
4416        li: 'ul ol',
4417        td: 'tr',
4418        th: 'tr',
4419        tr: 'tbody thead tfoot',
4420        tbody: 'table',
4421        thead: 'table',
4422        tfoot: 'table',
4423        legend: 'fieldset',
4424        area: 'map',
4425        param: 'video audio object'
4426      }, function (parents, item) {
4427        if (elements[item]) {
4428          elements[item].parentsRequired = split(parents);
4429        }
4430      });
4431      if (settings.invalid_elements) {
4432        each$3(explode$1(settings.invalid_elements), function (item) {
4433          if (elements[item]) {
4434            delete elements[item];
4435          }
4436        });
4437      }
4438      if (!getElementRule('span')) {
4439        addValidElements('span[!data-mce-type|*]');
4440      }
4441      var getValidStyles = function () {
4442        return validStyles;
4443      };
4444      var getInvalidStyles = function () {
4445        return invalidStyles;
4446      };
4447      var getValidClasses = function () {
4448        return validClasses;
4449      };
4450      var getBoolAttrs = function () {
4451        return boolAttrMap;
4452      };
4453      var getBlockElements = function () {
4454        return blockElementsMap;
4455      };
4456      var getTextBlockElements = function () {
4457        return textBlockElementsMap;
4458      };
4459      var getTextInlineElements = function () {
4460        return textInlineElementsMap;
4461      };
4462      var getShortEndedElements = function () {
4463        return shortEndedElementsMap;
4464      };
4465      var getSelfClosingElements = function () {
4466        return selfClosingElementsMap;
4467      };
4468      var getNonEmptyElements = function () {
4469        return nonEmptyElementsMap;
4470      };
4471      var getMoveCaretBeforeOnEnterElements = function () {
4472        return moveCaretBeforeOnEnterElementsMap;
4473      };
4474      var getWhiteSpaceElements = function () {
4475        return whiteSpaceElementsMap;
4476      };
4477      var getSpecialElements = function () {
4478        return specialElements;
4479      };
4480      var isValidChild = function (name, child) {
4481        var parent = children[name.toLowerCase()];
4482        return !!(parent && parent[child.toLowerCase()]);
4483      };
4484      var isValid = function (name, attr) {
4485        var attrPatterns, i;
4486        var rule = getElementRule(name);
4487        if (rule) {
4488          if (attr) {
4489            if (rule.attributes[attr]) {
4490              return true;
4491            }
4492            attrPatterns = rule.attributePatterns;
4493            if (attrPatterns) {
4494              i = attrPatterns.length;
4495              while (i--) {
4496                if (attrPatterns[i].pattern.test(name)) {
4497                  return true;
4498                }
4499              }
4500            }
4501          } else {
4502            return true;
4503          }
4504        }
4505        return false;
4506      };
4507      var getCustomElements = function () {
4508        return customElementsMap;
4509      };
4510      return {
4511        children: children,
4512        elements: elements,
4513        getValidStyles: getValidStyles,
4514        getValidClasses: getValidClasses,
4515        getBlockElements: getBlockElements,
4516        getInvalidStyles: getInvalidStyles,
4517        getShortEndedElements: getShortEndedElements,
4518        getTextBlockElements: getTextBlockElements,
4519        getTextInlineElements: getTextInlineElements,
4520        getBoolAttrs: getBoolAttrs,
4521        getElementRule: getElementRule,
4522        getSelfClosingElements: getSelfClosingElements,
4523        getNonEmptyElements: getNonEmptyElements,
4524        getMoveCaretBeforeOnEnterElements: getMoveCaretBeforeOnEnterElements,
4525        getWhiteSpaceElements: getWhiteSpaceElements,
4526        getSpecialElements: getSpecialElements,
4527        isValidChild: isValidChild,
4528        isValid: isValid,
4529        getCustomElements: getCustomElements,
4530        addValidElements: addValidElements,
4531        setValidElements: setValidElements,
4532        addCustomElements: addCustomElements,
4533        addValidChildren: addValidChildren
4534      };
4535    }
4536
4537    var toHex = function (match, r, g, b) {
4538      var hex = function (val) {
4539        val = parseInt(val, 10).toString(16);
4540        return val.length > 1 ? val : '0' + val;
4541      };
4542      return '#' + hex(r) + hex(g) + hex(b);
4543    };
4544    var Styles = function (settings, schema) {
4545      var rgbRegExp = /rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/gi;
4546      var urlOrStrRegExp = /(?:url(?:(?:\(\s*\"([^\"]+)\"\s*\))|(?:\(\s*\'([^\']+)\'\s*\))|(?:\(\s*([^)\s]+)\s*\))))|(?:\'([^\']+)\')|(?:\"([^\"]+)\")/gi;
4547      var styleRegExp = /\s*([^:]+):\s*([^;]+);?/g;
4548      var trimRightRegExp = /\s+$/;
4549      var i;
4550      var encodingLookup = {};
4551      var validStyles;
4552      var invalidStyles;
4553      var invisibleChar = zeroWidth;
4554      settings = settings || {};
4555      if (schema) {
4556        validStyles = schema.getValidStyles();
4557        invalidStyles = schema.getInvalidStyles();
4558      }
4559      var encodingItems = ('\\" \\\' \\; \\: ; : ' + invisibleChar).split(' ');
4560      for (i = 0; i < encodingItems.length; i++) {
4561        encodingLookup[encodingItems[i]] = invisibleChar + i;
4562        encodingLookup[invisibleChar + i] = encodingItems[i];
4563      }
4564      return {
4565        toHex: function (color) {
4566          return color.replace(rgbRegExp, toHex);
4567        },
4568        parse: function (css) {
4569          var styles = {};
4570          var matches, name, value, isEncoded;
4571          var urlConverter = settings.url_converter;
4572          var urlConverterScope = settings.url_converter_scope || this;
4573          var compress = function (prefix, suffix, noJoin) {
4574            var top = styles[prefix + '-top' + suffix];
4575            if (!top) {
4576              return;
4577            }
4578            var right = styles[prefix + '-right' + suffix];
4579            if (!right) {
4580              return;
4581            }
4582            var bottom = styles[prefix + '-bottom' + suffix];
4583            if (!bottom) {
4584              return;
4585            }
4586            var left = styles[prefix + '-left' + suffix];
4587            if (!left) {
4588              return;
4589            }
4590            var box = [
4591              top,
4592              right,
4593              bottom,
4594              left
4595            ];
4596            i = box.length - 1;
4597            while (i--) {
4598              if (box[i] !== box[i + 1]) {
4599                break;
4600              }
4601            }
4602            if (i > -1 && noJoin) {
4603              return;
4604            }
4605            styles[prefix + suffix] = i === -1 ? box[0] : box.join(' ');
4606            delete styles[prefix + '-top' + suffix];
4607            delete styles[prefix + '-right' + suffix];
4608            delete styles[prefix + '-bottom' + suffix];
4609            delete styles[prefix + '-left' + suffix];
4610          };
4611          var canCompress = function (key) {
4612            var value = styles[key], i;
4613            if (!value) {
4614              return;
4615            }
4616            value = value.split(' ');
4617            i = value.length;
4618            while (i--) {
4619              if (value[i] !== value[0]) {
4620                return false;
4621              }
4622            }
4623            styles[key] = value[0];
4624            return true;
4625          };
4626          var compress2 = function (target, a, b, c) {
4627            if (!canCompress(a)) {
4628              return;
4629            }
4630            if (!canCompress(b)) {
4631              return;
4632            }
4633            if (!canCompress(c)) {
4634              return;
4635            }
4636            styles[target] = styles[a] + ' ' + styles[b] + ' ' + styles[c];
4637            delete styles[a];
4638            delete styles[b];
4639            delete styles[c];
4640          };
4641          var encode = function (str) {
4642            isEncoded = true;
4643            return encodingLookup[str];
4644          };
4645          var decode = function (str, keepSlashes) {
4646            if (isEncoded) {
4647              str = str.replace(/\uFEFF[0-9]/g, function (str) {
4648                return encodingLookup[str];
4649              });
4650            }
4651            if (!keepSlashes) {
4652              str = str.replace(/\\([\'\";:])/g, '$1');
4653            }
4654            return str;
4655          };
4656          var decodeSingleHexSequence = function (escSeq) {
4657            return String.fromCharCode(parseInt(escSeq.slice(1), 16));
4658          };
4659          var decodeHexSequences = function (value) {
4660            return value.replace(/\\[0-9a-f]+/gi, decodeSingleHexSequence);
4661          };
4662          var processUrl = function (match, url, url2, url3, str, str2) {
4663            str = str || str2;
4664            if (str) {
4665              str = decode(str);
4666              return '\'' + str.replace(/\'/g, '\\\'') + '\'';
4667            }
4668            url = decode(url || url2 || url3);
4669            if (!settings.allow_script_urls) {
4670              var scriptUrl = url.replace(/[\s\r\n]+/g, '');
4671              if (/(java|vb)script:/i.test(scriptUrl)) {
4672                return '';
4673              }
4674              if (!settings.allow_svg_data_urls && /^data:image\/svg/i.test(scriptUrl)) {
4675                return '';
4676              }
4677            }
4678            if (urlConverter) {
4679              url = urlConverter.call(urlConverterScope, url, 'style');
4680            }
4681            return 'url(\'' + url.replace(/\'/g, '\\\'') + '\')';
4682          };
4683          if (css) {
4684            css = css.replace(/[\u0000-\u001F]/g, '');
4685            css = css.replace(/\\[\"\';:\uFEFF]/g, encode).replace(/\"[^\"]+\"|\'[^\']+\'/g, function (str) {
4686              return str.replace(/[;:]/g, encode);
4687            });
4688            while (matches = styleRegExp.exec(css)) {
4689              styleRegExp.lastIndex = matches.index + matches[0].length;
4690              name = matches[1].replace(trimRightRegExp, '').toLowerCase();
4691              value = matches[2].replace(trimRightRegExp, '');
4692              if (name && value) {
4693                name = decodeHexSequences(name);
4694                value = decodeHexSequences(value);
4695                if (name.indexOf(invisibleChar) !== -1 || name.indexOf('"') !== -1) {
4696                  continue;
4697                }
4698                if (!settings.allow_script_urls && (name === 'behavior' || /expression\s*\(|\/\*|\*\//.test(value))) {
4699                  continue;
4700                }
4701                if (name === 'font-weight' && value === '700') {
4702                  value = 'bold';
4703                } else if (name === 'color' || name === 'background-color') {
4704                  value = value.toLowerCase();
4705                }
4706                value = value.replace(rgbRegExp, toHex);
4707                value = value.replace(urlOrStrRegExp, processUrl);
4708                styles[name] = isEncoded ? decode(value, true) : value;
4709              }
4710            }
4711            compress('border', '', true);
4712            compress('border', '-width');
4713            compress('border', '-color');
4714            compress('border', '-style');
4715            compress('padding', '');
4716            compress('margin', '');
4717            compress2('border', 'border-width', 'border-style', 'border-color');
4718            if (styles.border === 'medium none') {
4719              delete styles.border;
4720            }
4721            if (styles['border-image'] === 'none') {
4722              delete styles['border-image'];
4723            }
4724          }
4725          return styles;
4726        },
4727        serialize: function (styles, elementName) {
4728          var css = '';
4729          var serializeStyles = function (name) {
4730            var value;
4731            var styleList = validStyles[name];
4732            if (styleList) {
4733              for (var i_1 = 0, l = styleList.length; i_1 < l; i_1++) {
4734                name = styleList[i_1];
4735                value = styles[name];
4736                if (value) {
4737                  css += (css.length > 0 ? ' ' : '') + name + ': ' + value + ';';
4738                }
4739              }
4740            }
4741          };
4742          var isValid = function (name, elementName) {
4743            var styleMap = invalidStyles['*'];
4744            if (styleMap && styleMap[name]) {
4745              return false;
4746            }
4747            styleMap = invalidStyles[elementName];
4748            return !(styleMap && styleMap[name]);
4749          };
4750          if (elementName && validStyles) {
4751            serializeStyles('*');
4752            serializeStyles(elementName);
4753          } else {
4754            each$1(styles, function (value, name) {
4755              if (value && (!invalidStyles || isValid(name, elementName))) {
4756                css += (css.length > 0 ? ' ' : '') + name + ': ' + value + ';';
4757              }
4758            });
4759          }
4760          return css;
4761        }
4762      };
4763    };
4764
4765    var eventExpandoPrefix = 'mce-data-';
4766    var mouseEventRe = /^(?:mouse|contextmenu)|click/;
4767    var deprecated = {
4768      keyLocation: 1,
4769      layerX: 1,
4770      layerY: 1,
4771      returnValue: 1,
4772      webkitMovementX: 1,
4773      webkitMovementY: 1,
4774      keyIdentifier: 1,
4775      mozPressure: 1
4776    };
4777    var hasIsDefaultPrevented = function (event) {
4778      return event.isDefaultPrevented === returnTrue || event.isDefaultPrevented === returnFalse;
4779    };
4780    var returnFalse = function () {
4781      return false;
4782    };
4783    var returnTrue = function () {
4784      return true;
4785    };
4786    var addEvent = function (target, name, callback, capture) {
4787      if (target.addEventListener) {
4788        target.addEventListener(name, callback, capture || false);
4789      } else if (target.attachEvent) {
4790        target.attachEvent('on' + name, callback);
4791      }
4792    };
4793    var removeEvent = function (target, name, callback, capture) {
4794      if (target.removeEventListener) {
4795        target.removeEventListener(name, callback, capture || false);
4796      } else if (target.detachEvent) {
4797        target.detachEvent('on' + name, callback);
4798      }
4799    };
4800    var isMouseEvent = function (event) {
4801      return mouseEventRe.test(event.type);
4802    };
4803    var fix = function (originalEvent, data) {
4804      var name;
4805      var event = data || {};
4806      for (name in originalEvent) {
4807        if (!deprecated[name]) {
4808          event[name] = originalEvent[name];
4809        }
4810      }
4811      if (!event.target) {
4812        event.target = event.srcElement || document;
4813      }
4814      if (event.composedPath) {
4815        event.composedPath = function () {
4816          return originalEvent.composedPath();
4817        };
4818      }
4819      if (originalEvent && isMouseEvent(originalEvent) && originalEvent.pageX === undefined && originalEvent.clientX !== undefined) {
4820        var eventDoc = event.target.ownerDocument || document;
4821        var doc = eventDoc.documentElement;
4822        var body = eventDoc.body;
4823        event.pageX = originalEvent.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
4824        event.pageY = originalEvent.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
4825      }
4826      event.preventDefault = function () {
4827        event.isDefaultPrevented = returnTrue;
4828        if (originalEvent) {
4829          if (originalEvent.preventDefault) {
4830            originalEvent.preventDefault();
4831          } else {
4832            originalEvent.returnValue = false;
4833          }
4834        }
4835      };
4836      event.stopPropagation = function () {
4837        event.isPropagationStopped = returnTrue;
4838        if (originalEvent) {
4839          if (originalEvent.stopPropagation) {
4840            originalEvent.stopPropagation();
4841          } else {
4842            originalEvent.cancelBubble = true;
4843          }
4844        }
4845      };
4846      event.stopImmediatePropagation = function () {
4847        event.isImmediatePropagationStopped = returnTrue;
4848        event.stopPropagation();
4849      };
4850      if (hasIsDefaultPrevented(event) === false) {
4851        event.isDefaultPrevented = returnFalse;
4852        event.isPropagationStopped = returnFalse;
4853        event.isImmediatePropagationStopped = returnFalse;
4854      }
4855      if (typeof event.metaKey === 'undefined') {
4856        event.metaKey = false;
4857      }
4858      return event;
4859    };
4860    var bindOnReady = function (win, callback, eventUtils) {
4861      var doc = win.document, event = { type: 'ready' };
4862      if (eventUtils.domLoaded) {
4863        callback(event);
4864        return;
4865      }
4866      var isDocReady = function () {
4867        return doc.readyState === 'complete' || doc.readyState === 'interactive' && doc.body;
4868      };
4869      var readyHandler = function () {
4870        removeEvent(win, 'DOMContentLoaded', readyHandler);
4871        removeEvent(win, 'load', readyHandler);
4872        if (!eventUtils.domLoaded) {
4873          eventUtils.domLoaded = true;
4874          callback(event);
4875        }
4876      };
4877      if (isDocReady()) {
4878        readyHandler();
4879      } else {
4880        addEvent(win, 'DOMContentLoaded', readyHandler);
4881      }
4882      addEvent(win, 'load', readyHandler);
4883    };
4884    var EventUtils = function () {
4885      function EventUtils() {
4886        this.domLoaded = false;
4887        this.events = {};
4888        this.count = 1;
4889        this.expando = eventExpandoPrefix + (+new Date()).toString(32);
4890        this.hasMouseEnterLeave = 'onmouseenter' in document.documentElement;
4891        this.hasFocusIn = 'onfocusin' in document.documentElement;
4892        this.count = 1;
4893      }
4894      EventUtils.prototype.bind = function (target, names, callback, scope) {
4895        var self = this;
4896        var id, callbackList, i, name, fakeName, nativeHandler, capture;
4897        var win = window;
4898        var defaultNativeHandler = function (evt) {
4899          self.executeHandlers(fix(evt || win.event), id);
4900        };
4901        if (!target || target.nodeType === 3 || target.nodeType === 8) {
4902          return;
4903        }
4904        if (!target[self.expando]) {
4905          id = self.count++;
4906          target[self.expando] = id;
4907          self.events[id] = {};
4908        } else {
4909          id = target[self.expando];
4910        }
4911        scope = scope || target;
4912        var namesList = names.split(' ');
4913        i = namesList.length;
4914        while (i--) {
4915          name = namesList[i];
4916          nativeHandler = defaultNativeHandler;
4917          fakeName = capture = false;
4918          if (name === 'DOMContentLoaded') {
4919            name = 'ready';
4920          }
4921          if (self.domLoaded && name === 'ready' && target.readyState === 'complete') {
4922            callback.call(scope, fix({ type: name }));
4923            continue;
4924          }
4925          if (!self.hasMouseEnterLeave) {
4926            fakeName = self.mouseEnterLeave[name];
4927            if (fakeName) {
4928              nativeHandler = function (evt) {
4929                var current = evt.currentTarget;
4930                var related = evt.relatedTarget;
4931                if (related && current.contains) {
4932                  related = current.contains(related);
4933                } else {
4934                  while (related && related !== current) {
4935                    related = related.parentNode;
4936                  }
4937                }
4938                if (!related) {
4939                  evt = fix(evt || win.event);
4940                  evt.type = evt.type === 'mouseout' ? 'mouseleave' : 'mouseenter';
4941                  evt.target = current;
4942                  self.executeHandlers(evt, id);
4943                }
4944              };
4945            }
4946          }
4947          if (!self.hasFocusIn && (name === 'focusin' || name === 'focusout')) {
4948            capture = true;
4949            fakeName = name === 'focusin' ? 'focus' : 'blur';
4950            nativeHandler = function (evt) {
4951              evt = fix(evt || win.event);
4952              evt.type = evt.type === 'focus' ? 'focusin' : 'focusout';
4953              self.executeHandlers(evt, id);
4954            };
4955          }
4956          callbackList = self.events[id][name];
4957          if (!callbackList) {
4958            self.events[id][name] = callbackList = [{
4959                func: callback,
4960                scope: scope
4961              }];
4962            callbackList.fakeName = fakeName;
4963            callbackList.capture = capture;
4964            callbackList.nativeHandler = nativeHandler;
4965            if (name === 'ready') {
4966              bindOnReady(target, nativeHandler, self);
4967            } else {
4968              addEvent(target, fakeName || name, nativeHandler, capture);
4969            }
4970          } else {
4971            if (name === 'ready' && self.domLoaded) {
4972              callback(fix({ type: name }));
4973            } else {
4974              callbackList.push({
4975                func: callback,
4976                scope: scope
4977              });
4978            }
4979          }
4980        }
4981        target = callbackList = null;
4982        return callback;
4983      };
4984      EventUtils.prototype.unbind = function (target, names, callback) {
4985        var callbackList, i, ci, name, eventMap;
4986        if (!target || target.nodeType === 3 || target.nodeType === 8) {
4987          return this;
4988        }
4989        var id = target[this.expando];
4990        if (id) {
4991          eventMap = this.events[id];
4992          if (names) {
4993            var namesList = names.split(' ');
4994            i = namesList.length;
4995            while (i--) {
4996              name = namesList[i];
4997              callbackList = eventMap[name];
4998              if (callbackList) {
4999                if (callback) {
5000                  ci = callbackList.length;
5001                  while (ci--) {
5002                    if (callbackList[ci].func === callback) {
5003                      var nativeHandler = callbackList.nativeHandler;
5004                      var fakeName = callbackList.fakeName, capture = callbackList.capture;
5005                      callbackList = callbackList.slice(0, ci).concat(callbackList.slice(ci + 1));
5006                      callbackList.nativeHandler = nativeHandler;
5007                      callbackList.fakeName = fakeName;
5008                      callbackList.capture = capture;
5009                      eventMap[name] = callbackList;
5010                    }
5011                  }
5012                }
5013                if (!callback || callbackList.length === 0) {
5014                  delete eventMap[name];
5015                  removeEvent(target, callbackList.fakeName || name, callbackList.nativeHandler, callbackList.capture);
5016                }
5017              }
5018            }
5019          } else {
5020            each$1(eventMap, function (callbackList, name) {
5021              removeEvent(target, callbackList.fakeName || name, callbackList.nativeHandler, callbackList.capture);
5022            });
5023            eventMap = {};
5024          }
5025          for (name in eventMap) {
5026            if (has(eventMap, name)) {
5027              return this;
5028            }
5029          }
5030          delete this.events[id];
5031          try {
5032            delete target[this.expando];
5033          } catch (ex) {
5034            target[this.expando] = null;
5035          }
5036        }
5037        return this;
5038      };
5039      EventUtils.prototype.fire = function (target, name, args) {
5040        var id;
5041        if (!target || target.nodeType === 3 || target.nodeType === 8) {
5042          return this;
5043        }
5044        var event = fix(null, args);
5045        event.type = name;
5046        event.target = target;
5047        do {
5048          id = target[this.expando];
5049          if (id) {
5050            this.executeHandlers(event, id);
5051          }
5052          target = target.parentNode || target.ownerDocument || target.defaultView || target.parentWindow;
5053        } while (target && !event.isPropagationStopped());
5054        return this;
5055      };
5056      EventUtils.prototype.clean = function (target) {
5057        var i, children;
5058        if (!target || target.nodeType === 3 || target.nodeType === 8) {
5059          return this;
5060        }
5061        if (target[this.expando]) {
5062          this.unbind(target);
5063        }
5064        if (!target.getElementsByTagName) {
5065          target = target.document;
5066        }
5067        if (target && target.getElementsByTagName) {
5068          this.unbind(target);
5069          children = target.getElementsByTagName('*');
5070          i = children.length;
5071          while (i--) {
5072            target = children[i];
5073            if (target[this.expando]) {
5074              this.unbind(target);
5075            }
5076          }
5077        }
5078        return this;
5079      };
5080      EventUtils.prototype.destroy = function () {
5081        this.events = {};
5082      };
5083      EventUtils.prototype.cancel = function (e) {
5084        if (e) {
5085          e.preventDefault();
5086          e.stopImmediatePropagation();
5087        }
5088        return false;
5089      };
5090      EventUtils.prototype.executeHandlers = function (evt, id) {
5091        var container = this.events[id];
5092        var callbackList = container && container[evt.type];
5093        if (callbackList) {
5094          for (var i = 0, l = callbackList.length; i < l; i++) {
5095            var callback = callbackList[i];
5096            if (callback && callback.func.call(callback.scope, evt) === false) {
5097              evt.preventDefault();
5098            }
5099            if (evt.isImmediatePropagationStopped()) {
5100              return;
5101            }
5102          }
5103        }
5104      };
5105      EventUtils.Event = new EventUtils();
5106      return EventUtils;
5107    }();
5108
5109    var support, Expr, getText, isXML, tokenize, compile, select, outermostContext, sortInput, hasDuplicate, setDocument, document$1, docElem, documentIsHTML, rbuggyQSA, rbuggyMatches, matches, contains$3, expando = 'sizzle' + -new Date(), preferredDoc = window.document, dirruns = 0, done = 0, classCache = createCache(), tokenCache = createCache(), compilerCache = createCache(), sortOrder = function (a, b) {
5110        if (a === b) {
5111          hasDuplicate = true;
5112        }
5113        return 0;
5114      }, strundefined = typeof undefined, MAX_NEGATIVE = 1 << 31, hasOwn = {}.hasOwnProperty, arr = [], pop = arr.pop, push_native = arr.push, push = arr.push, slice = arr.slice, indexOf$2 = arr.indexOf || function (elem) {
5115        var i = 0, len = this.length;
5116        for (; i < len; i++) {
5117          if (this[i] === elem) {
5118            return i;
5119          }
5120        }
5121        return -1;
5122      }, booleans = 'checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped', whitespace = '[\\x20\\t\\r\\n\\f]', identifier = '(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+', attributes = '\\[' + whitespace + '*(' + identifier + ')(?:' + whitespace + '*([*^$|!~]?=)' + whitespace + '*(?:\'((?:\\\\.|[^\\\\\'])*)\'|"((?:\\\\.|[^\\\\"])*)"|(' + identifier + '))|)' + whitespace + '*\\]', pseudos = ':(' + identifier + ')(?:\\((' + '(\'((?:\\\\.|[^\\\\\'])*)\'|"((?:\\\\.|[^\\\\"])*)")|' + '((?:\\\\.|[^\\\\()[\\]]|' + attributes + ')*)|' + '.*' + ')\\)|)', rtrim = new RegExp('^' + whitespace + '+|((?:^|[^\\\\])(?:\\\\.)*)' + whitespace + '+$', 'g'), rcomma = new RegExp('^' + whitespace + '*,' + whitespace + '*'), rcombinators = new RegExp('^' + whitespace + '*([>+~]|' + whitespace + ')' + whitespace + '*'), rattributeQuotes = new RegExp('=' + whitespace + '*([^\\]\'"]*?)' + whitespace + '*\\]', 'g'), rpseudo = new RegExp(pseudos), ridentifier = new RegExp('^' + identifier + '$'), matchExpr = {
5123        ID: new RegExp('^#(' + identifier + ')'),
5124        CLASS: new RegExp('^\\.(' + identifier + ')'),
5125        TAG: new RegExp('^(' + identifier + '|[*])'),
5126        ATTR: new RegExp('^' + attributes),
5127        PSEUDO: new RegExp('^' + pseudos),
5128        CHILD: new RegExp('^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(' + whitespace + '*(even|odd|(([+-]|)(\\d*)n|)' + whitespace + '*(?:([+-]|)' + whitespace + '*(\\d+)|))' + whitespace + '*\\)|)', 'i'),
5129        bool: new RegExp('^(?:' + booleans + ')$', 'i'),
5130        needsContext: new RegExp('^' + whitespace + '*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(' + whitespace + '*((?:-\\d)?\\d*)' + whitespace + '*\\)|)(?=[^-]|$)', 'i')
5131      }, rinputs = /^(?:input|select|textarea|button)$/i, rheader = /^h\d$/i, rnative = /^[^{]+\{\s*\[native \w/, rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, rsibling = /[+~]/, rescape = /'|\\/g, runescape = new RegExp('\\\\([\\da-f]{1,6}' + whitespace + '?|(' + whitespace + ')|.)', 'ig'), funescape = function (_, escaped, escapedWhitespace) {
5132        var high = '0x' + escaped - 65536;
5133        return high !== high || escapedWhitespace ? escaped : high < 0 ? String.fromCharCode(high + 65536) : String.fromCharCode(high >> 10 | 55296, high & 1023 | 56320);
5134      };
5135    try {
5136      push.apply(arr = slice.call(preferredDoc.childNodes), preferredDoc.childNodes);
5137      arr[preferredDoc.childNodes.length].nodeType;
5138    } catch (e) {
5139      push = {
5140        apply: arr.length ? function (target, els) {
5141          push_native.apply(target, slice.call(els));
5142        } : function (target, els) {
5143          var j = target.length, i = 0;
5144          while (target[j++] = els[i++]) {
5145          }
5146          target.length = j - 1;
5147        }
5148      };
5149    }
5150    var Sizzle = function (selector, context, results, seed) {
5151      var match, elem, m, nodeType, i, groups, old, nid, newContext, newSelector;
5152      if ((context ? context.ownerDocument || context : preferredDoc) !== document$1) {
5153        setDocument(context);
5154      }
5155      context = context || document$1;
5156      results = results || [];
5157      if (!selector || typeof selector !== 'string') {
5158        return results;
5159      }
5160      if ((nodeType = context.nodeType) !== 1 && nodeType !== 9) {
5161        return [];
5162      }
5163      if (documentIsHTML && !seed) {
5164        if (match = rquickExpr.exec(selector)) {
5165          if (m = match[1]) {
5166            if (nodeType === 9) {
5167              elem = context.getElementById(m);
5168              if (elem && elem.parentNode) {
5169                if (elem.id === m) {
5170                  results.push(elem);
5171                  return results;
5172                }
5173              } else {
5174                return results;
5175              }
5176            } else {
5177              if (context.ownerDocument && (elem = context.ownerDocument.getElementById(m)) && contains$3(context, elem) && elem.id === m) {
5178                results.push(elem);
5179                return results;
5180              }
5181            }
5182          } else if (match[2]) {
5183            push.apply(results, context.getElementsByTagName(selector));
5184            return results;
5185          } else if ((m = match[3]) && support.getElementsByClassName) {
5186            push.apply(results, context.getElementsByClassName(m));
5187            return results;
5188          }
5189        }
5190        if (support.qsa && (!rbuggyQSA || !rbuggyQSA.test(selector))) {
5191          nid = old = expando;
5192          newContext = context;
5193          newSelector = nodeType === 9 && selector;
5194          if (nodeType === 1 && context.nodeName.toLowerCase() !== 'object') {
5195            groups = tokenize(selector);
5196            if (old = context.getAttribute('id')) {
5197              nid = old.replace(rescape, '\\$&');
5198            } else {
5199              context.setAttribute('id', nid);
5200            }
5201            nid = '[id=\'' + nid + '\'] ';
5202            i = groups.length;
5203            while (i--) {
5204              groups[i] = nid + toSelector(groups[i]);
5205            }
5206            newContext = rsibling.test(selector) && testContext(context.parentNode) || context;
5207            newSelector = groups.join(',');
5208          }
5209          if (newSelector) {
5210            try {
5211              push.apply(results, newContext.querySelectorAll(newSelector));
5212              return results;
5213            } catch (qsaError) {
5214            } finally {
5215              if (!old) {
5216                context.removeAttribute('id');
5217              }
5218            }
5219          }
5220        }
5221      }
5222      return select(selector.replace(rtrim, '$1'), context, results, seed);
5223    };
5224    function createCache() {
5225      var keys = [];
5226      function cache(key, value) {
5227        if (keys.push(key + ' ') > Expr.cacheLength) {
5228          delete cache[keys.shift()];
5229        }
5230        return cache[key + ' '] = value;
5231      }
5232      return cache;
5233    }
5234    function markFunction(fn) {
5235      fn[expando] = true;
5236      return fn;
5237    }
5238    function siblingCheck(a, b) {
5239      var cur = b && a, diff = cur && a.nodeType === 1 && b.nodeType === 1 && (~b.sourceIndex || MAX_NEGATIVE) - (~a.sourceIndex || MAX_NEGATIVE);
5240      if (diff) {
5241        return diff;
5242      }
5243      if (cur) {
5244        while (cur = cur.nextSibling) {
5245          if (cur === b) {
5246            return -1;
5247          }
5248        }
5249      }
5250      return a ? 1 : -1;
5251    }
5252    function createInputPseudo(type) {
5253      return function (elem) {
5254        var name = elem.nodeName.toLowerCase();
5255        return name === 'input' && elem.type === type;
5256      };
5257    }
5258    function createButtonPseudo(type) {
5259      return function (elem) {
5260        var name = elem.nodeName.toLowerCase();
5261        return (name === 'input' || name === 'button') && elem.type === type;
5262      };
5263    }
5264    function createPositionalPseudo(fn) {
5265      return markFunction(function (argument) {
5266        argument = +argument;
5267        return markFunction(function (seed, matches) {
5268          var j, matchIndexes = fn([], seed.length, argument), i = matchIndexes.length;
5269          while (i--) {
5270            if (seed[j = matchIndexes[i]]) {
5271              seed[j] = !(matches[j] = seed[j]);
5272            }
5273          }
5274        });
5275      });
5276    }
5277    function testContext(context) {
5278      return context && typeof context.getElementsByTagName !== strundefined && context;
5279    }
5280    support = Sizzle.support = {};
5281    isXML = Sizzle.isXML = function (elem) {
5282      var documentElement = elem && (elem.ownerDocument || elem).documentElement;
5283      return documentElement ? documentElement.nodeName !== 'HTML' : false;
5284    };
5285    setDocument = Sizzle.setDocument = function (node) {
5286      var hasCompare, doc = node ? node.ownerDocument || node : preferredDoc, parent = doc.defaultView;
5287      function getTop(win) {
5288        try {
5289          return win.top;
5290        } catch (ex) {
5291        }
5292        return null;
5293      }
5294      if (doc === document$1 || doc.nodeType !== 9 || !doc.documentElement) {
5295        return document$1;
5296      }
5297      document$1 = doc;
5298      docElem = doc.documentElement;
5299      documentIsHTML = !isXML(doc);
5300      if (parent && parent !== getTop(parent)) {
5301        if (parent.addEventListener) {
5302          parent.addEventListener('unload', function () {
5303            setDocument();
5304          }, false);
5305        } else if (parent.attachEvent) {
5306          parent.attachEvent('onunload', function () {
5307            setDocument();
5308          });
5309        }
5310      }
5311      support.attributes = true;
5312      support.getElementsByTagName = true;
5313      support.getElementsByClassName = rnative.test(doc.getElementsByClassName);
5314      support.getById = true;
5315      Expr.find.ID = function (id, context) {
5316        if (typeof context.getElementById !== strundefined && documentIsHTML) {
5317          var m = context.getElementById(id);
5318          return m && m.parentNode ? [m] : [];
5319        }
5320      };
5321      Expr.filter.ID = function (id) {
5322        var attrId = id.replace(runescape, funescape);
5323        return function (elem) {
5324          return elem.getAttribute('id') === attrId;
5325        };
5326      };
5327      Expr.find.TAG = support.getElementsByTagName ? function (tag, context) {
5328        if (typeof context.getElementsByTagName !== strundefined) {
5329          return context.getElementsByTagName(tag);
5330        }
5331      } : function (tag, context) {
5332        var elem, tmp = [], i = 0, results = context.getElementsByTagName(tag);
5333        if (tag === '*') {
5334          while (elem = results[i++]) {
5335            if (elem.nodeType === 1) {
5336              tmp.push(elem);
5337            }
5338          }
5339          return tmp;
5340        }
5341        return results;
5342      };
5343      Expr.find.CLASS = support.getElementsByClassName && function (className, context) {
5344        if (documentIsHTML) {
5345          return context.getElementsByClassName(className);
5346        }
5347      };
5348      rbuggyMatches = [];
5349      rbuggyQSA = [];
5350      support.disconnectedMatch = true;
5351      rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join('|'));
5352      rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join('|'));
5353      hasCompare = rnative.test(docElem.compareDocumentPosition);
5354      contains$3 = hasCompare || rnative.test(docElem.contains) ? function (a, b) {
5355        var adown = a.nodeType === 9 ? a.documentElement : a, bup = b && b.parentNode;
5356        return a === bup || !!(bup && bup.nodeType === 1 && (adown.contains ? adown.contains(bup) : a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16));
5357      } : function (a, b) {
5358        if (b) {
5359          while (b = b.parentNode) {
5360            if (b === a) {
5361              return true;
5362            }
5363          }
5364        }
5365        return false;
5366      };
5367      sortOrder = hasCompare ? function (a, b) {
5368        if (a === b) {
5369          hasDuplicate = true;
5370          return 0;
5371        }
5372        var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
5373        if (compare) {
5374          return compare;
5375        }
5376        compare = (a.ownerDocument || a) === (b.ownerDocument || b) ? a.compareDocumentPosition(b) : 1;
5377        if (compare & 1 || !support.sortDetached && b.compareDocumentPosition(a) === compare) {
5378          if (a === doc || a.ownerDocument === preferredDoc && contains$3(preferredDoc, a)) {
5379            return -1;
5380          }
5381          if (b === doc || b.ownerDocument === preferredDoc && contains$3(preferredDoc, b)) {
5382            return 1;
5383          }
5384          return sortInput ? indexOf$2.call(sortInput, a) - indexOf$2.call(sortInput, b) : 0;
5385        }
5386        return compare & 4 ? -1 : 1;
5387      } : function (a, b) {
5388        if (a === b) {
5389          hasDuplicate = true;
5390          return 0;
5391        }
5392        var cur, i = 0, aup = a.parentNode, bup = b.parentNode, ap = [a], bp = [b];
5393        if (!aup || !bup) {
5394          return a === doc ? -1 : b === doc ? 1 : aup ? -1 : bup ? 1 : sortInput ? indexOf$2.call(sortInput, a) - indexOf$2.call(sortInput, b) : 0;
5395        } else if (aup === bup) {
5396          return siblingCheck(a, b);
5397        }
5398        cur = a;
5399        while (cur = cur.parentNode) {
5400          ap.unshift(cur);
5401        }
5402        cur = b;
5403        while (cur = cur.parentNode) {
5404          bp.unshift(cur);
5405        }
5406        while (ap[i] === bp[i]) {
5407          i++;
5408        }
5409        return i ? siblingCheck(ap[i], bp[i]) : ap[i] === preferredDoc ? -1 : bp[i] === preferredDoc ? 1 : 0;
5410      };
5411      return doc;
5412    };
5413    Sizzle.matches = function (expr, elements) {
5414      return Sizzle(expr, null, null, elements);
5415    };
5416    Sizzle.matchesSelector = function (elem, expr) {
5417      if ((elem.ownerDocument || elem) !== document$1) {
5418        setDocument(elem);
5419      }
5420      expr = expr.replace(rattributeQuotes, '=\'$1\']');
5421      if (support.matchesSelector && documentIsHTML && (!rbuggyMatches || !rbuggyMatches.test(expr)) && (!rbuggyQSA || !rbuggyQSA.test(expr))) {
5422        try {
5423          var ret = matches.call(elem, expr);
5424          if (ret || support.disconnectedMatch || elem.document && elem.document.nodeType !== 11) {
5425            return ret;
5426          }
5427        } catch (e) {
5428        }
5429      }
5430      return Sizzle(expr, document$1, null, [elem]).length > 0;
5431    };
5432    Sizzle.contains = function (context, elem) {
5433      if ((context.ownerDocument || context) !== document$1) {
5434        setDocument(context);
5435      }
5436      return contains$3(context, elem);
5437    };
5438    Sizzle.attr = function (elem, name) {
5439      if ((elem.ownerDocument || elem) !== document$1) {
5440        setDocument(elem);
5441      }
5442      var fn = Expr.attrHandle[name.toLowerCase()], val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ? fn(elem, name, !documentIsHTML) : undefined;
5443      return val !== undefined ? val : support.attributes || !documentIsHTML ? elem.getAttribute(name) : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null;
5444    };
5445    Sizzle.error = function (msg) {
5446      throw new Error('Syntax error, unrecognized expression: ' + msg);
5447    };
5448    Sizzle.uniqueSort = function (results) {
5449      var elem, duplicates = [], j = 0, i = 0;
5450      hasDuplicate = !support.detectDuplicates;
5451      sortInput = !support.sortStable && results.slice(0);
5452      results.sort(sortOrder);
5453      if (hasDuplicate) {
5454        while (elem = results[i++]) {
5455          if (elem === results[i]) {
5456            j = duplicates.push(i);
5457          }
5458        }
5459        while (j--) {
5460          results.splice(duplicates[j], 1);
5461        }
5462      }
5463      sortInput = null;
5464      return results;
5465    };
5466    getText = Sizzle.getText = function (elem) {
5467      var node, ret = '', i = 0, nodeType = elem.nodeType;
5468      if (!nodeType) {
5469        while (node = elem[i++]) {
5470          ret += getText(node);
5471        }
5472      } else if (nodeType === 1 || nodeType === 9 || nodeType === 11) {
5473        if (typeof elem.textContent === 'string') {
5474          return elem.textContent;
5475        } else {
5476          for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
5477            ret += getText(elem);
5478          }
5479        }
5480      } else if (nodeType === 3 || nodeType === 4) {
5481        return elem.nodeValue;
5482      }
5483      return ret;
5484    };
5485    Expr = Sizzle.selectors = {
5486      cacheLength: 50,
5487      createPseudo: markFunction,
5488      match: matchExpr,
5489      attrHandle: {},
5490      find: {},
5491      relative: {
5492        '>': {
5493          dir: 'parentNode',
5494          first: true
5495        },
5496        ' ': { dir: 'parentNode' },
5497        '+': {
5498          dir: 'previousSibling',
5499          first: true
5500        },
5501        '~': { dir: 'previousSibling' }
5502      },
5503      preFilter: {
5504        ATTR: function (match) {
5505          match[1] = match[1].replace(runescape, funescape);
5506          match[3] = (match[3] || match[4] || match[5] || '').replace(runescape, funescape);
5507          if (match[2] === '~=') {
5508            match[3] = ' ' + match[3] + ' ';
5509          }
5510          return match.slice(0, 4);
5511        },
5512        CHILD: function (match) {
5513          match[1] = match[1].toLowerCase();
5514          if (match[1].slice(0, 3) === 'nth') {
5515            if (!match[3]) {
5516              Sizzle.error(match[0]);
5517            }
5518            match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === 'even' || match[3] === 'odd'));
5519            match[5] = +(match[7] + match[8] || match[3] === 'odd');
5520          } else if (match[3]) {
5521            Sizzle.error(match[0]);
5522          }
5523          return match;
5524        },
5525        PSEUDO: function (match) {
5526          var excess, unquoted = !match[6] && match[2];
5527          if (matchExpr.CHILD.test(match[0])) {
5528            return null;
5529          }
5530          if (match[3]) {
5531            match[2] = match[4] || match[5] || '';
5532          } else if (unquoted && rpseudo.test(unquoted) && (excess = tokenize(unquoted, true)) && (excess = unquoted.indexOf(')', unquoted.length - excess) - unquoted.length)) {
5533            match[0] = match[0].slice(0, excess);
5534            match[2] = unquoted.slice(0, excess);
5535          }
5536          return match.slice(0, 3);
5537        }
5538      },
5539      filter: {
5540        TAG: function (nodeNameSelector) {
5541          var nodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase();
5542          return nodeNameSelector === '*' ? function () {
5543            return true;
5544          } : function (elem) {
5545            return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
5546          };
5547        },
5548        CLASS: function (className) {
5549          var pattern = classCache[className + ' '];
5550          return pattern || (pattern = new RegExp('(^|' + whitespace + ')' + className + '(' + whitespace + '|$)')) && classCache(className, function (elem) {
5551            return pattern.test(typeof elem.className === 'string' && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute('class') || '');
5552          });
5553        },
5554        ATTR: function (name, operator, check) {
5555          return function (elem) {
5556            var result = Sizzle.attr(elem, name);
5557            if (result == null) {
5558              return operator === '!=';
5559            }
5560            if (!operator) {
5561              return true;
5562            }
5563            result += '';
5564            return operator === '=' ? result === check : operator === '!=' ? result !== check : operator === '^=' ? check && result.indexOf(check) === 0 : operator === '*=' ? check && result.indexOf(check) > -1 : operator === '$=' ? check && result.slice(-check.length) === check : operator === '~=' ? (' ' + result + ' ').indexOf(check) > -1 : operator === '|=' ? result === check || result.slice(0, check.length + 1) === check + '-' : false;
5565          };
5566        },
5567        CHILD: function (type, what, argument, first, last) {
5568          var simple = type.slice(0, 3) !== 'nth', forward = type.slice(-4) !== 'last', ofType = what === 'of-type';
5569          return first === 1 && last === 0 ? function (elem) {
5570            return !!elem.parentNode;
5571          } : function (elem, context, xml) {
5572            var cache, outerCache, node, diff, nodeIndex, start, dir = simple !== forward ? 'nextSibling' : 'previousSibling', parent = elem.parentNode, name = ofType && elem.nodeName.toLowerCase(), useCache = !xml && !ofType;
5573            if (parent) {
5574              if (simple) {
5575                while (dir) {
5576                  node = elem;
5577                  while (node = node[dir]) {
5578                    if (ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) {
5579                      return false;
5580                    }
5581                  }
5582                  start = dir = type === 'only' && !start && 'nextSibling';
5583                }
5584                return true;
5585              }
5586              start = [forward ? parent.firstChild : parent.lastChild];
5587              if (forward && useCache) {
5588                outerCache = parent[expando] || (parent[expando] = {});
5589                cache = outerCache[type] || [];
5590                nodeIndex = cache[0] === dirruns && cache[1];
5591                diff = cache[0] === dirruns && cache[2];
5592                node = nodeIndex && parent.childNodes[nodeIndex];
5593                while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) {
5594                  if (node.nodeType === 1 && ++diff && node === elem) {
5595                    outerCache[type] = [
5596                      dirruns,
5597                      nodeIndex,
5598                      diff
5599                    ];
5600                    break;
5601                  }
5602                }
5603              } else if (useCache && (cache = (elem[expando] || (elem[expando] = {}))[type]) && cache[0] === dirruns) {
5604                diff = cache[1];
5605              } else {
5606                while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) {
5607                  if ((ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) && ++diff) {
5608                    if (useCache) {
5609                      (node[expando] || (node[expando] = {}))[type] = [
5610                        dirruns,
5611                        diff
5612                      ];
5613                    }
5614                    if (node === elem) {
5615                      break;
5616                    }
5617                  }
5618                }
5619              }
5620              diff -= last;
5621              return diff === first || diff % first === 0 && diff / first >= 0;
5622            }
5623          };
5624        },
5625        PSEUDO: function (pseudo, argument) {
5626          var args, fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] || Sizzle.error('unsupported pseudo: ' + pseudo);
5627          if (fn[expando]) {
5628            return fn(argument);
5629          }
5630          if (fn.length > 1) {
5631            args = [
5632              pseudo,
5633              pseudo,
5634              '',
5635              argument
5636            ];
5637            return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ? markFunction(function (seed, matches) {
5638              var idx, matched = fn(seed, argument), i = matched.length;
5639              while (i--) {
5640                idx = indexOf$2.call(seed, matched[i]);
5641                seed[idx] = !(matches[idx] = matched[i]);
5642              }
5643            }) : function (elem) {
5644              return fn(elem, 0, args);
5645            };
5646          }
5647          return fn;
5648        }
5649      },
5650      pseudos: {
5651        not: markFunction(function (selector) {
5652          var input = [], results = [], matcher = compile(selector.replace(rtrim, '$1'));
5653          return matcher[expando] ? markFunction(function (seed, matches, context, xml) {
5654            var elem, unmatched = matcher(seed, null, xml, []), i = seed.length;
5655            while (i--) {
5656              if (elem = unmatched[i]) {
5657                seed[i] = !(matches[i] = elem);
5658              }
5659            }
5660          }) : function (elem, context, xml) {
5661            input[0] = elem;
5662            matcher(input, null, xml, results);
5663            return !results.pop();
5664          };
5665        }),
5666        has: markFunction(function (selector) {
5667          return function (elem) {
5668            return Sizzle(selector, elem).length > 0;
5669          };
5670        }),
5671        contains: markFunction(function (text) {
5672          text = text.replace(runescape, funescape);
5673          return function (elem) {
5674            return (elem.textContent || elem.innerText || getText(elem)).indexOf(text) > -1;
5675          };
5676        }),
5677        lang: markFunction(function (lang) {
5678          if (!ridentifier.test(lang || '')) {
5679            Sizzle.error('unsupported lang: ' + lang);
5680          }
5681          lang = lang.replace(runescape, funescape).toLowerCase();
5682          return function (elem) {
5683            var elemLang;
5684            do {
5685              if (elemLang = documentIsHTML ? elem.lang : elem.getAttribute('xml:lang') || elem.getAttribute('lang')) {
5686                elemLang = elemLang.toLowerCase();
5687                return elemLang === lang || elemLang.indexOf(lang + '-') === 0;
5688              }
5689            } while ((elem = elem.parentNode) && elem.nodeType === 1);
5690            return false;
5691          };
5692        }),
5693        target: function (elem) {
5694          var hash = window.location && window.location.hash;
5695          return hash && hash.slice(1) === elem.id;
5696        },
5697        root: function (elem) {
5698          return elem === docElem;
5699        },
5700        focus: function (elem) {
5701          return elem === document$1.activeElement && (!document$1.hasFocus || document$1.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
5702        },
5703        enabled: function (elem) {
5704          return elem.disabled === false;
5705        },
5706        disabled: function (elem) {
5707          return elem.disabled === true;
5708        },
5709        checked: function (elem) {
5710          var nodeName = elem.nodeName.toLowerCase();
5711          return nodeName === 'input' && !!elem.checked || nodeName === 'option' && !!elem.selected;
5712        },
5713        selected: function (elem) {
5714          if (elem.parentNode) {
5715            elem.parentNode.selectedIndex;
5716          }
5717          return elem.selected === true;
5718        },
5719        empty: function (elem) {
5720          for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
5721            if (elem.nodeType < 6) {
5722              return false;
5723            }
5724          }
5725          return true;
5726        },
5727        parent: function (elem) {
5728          return !Expr.pseudos.empty(elem);
5729        },
5730        header: function (elem) {
5731          return rheader.test(elem.nodeName);
5732        },
5733        input: function (elem) {
5734          return rinputs.test(elem.nodeName);
5735        },
5736        button: function (elem) {
5737          var name = elem.nodeName.toLowerCase();
5738          return name === 'input' && elem.type === 'button' || name === 'button';
5739        },
5740        text: function (elem) {
5741          var attr;
5742          return elem.nodeName.toLowerCase() === 'input' && elem.type === 'text' && ((attr = elem.getAttribute('type')) == null || attr.toLowerCase() === 'text');
5743        },
5744        first: createPositionalPseudo(function () {
5745          return [0];
5746        }),
5747        last: createPositionalPseudo(function (matchIndexes, length) {
5748          return [length - 1];
5749        }),
5750        eq: createPositionalPseudo(function (matchIndexes, length, argument) {
5751          return [argument < 0 ? argument + length : argument];
5752        }),
5753        even: createPositionalPseudo(function (matchIndexes, length) {
5754          var i = 0;
5755          for (; i < length; i += 2) {
5756            matchIndexes.push(i);
5757          }
5758          return matchIndexes;
5759        }),
5760        odd: createPositionalPseudo(function (matchIndexes, length) {
5761          var i = 1;
5762          for (; i < length; i += 2) {
5763            matchIndexes.push(i);
5764          }
5765          return matchIndexes;
5766        }),
5767        lt: createPositionalPseudo(function (matchIndexes, length, argument) {
5768          var i = argument < 0 ? argument + length : argument;
5769          for (; --i >= 0;) {
5770            matchIndexes.push(i);
5771          }
5772          return matchIndexes;
5773        }),
5774        gt: createPositionalPseudo(function (matchIndexes, length, argument) {
5775          var i = argument < 0 ? argument + length : argument;
5776          for (; ++i < length;) {
5777            matchIndexes.push(i);
5778          }
5779          return matchIndexes;
5780        })
5781      }
5782    };
5783    Expr.pseudos.nth = Expr.pseudos.eq;
5784    each([
5785      'radio',
5786      'checkbox',
5787      'file',
5788      'password',
5789      'image'
5790    ], function (i) {
5791      Expr.pseudos[i] = createInputPseudo(i);
5792    });
5793    each([
5794      'submit',
5795      'reset'
5796    ], function (i) {
5797      Expr.pseudos[i] = createButtonPseudo(i);
5798    });
5799    function setFilters() {
5800    }
5801    setFilters.prototype = Expr.filters = Expr.pseudos;
5802    Expr.setFilters = new setFilters();
5803    tokenize = Sizzle.tokenize = function (selector, parseOnly) {
5804      var matched, match, tokens, type, soFar, groups, preFilters, cached = tokenCache[selector + ' '];
5805      if (cached) {
5806        return parseOnly ? 0 : cached.slice(0);
5807      }
5808      soFar = selector;
5809      groups = [];
5810      preFilters = Expr.preFilter;
5811      while (soFar) {
5812        if (!matched || (match = rcomma.exec(soFar))) {
5813          if (match) {
5814            soFar = soFar.slice(match[0].length) || soFar;
5815          }
5816          groups.push(tokens = []);
5817        }
5818        matched = false;
5819        if (match = rcombinators.exec(soFar)) {
5820          matched = match.shift();
5821          tokens.push({
5822            value: matched,
5823            type: match[0].replace(rtrim, ' ')
5824          });
5825          soFar = soFar.slice(matched.length);
5826        }
5827        for (type in Expr.filter) {
5828          if (!Expr.filter.hasOwnProperty(type)) {
5829            continue;
5830          }
5831          if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] || (match = preFilters[type](match)))) {
5832            matched = match.shift();
5833            tokens.push({
5834              value: matched,
5835              type: type,
5836              matches: match
5837            });
5838            soFar = soFar.slice(matched.length);
5839          }
5840        }
5841        if (!matched) {
5842          break;
5843        }
5844      }
5845      return parseOnly ? soFar.length : soFar ? Sizzle.error(selector) : tokenCache(selector, groups).slice(0);
5846    };
5847    function toSelector(tokens) {
5848      var i = 0, len = tokens.length, selector = '';
5849      for (; i < len; i++) {
5850        selector += tokens[i].value;
5851      }
5852      return selector;
5853    }
5854    function addCombinator(matcher, combinator, base) {
5855      var dir = combinator.dir, checkNonElements = base && dir === 'parentNode', doneName = done++;
5856      return combinator.first ? function (elem, context, xml) {
5857        while (elem = elem[dir]) {
5858          if (elem.nodeType === 1 || checkNonElements) {
5859            return matcher(elem, context, xml);
5860          }
5861        }
5862      } : function (elem, context, xml) {
5863        var oldCache, outerCache, newCache = [
5864            dirruns,
5865            doneName
5866          ];
5867        if (xml) {
5868          while (elem = elem[dir]) {
5869            if (elem.nodeType === 1 || checkNonElements) {
5870              if (matcher(elem, context, xml)) {
5871                return true;
5872              }
5873            }
5874          }
5875        } else {
5876          while (elem = elem[dir]) {
5877            if (elem.nodeType === 1 || checkNonElements) {
5878              outerCache = elem[expando] || (elem[expando] = {});
5879              if ((oldCache = outerCache[dir]) && oldCache[0] === dirruns && oldCache[1] === doneName) {
5880                return newCache[2] = oldCache[2];
5881              } else {
5882                outerCache[dir] = newCache;
5883                if (newCache[2] = matcher(elem, context, xml)) {
5884                  return true;
5885                }
5886              }
5887            }
5888          }
5889        }
5890      };
5891    }
5892    function elementMatcher(matchers) {
5893      return matchers.length > 1 ? function (elem, context, xml) {
5894        var i = matchers.length;
5895        while (i--) {
5896          if (!matchers[i](elem, context, xml)) {
5897            return false;
5898          }
5899        }
5900        return true;
5901      } : matchers[0];
5902    }
5903    function multipleContexts(selector, contexts, results) {
5904      var i = 0, len = contexts.length;
5905      for (; i < len; i++) {
5906        Sizzle(selector, contexts[i], results);
5907      }
5908      return results;
5909    }
5910    function condense(unmatched, map, filter, context, xml) {
5911      var elem, newUnmatched = [], i = 0, len = unmatched.length, mapped = map != null;
5912      for (; i < len; i++) {
5913        if (elem = unmatched[i]) {
5914          if (!filter || filter(elem, context, xml)) {
5915            newUnmatched.push(elem);
5916            if (mapped) {
5917              map.push(i);
5918            }
5919          }
5920        }
5921      }
5922      return newUnmatched;
5923    }
5924    function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) {
5925      if (postFilter && !postFilter[expando]) {
5926        postFilter = setMatcher(postFilter);
5927      }
5928      if (postFinder && !postFinder[expando]) {
5929        postFinder = setMatcher(postFinder, postSelector);
5930      }
5931      return markFunction(function (seed, results, context, xml) {
5932        var temp, i, elem, preMap = [], postMap = [], preexisting = results.length, elems = seed || multipleContexts(selector || '*', context.nodeType ? [context] : context, []), matcherIn = preFilter && (seed || !selector) ? condense(elems, preMap, preFilter, context, xml) : elems, matcherOut = matcher ? postFinder || (seed ? preFilter : preexisting || postFilter) ? [] : results : matcherIn;
5933        if (matcher) {
5934          matcher(matcherIn, matcherOut, context, xml);
5935        }
5936        if (postFilter) {
5937          temp = condense(matcherOut, postMap);
5938          postFilter(temp, [], context, xml);
5939          i = temp.length;
5940          while (i--) {
5941            if (elem = temp[i]) {
5942              matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem);
5943            }
5944          }
5945        }
5946        if (seed) {
5947          if (postFinder || preFilter) {
5948            if (postFinder) {
5949              temp = [];
5950              i = matcherOut.length;
5951              while (i--) {
5952                if (elem = matcherOut[i]) {
5953                  temp.push(matcherIn[i] = elem);
5954                }
5955              }
5956              postFinder(null, matcherOut = [], temp, xml);
5957            }
5958            i = matcherOut.length;
5959            while (i--) {
5960              if ((elem = matcherOut[i]) && (temp = postFinder ? indexOf$2.call(seed, elem) : preMap[i]) > -1) {
5961                seed[temp] = !(results[temp] = elem);
5962              }
5963            }
5964          }
5965        } else {
5966          matcherOut = condense(matcherOut === results ? matcherOut.splice(preexisting, matcherOut.length) : matcherOut);
5967          if (postFinder) {
5968            postFinder(null, results, matcherOut, xml);
5969          } else {
5970            push.apply(results, matcherOut);
5971          }
5972        }
5973      });
5974    }
5975    function matcherFromTokens(tokens) {
5976      var checkContext, matcher, j, len = tokens.length, leadingRelative = Expr.relative[tokens[0].type], implicitRelative = leadingRelative || Expr.relative[' '], i = leadingRelative ? 1 : 0, matchContext = addCombinator(function (elem) {
5977          return elem === checkContext;
5978        }, implicitRelative, true), matchAnyContext = addCombinator(function (elem) {
5979          return indexOf$2.call(checkContext, elem) > -1;
5980        }, implicitRelative, true), matchers = [function (elem, context, xml) {
5981            return !leadingRelative && (xml || context !== outermostContext) || ((checkContext = context).nodeType ? matchContext(elem, context, xml) : matchAnyContext(elem, context, xml));
5982          }];
5983      for (; i < len; i++) {
5984        if (matcher = Expr.relative[tokens[i].type]) {
5985          matchers = [addCombinator(elementMatcher(matchers), matcher)];
5986        } else {
5987          matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches);
5988          if (matcher[expando]) {
5989            j = ++i;
5990            for (; j < len; j++) {
5991              if (Expr.relative[tokens[j].type]) {
5992                break;
5993              }
5994            }
5995            return setMatcher(i > 1 && elementMatcher(matchers), i > 1 && toSelector(tokens.slice(0, i - 1).concat({ value: tokens[i - 2].type === ' ' ? '*' : '' })).replace(rtrim, '$1'), matcher, i < j && matcherFromTokens(tokens.slice(i, j)), j < len && matcherFromTokens(tokens = tokens.slice(j)), j < len && toSelector(tokens));
5996          }
5997          matchers.push(matcher);
5998        }
5999      }
6000      return elementMatcher(matchers);
6001    }
6002    function matcherFromGroupMatchers(elementMatchers, setMatchers) {
6003      var bySet = setMatchers.length > 0, byElement = elementMatchers.length > 0, superMatcher = function (seed, context, xml, results, outermost) {
6004          var elem, j, matcher, matchedCount = 0, i = '0', unmatched = seed && [], setMatched = [], contextBackup = outermostContext, elems = seed || byElement && Expr.find.TAG('*', outermost), dirrunsUnique = dirruns += contextBackup == null ? 1 : Math.random() || 0.1, len = elems.length;
6005          if (outermost) {
6006            outermostContext = context !== document$1 && context;
6007          }
6008          for (; i !== len && (elem = elems[i]) != null; i++) {
6009            if (byElement && elem) {
6010              j = 0;
6011              while (matcher = elementMatchers[j++]) {
6012                if (matcher(elem, context, xml)) {
6013                  results.push(elem);
6014                  break;
6015                }
6016              }
6017              if (outermost) {
6018                dirruns = dirrunsUnique;
6019              }
6020            }
6021            if (bySet) {
6022              if (elem = !matcher && elem) {
6023                matchedCount--;
6024              }
6025              if (seed) {
6026                unmatched.push(elem);
6027              }
6028            }
6029          }
6030          matchedCount += i;
6031          if (bySet && i !== matchedCount) {
6032            j = 0;
6033            while (matcher = setMatchers[j++]) {
6034              matcher(unmatched, setMatched, context, xml);
6035            }
6036            if (seed) {
6037              if (matchedCount > 0) {
6038                while (i--) {
6039                  if (!(unmatched[i] || setMatched[i])) {
6040                    setMatched[i] = pop.call(results);
6041                  }
6042                }
6043              }
6044              setMatched = condense(setMatched);
6045            }
6046            push.apply(results, setMatched);
6047            if (outermost && !seed && setMatched.length > 0 && matchedCount + setMatchers.length > 1) {
6048              Sizzle.uniqueSort(results);
6049            }
6050          }
6051          if (outermost) {
6052            dirruns = dirrunsUnique;
6053            outermostContext = contextBackup;
6054          }
6055          return unmatched;
6056        };
6057      return bySet ? markFunction(superMatcher) : superMatcher;
6058    }
6059    compile = Sizzle.compile = function (selector, match) {
6060      var i, setMatchers = [], elementMatchers = [], cached = compilerCache[selector + ' '];
6061      if (!cached) {
6062        if (!match) {
6063          match = tokenize(selector);
6064        }
6065        i = match.length;
6066        while (i--) {
6067          cached = matcherFromTokens(match[i]);
6068          if (cached[expando]) {
6069            setMatchers.push(cached);
6070          } else {
6071            elementMatchers.push(cached);
6072          }
6073        }
6074        cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers));
6075        cached.selector = selector;
6076      }
6077      return cached;
6078    };
6079    select = Sizzle.select = function (selector, context, results, seed) {
6080      var i, tokens, token, type, find, compiled = typeof selector === 'function' && selector, match = !seed && tokenize(selector = compiled.selector || selector);
6081      results = results || [];
6082      if (match.length === 1) {
6083        tokens = match[0] = match[0].slice(0);
6084        if (tokens.length > 2 && (token = tokens[0]).type === 'ID' && support.getById && context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) {
6085          context = (Expr.find.ID(token.matches[0].replace(runescape, funescape), context) || [])[0];
6086          if (!context) {
6087            return results;
6088          } else if (compiled) {
6089            context = context.parentNode;
6090          }
6091          selector = selector.slice(tokens.shift().value.length);
6092        }
6093        i = matchExpr.needsContext.test(selector) ? 0 : tokens.length;
6094        while (i--) {
6095          token = tokens[i];
6096          if (Expr.relative[type = token.type]) {
6097            break;
6098          }
6099          if (find = Expr.find[type]) {
6100            if (seed = find(token.matches[0].replace(runescape, funescape), rsibling.test(tokens[0].type) && testC
6100ontext(context.parentNode) || context)) {
6101              tokens.splice(i, 1);
6102              selector = seed.length && toSelector(tokens);
6103              if (!selector) {
6104                push.apply(results, seed);
6105                return results;
6106              }
6107              break;
6108            }
6109          }
6110        }
6111      }
6112      (compiled || compile(selector, match))(seed, context, !documentIsHTML, results, rsibling.test(selector) && testContext(context.parentNode) || context);
6113      return results;
6114    };
6115    support.sortStable = expando.split('').sort(sortOrder).join('') === expando;
6116    support.detectDuplicates = !!hasDuplicate;
6117    setDocument();
6118    support.sortDetached = true;
6119
6120    var doc = document, push$1 = Array.prototype.push, slice$1 = Array.prototype.slice;
6121    var rquickExpr$1 = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/;
6122    var Event = EventUtils.Event;
6123    var skipUniques = Tools.makeMap('children,contents,next,prev');
6124    var isDefined = function (obj) {
6125      return typeof obj !== 'undefined';
6126    };
6127    var isString$1 = function (obj) {
6128      return typeof obj === 'string';
6129    };
6130    var isWindow = function (obj) {
6131      return obj && obj === obj.window;
6132    };
6133    var createFragment = function (html, fragDoc) {
6134      fragDoc = fragDoc || doc;
6135      var container = fragDoc.createElement('div');
6136      var frag = fragDoc.createDocumentFragment();
6137      container.innerHTML = html;
6138      var node;
6139      while (node = container.firstChild) {
6140        frag.appendChild(node);
6141      }
6142      return frag;
6143    };
6144    var domManipulate = function (targetNodes, sourceItem, callback, reverse) {
6145      var i;
6146      if (isString$1(sourceItem)) {
6147        sourceItem = createFragment(sourceItem, getElementDocument(targetNodes[0]));
6148      } else if (sourceItem.length && !sourceItem.nodeType) {
6149        sourceItem = DomQuery.makeArray(sourceItem);
6150        if (reverse) {
6151          for (i = sourceItem.length - 1; i >= 0; i--) {
6152            domManipulate(targetNodes, sourceItem[i], callback, reverse);
6153          }
6154        } else {
6155          for (i = 0; i < sourceItem.length; i++) {
6156            domManipulate(targetNodes, sourceItem[i], callback, reverse);
6157          }
6158        }
6159        return targetNodes;
6160      }
6161      if (sourceItem.nodeType) {
6162        i = targetNodes.length;
6163        while (i--) {
6164          callback.call(targetNodes[i], sourceItem);
6165        }
6166      }
6167      return targetNodes;
6168    };
6169    var hasClass = function (node, className) {
6170      return node && className && (' ' + node.className + ' ').indexOf(' ' + className + ' ') !== -1;
6171    };
6172    var wrap$1 = function (elements, wrapper, all) {
6173      var lastParent, newWrapper;
6174      wrapper = DomQuery(wrapper)[0];
6175      elements.each(function () {
6176        var self = this;
6177        if (!all || lastParent !== self.parentNode) {
6178          lastParent = self.parentNode;
6179          newWrapper = wrapper.cloneNode(false);
6180          self.parentNode.insertBefore(newWrapper, self);
6181          newWrapper.appendChild(self);
6182        } else {
6183          newWrapper.appendChild(self);
6184        }
6185      });
6186      return elements;
6187    };
6188    var numericCssMap = Tools.makeMap('fillOpacity fontWeight lineHeight opacity orphans widows zIndex zoom', ' ');
6189    var booleanMap = Tools.makeMap('checked compact declare defer disabled ismap multiple nohref noshade nowrap readonly selected', ' ');
6190    var propFix = {
6191      for: 'htmlFor',
6192      class: 'className',
6193      readonly: 'readOnly'
6194    };
6195    var cssFix = { float: 'cssFloat' };
6196    var attrHooks = {}, cssHooks = {};
6197    var DomQueryConstructor = function (selector, context) {
6198      return new DomQuery.fn.init(selector, context);
6199    };
6200    var inArray$1 = function (item, array) {
6201      var i;
6202      if (array.indexOf) {
6203        return array.indexOf(item);
6204      }
6205      i = array.length;
6206      while (i--) {
6207        if (array[i] === item) {
6208          return i;
6209        }
6210      }
6211      return -1;
6212    };
6213    var whiteSpaceRegExp$2 = /^\s*|\s*$/g;
6214    var trim$3 = function (str) {
6215      return str === null || str === undefined ? '' : ('' + str).replace(whiteSpaceRegExp$2, '');
6216    };
6217    var each$4 = function (obj, callback) {
6218      var length, key, i, value;
6219      if (obj) {
6220        length = obj.length;
6221        if (length === undefined) {
6222          for (key in obj) {
6223            if (obj.hasOwnProperty(key)) {
6224              value = obj[key];
6225              if (callback.call(value, key, value) === false) {
6226                break;
6227              }
6228            }
6229          }
6230        } else {
6231          for (i = 0; i < length; i++) {
6232            value = obj[i];
6233            if (callback.call(value, i, value) === false) {
6234              break;
6235            }
6236          }
6237        }
6238      }
6239      return obj;
6240    };
6241    var grep = function (array, callback) {
6242      var out = [];
6243      each$4(array, function (i, item) {
6244        if (callback(item, i)) {
6245          out.push(item);
6246        }
6247      });
6248      return out;
6249    };
6250    var getElementDocument = function (element) {
6251      if (!element) {
6252        return doc;
6253      }
6254      if (element.nodeType === 9) {
6255        return element;
6256      }
6257      return element.ownerDocument;
6258    };
6259    DomQueryConstructor.fn = DomQueryConstructor.prototype = {
6260      constructor: DomQueryConstructor,
6261      selector: '',
6262      context: null,
6263      length: 0,
6264      init: function (selector, context) {
6265        var self = this;
6266        var match, node;
6267        if (!selector) {
6268          return self;
6269        }
6270        if (selector.nodeType) {
6271          self.context = self[0] = selector;
6272          self.length = 1;
6273          return self;
6274        }
6275        if (context && context.nodeType) {
6276          self.context = context;
6277        } else {
6278          if (context) {
6279            return DomQuery(selector).attr(context);
6280          }
6281          self.context = context = document;
6282        }
6283        if (isString$1(selector)) {
6284          self.selector = selector;
6285          if (selector.charAt(0) === '<' && selector.charAt(selector.length - 1) === '>' && selector.length >= 3) {
6286            match = [
6287              null,
6288              selector,
6289              null
6290            ];
6291          } else {
6292            match = rquickExpr$1.exec(selector);
6293          }
6294          if (match) {
6295            if (match[1]) {
6296              node = createFragment(selector, getElementDocument(context)).firstChild;
6297              while (node) {
6298                push$1.call(self, node);
6299                node = node.nextSibling;
6300              }
6301            } else {
6302              node = getElementDocument(context).getElementById(match[2]);
6303              if (!node) {
6304                return self;
6305              }
6306              if (node.id !== match[2]) {
6307                return self.find(selector);
6308              }
6309              self.length = 1;
6310              self[0] = node;
6311            }
6312          } else {
6313            return DomQuery(context).find(selector);
6314          }
6315        } else {
6316          this.add(selector, false);
6317        }
6318        return self;
6319      },
6320      toArray: function () {
6321        return Tools.toArray(this);
6322      },
6323      add: function (items, sort) {
6324        var self = this;
6325        var nodes, i;
6326        if (isString$1(items)) {
6327          return self.add(DomQuery(items));
6328        }
6329        if (sort !== false) {
6330          nodes = DomQuery.unique(self.toArray().concat(DomQuery.makeArray(items)));
6331          self.length = nodes.length;
6332          for (i = 0; i < nodes.length; i++) {
6333            self[i] = nodes[i];
6334          }
6335        } else {
6336          push$1.apply(self, DomQuery.makeArray(items));
6337        }
6338        return self;
6339      },
6340      attr: function (name, value) {
6341        var self = this;
6342        var hook;
6343        if (typeof name === 'object') {
6344          each$4(name, function (name, value) {
6345            self.attr(name, value);
6346          });
6347        } else if (isDefined(value)) {
6348          this.each(function () {
6349            var hook;
6350            if (this.nodeType === 1) {
6351              hook = attrHooks[name];
6352              if (hook && hook.set) {
6353                hook.set(this, value);
6354                return;
6355              }
6356              if (value === null) {
6357                this.removeAttribute(name, 2);
6358              } else {
6359                this.setAttribute(name, value, 2);
6360              }
6361            }
6362          });
6363        } else {
6364          if (self[0] && self[0].nodeType === 1) {
6365            hook = attrHooks[name];
6366            if (hook && hook.get) {
6367              return hook.get(self[0], name);
6368            }
6369            if (booleanMap[name]) {
6370              return self.prop(name) ? name : undefined;
6371            }
6372            value = self[0].getAttribute(name, 2);
6373            if (value === null) {
6374              value = undefined;
6375            }
6376          }
6377          return value;
6378        }
6379        return self;
6380      },
6381      removeAttr: function (name) {
6382        return this.attr(name, null);
6383      },
6384      prop: function (name, value) {
6385        var self = this;
6386        name = propFix[name] || name;
6387        if (typeof name === 'object') {
6388          each$4(name, function (name, value) {
6389            self.prop(name, value);
6390          });
6391        } else if (isDefined(value)) {
6392          this.each(function () {
6393            if (this.nodeType === 1) {
6394              this[name] = value;
6395            }
6396          });
6397        } else {
6398          if (self[0] && self[0].nodeType && name in self[0]) {
6399            return self[0][name];
6400          }
6401          return value;
6402        }
6403        return self;
6404      },
6405      css: function (name, value) {
6406        var self = this;
6407        var elm, hook;
6408        var camel = function (name) {
6409          return name.replace(/-(\D)/g, function (a, b) {
6410            return b.toUpperCase();
6411          });
6412        };
6413        var dashed = function (name) {
6414          return name.replace(/[A-Z]/g, function (a) {
6415            return '-' + a;
6416          });
6417        };
6418        if (typeof name === 'object') {
6419          each$4(name, function (name, value) {
6420            self.css(name, value);
6421          });
6422        } else {
6423          if (isDefined(value)) {
6424            name = camel(name);
6425            if (typeof value === 'number' && !numericCssMap[name]) {
6426              value = value.toString() + 'px';
6427            }
6428            self.each(function () {
6429              var style = this.style;
6430              hook = cssHooks[name];
6431              if (hook && hook.set) {
6432                hook.set(this, value);
6433                return;
6434              }
6435              try {
6436                this.style[cssFix[name] || name] = value;
6437              } catch (ex) {
6438              }
6439              if (value === null || value === '') {
6440                if (style.removeProperty) {
6441                  style.removeProperty(dashed(name));
6442                } else {
6443                  style.removeAttribute(name);
6444                }
6445              }
6446            });
6447          } else {
6448            elm = self[0];
6449            hook = cssHooks[name];
6450            if (hook && hook.get) {
6451              return hook.get(elm);
6452            }
6453            if (elm.ownerDocument.defaultView) {
6454              try {
6455                return elm.ownerDocument.defaultView.getComputedStyle(elm, null).getPropertyValue(dashed(name));
6456              } catch (ex) {
6457                return undefined;
6458              }
6459            } else if (elm.currentStyle) {
6460              return elm.currentStyle[camel(name)];
6461            } else {
6462              return '';
6463            }
6464          }
6465        }
6466        return self;
6467      },
6468      remove: function () {
6469        var self = this;
6470        var node, i = this.length;
6471        while (i--) {
6472          node = self[i];
6473          Event.clean(node);
6474          if (node.parentNode) {
6475            node.parentNode.removeChild(node);
6476          }
6477        }
6478        return this;
6479      },
6480      empty: function () {
6481        var self = this;
6482        var node, i = this.length;
6483        while (i--) {
6484          node = self[i];
6485          while (node.firstChild) {
6486            node.removeChild(node.firstChild);
6487          }
6488        }
6489        return this;
6490      },
6491      html: function (value) {
6492        var self = this;
6493        var i;
6494        if (isDefined(value)) {
6495          i = self.length;
6496          try {
6497            while (i--) {
6498              self[i].innerHTML = value;
6499            }
6500          } catch (ex) {
6501            DomQuery(self[i]).empty().append(value);
6502          }
6503          return self;
6504        }
6505        return self[0] ? self[0].innerHTML : '';
6506      },
6507      text: function (value) {
6508        var self = this;
6509        var i;
6510        if (isDefined(value)) {
6511          i = self.length;
6512          while (i--) {
6513            if ('innerText' in self[i]) {
6514              self[i].innerText = value;
6515            } else {
6516              self[0].textContent = value;
6517            }
6518          }
6519          return self;
6520        }
6521        return self[0] ? self[0].innerText || self[0].textContent : '';
6522      },
6523      append: function () {
6524        return domManipulate(this, arguments, function (node) {
6525          if (this.nodeType === 1 || this.host && this.host.nodeType === 1) {
6526            this.appendChild(node);
6527          }
6528        });
6529      },
6530      prepend: function () {
6531        return domManipulate(this, arguments, function (node) {
6532          if (this.nodeType === 1 || this.host && this.host.nodeType === 1) {
6533            this.insertBefore(node, this.firstChild);
6534          }
6535        }, true);
6536      },
6537      before: function () {
6538        var self = this;
6539        if (self[0] && self[0].parentNode) {
6540          return domManipulate(self, arguments, function (node) {
6541            this.parentNode.insertBefore(node, this);
6542          });
6543        }
6544        return self;
6545      },
6546      after: function () {
6547        var self = this;
6548        if (self[0] && self[0].parentNode) {
6549          return domManipulate(self, arguments, function (node) {
6550            this.parentNode.insertBefore(node, this.nextSibling);
6551          }, true);
6552        }
6553        return self;
6554      },
6555      appendTo: function (val) {
6556        DomQuery(val).append(this);
6557        return this;
6558      },
6559      prependTo: function (val) {
6560        DomQuery(val).prepend(this);
6561        return this;
6562      },
6563      replaceWith: function (content) {
6564        return this.before(content).remove();
6565      },
6566      wrap: function (content) {
6567        return wrap$1(this, content);
6568      },
6569      wrapAll: function (content) {
6570        return wrap$1(this, content, true);
6571      },
6572      wrapInner: function (content) {
6573        this.each(function () {
6574          DomQuery(this).contents().wrapAll(content);
6575        });
6576        return this;
6577      },
6578      unwrap: function () {
6579        return this.parent().each(function () {
6580          DomQuery(this).replaceWith(this.childNodes);
6581        });
6582      },
6583      clone: function () {
6584        var result = [];
6585        this.each(function () {
6586          result.push(this.cloneNode(true));
6587        });
6588        return DomQuery(result);
6589      },
6590      addClass: function (className) {
6591        return this.toggleClass(className, true);
6592      },
6593      removeClass: function (className) {
6594        return this.toggleClass(className, false);
6595      },
6596      toggleClass: function (className, state) {
6597        var self = this;
6598        if (typeof className !== 'string') {
6599          return self;
6600        }
6601        if (className.indexOf(' ') !== -1) {
6602          each$4(className.split(' '), function () {
6603            self.toggleClass(this, state);
6604          });
6605        } else {
6606          self.each(function (index, node) {
6607            var classState = hasClass(node, className);
6608            if (classState !== state) {
6609              var existingClassName = node.className;
6610              if (classState) {
6611                node.className = trim$3((' ' + existingClassName + ' ').replace(' ' + className + ' ', ' '));
6612              } else {
6613                node.className += existingClassName ? ' ' + className : className;
6614              }
6615            }
6616          });
6617        }
6618        return self;
6619      },
6620      hasClass: function (className) {
6621        return hasClass(this[0], className);
6622      },
6623      each: function (callback) {
6624        return each$4(this, callback);
6625      },
6626      on: function (name, callback) {
6627        return this.each(function () {
6628          Event.bind(this, name, callback);
6629        });
6630      },
6631      off: function (name, callback) {
6632        return this.each(function () {
6633          Event.unbind(this, name, callback);
6634        });
6635      },
6636      trigger: function (name) {
6637        return this.each(function () {
6638          if (typeof name === 'object') {
6639            Event.fire(this, name.type, name);
6640          } else {
6641            Event.fire(this, name);
6642          }
6643        });
6644      },
6645      show: function () {
6646        return this.css('display', '');
6647      },
6648      hide: function () {
6649        return this.css('display', 'none');
6650      },
6651      slice: function () {
6652        return new DomQuery(slice$1.apply(this, arguments));
6653      },
6654      eq: function (index) {
6655        return index === -1 ? this.slice(index) : this.slice(index, +index + 1);
6656      },
6657      first: function () {
6658        return this.eq(0);
6659      },
6660      last: function () {
6661        return this.eq(-1);
6662      },
6663      find: function (selector) {
6664        var i, l;
6665        var ret = [];
6666        for (i = 0, l = this.length; i < l; i++) {
6667          DomQuery.find(selector, this[i], ret);
6668        }
6669        return DomQuery(ret);
6670      },
6671      filter: function (selector) {
6672        if (typeof selector === 'function') {
6673          return DomQuery(grep(this.toArray(), function (item, i) {
6674            return selector(i, item);
6675          }));
6676        }
6677        return DomQuery(DomQuery.filter(selector, this.toArray()));
6678      },
6679      closest: function (selector) {
6680        var result = [];
6681        if (selector instanceof DomQuery) {
6682          selector = selector[0];
6683        }
6684        this.each(function (i, node) {
6685          while (node) {
6686            if (typeof selector === 'string' && DomQuery(node).is(selector)) {
6687              result.push(node);
6688              break;
6689            } else if (node === selector) {
6690              result.push(node);
6691              break;
6692            }
6693            node = node.parentNode;
6694          }
6695        });
6696        return DomQuery(result);
6697      },
6698      offset: function (offset) {
6699        var elm, doc, docElm;
6700        var x = 0, y = 0, pos;
6701        if (!offset) {
6702          elm = this[0];
6703          if (elm) {
6704            doc = elm.ownerDocument;
6705            docElm = doc.documentElement;
6706            if (elm.getBoundingClientRect) {
6707              pos = elm.getBoundingClientRect();
6708              x = pos.left + (docElm.scrollLeft || doc.body.scrollLeft) - docElm.clientLeft;
6709              y = pos.top + (docElm.scrollTop || doc.body.scrollTop) - docElm.clientTop;
6710            }
6711          }
6712          return {
6713            left: x,
6714            top: y
6715          };
6716        }
6717        return this.css(offset);
6718      },
6719      push: push$1,
6720      sort: Array.prototype.sort,
6721      splice: Array.prototype.splice
6722    };
6723    Tools.extend(DomQueryConstructor, {
6724      extend: Tools.extend,
6725      makeArray: function (object) {
6726        if (isWindow(object) || object.nodeType) {
6727          return [object];
6728        }
6729        return Tools.toArray(object);
6730      },
6731      inArray: inArray$1,
6732      isArray: Tools.isArray,
6733      each: each$4,
6734      trim: trim$3,
6735      grep: grep,
6736      find: Sizzle,
6737      expr: Sizzle.selectors,
6738      unique: Sizzle.uniqueSort,
6739      text: Sizzle.getText,
6740      contains: Sizzle.contains,
6741      filter: function (expr, elems, not) {
6742        var i = elems.length;
6743        if (not) {
6744          expr = ':not(' + expr + ')';
6745        }
6746        while (i--) {
6747          if (elems[i].nodeType !== 1) {
6748            elems.splice(i, 1);
6749          }
6750        }
6751        if (elems.length === 1) {
6752          elems = DomQuery.find.matchesSelector(elems[0], expr) ? [elems[0]] : [];
6753        } else {
6754          elems = DomQuery.find.matches(expr, elems);
6755        }
6756        return elems;
6757      }
6758    });
6759    var dir = function (el, prop, until) {
6760      var matched = [];
6761      var cur = el[prop];
6762      if (typeof until !== 'string' && until instanceof DomQuery) {
6763        until = until[0];
6764      }
6765      while (cur && cur.nodeType !== 9) {
6766        if (until !== undefined) {
6767          if (cur === until) {
6768            break;
6769          }
6770          if (typeof until === 'string' && DomQuery(cur).is(until)) {
6771            break;
6772          }
6773        }
6774        if (cur.nodeType === 1) {
6775          matched.push(cur);
6776        }
6777        cur = cur[prop];
6778      }
6779      return matched;
6780    };
6781    var sibling = function (node, siblingName, nodeType, until) {
6782      var result = [];
6783      if (until instanceof DomQuery) {
6784        until = until[0];
6785      }
6786      for (; node; node = node[siblingName]) {
6787        if (nodeType && node.nodeType !== nodeType) {
6788          continue;
6789        }
6790        if (until !== undefined) {
6791          if (node === until) {
6792            break;
6793          }
6794          if (typeof until === 'string' && DomQuery(node).is(until)) {
6795            break;
6796          }
6797        }
6798        result.push(node);
6799      }
6800      return result;
6801    };
6802    var firstSibling = function (node, siblingName, nodeType) {
6803      for (node = node[siblingName]; node; node = node[siblingName]) {
6804        if (node.nodeType === nodeType) {
6805          return node;
6806        }
6807      }
6808      return null;
6809    };
6810    each$4({
6811      parent: function (node) {
6812        var parent = node.parentNode;
6813        return parent && parent.nodeType !== 11 ? parent : null;
6814      },
6815      parents: function (node) {
6816        return dir(node, 'parentNode');
6817      },
6818      next: function (node) {
6819        return firstSibling(node, 'nextSibling', 1);
6820      },
6821      prev: function (node) {
6822        return firstSibling(node, 'previousSibling', 1);
6823      },
6824      children: function (node) {
6825        return sibling(node.firstChild, 'nextSibling', 1);
6826      },
6827      contents: function (node) {
6828        return Tools.toArray((node.nodeName === 'iframe' ? node.contentDocument || node.contentWindow.document : node).childNodes);
6829      }
6830    }, function (name, fn) {
6831      DomQueryConstructor.fn[name] = function (selector) {
6832        var self = this;
6833        var result = [];
6834        self.each(function () {
6835          var nodes = fn.call(result, this, selector, result);
6836          if (nodes) {
6837            if (DomQuery.isArray(nodes)) {
6838              result.push.apply(result, nodes);
6839            } else {
6840              result.push(nodes);
6841            }
6842          }
6843        });
6844        if (this.length > 1) {
6845          if (!skipUniques[name]) {
6846            result = DomQuery.unique(result);
6847          }
6848          if (name.indexOf('parents') === 0) {
6849            result = result.reverse();
6850          }
6851        }
6852        var wrappedResult = DomQuery(result);
6853        if (selector) {
6854          return wrappedResult.filter(selector);
6855        }
6856        return wrappedResult;
6857      };
6858    });
6859    each$4({
6860      parentsUntil: function (node, until) {
6861        return dir(node, 'parentNode', until);
6862      },
6863      nextUntil: function (node, until) {
6864        return sibling(node, 'nextSibling', 1, until).slice(1);
6865      },
6866      prevUntil: function (node, until) {
6867        return sibling(node, 'previousSibling', 1, until).slice(1);
6868      }
6869    }, function (name, fn) {
6870      DomQueryConstructor.fn[name] = function (selector, filter) {
6871        var self = this;
6872        var result = [];
6873        self.each(function () {
6874          var nodes = fn.call(result, this, selector, result);
6875          if (nodes) {
6876            if (DomQuery.isArray(nodes)) {
6877              result.push.apply(result, nodes);
6878            } else {
6879              result.push(nodes);
6880            }
6881          }
6882        });
6883        if (this.length > 1) {
6884          result = DomQuery.unique(result);
6885          if (name.indexOf('parents') === 0 || name === 'prevUntil') {
6886            result = result.reverse();
6887          }
6888        }
6889        var wrappedResult = DomQuery(result);
6890        if (filter) {
6891          return wrappedResult.filter(filter);
6892        }
6893        return wrappedResult;
6894      };
6895    });
6896    DomQueryConstructor.fn.is = function (selector) {
6897      return !!selector && this.filter(selector).length > 0;
6898    };
6899    DomQueryConstructor.fn.init.prototype = DomQueryConstructor.fn;
6900    DomQueryConstructor.overrideDefaults = function (callback) {
6901      var defaults;
6902      var sub = function (selector, context) {
6903        defaults = defaults || callback();
6904        if (arguments.length === 0) {
6905          selector = defaults.element;
6906        }
6907        if (!context) {
6908          context = defaults.context;
6909        }
6910        return new sub.fn.init(selector, context);
6911      };
6912      DomQuery.extend(sub, this);
6913      return sub;
6914    };
6915    DomQueryConstructor.attrHooks = attrHooks;
6916    DomQueryConstructor.cssHooks = cssHooks;
6917    var DomQuery = DomQueryConstructor;
6918
6919    var each$5 = Tools.each;
6920    var grep$1 = Tools.grep;
6921    var isIE = Env.ie;
6922    var simpleSelectorRe = /^([a-z0-9],?)+$/i;
6923    var setupAttrHooks = function (styles, settings, getContext) {
6924      var keepValues = settings.keep_values;
6925      var keepUrlHook = {
6926        set: function ($elm, value, name) {
6927          if (settings.url_converter) {
6928            value = settings.url_converter.call(settings.url_converter_scope || getContext(), value, name, $elm[0]);
6929          }
6930          $elm.attr('data-mce-' + name, value).attr(name, value);
6931        },
6932        get: function ($elm, name) {
6933          return $elm.attr('data-mce-' + name) || $elm.attr(name);
6934        }
6935      };
6936      var attrHooks = {
6937        style: {
6938          set: function ($elm, value) {
6939            if (value !== null && typeof value === 'object') {
6940              $elm.css(value);
6941              return;
6942            }
6943            if (keepValues) {
6944              $elm.attr('data-mce-style', value);
6945            }
6946            if (value !== null && typeof value === 'string') {
6947              $elm.removeAttr('style');
6948              $elm.css(styles.parse(value));
6949            } else {
6950              $elm.attr('style', value);
6951            }
6952          },
6953          get: function ($elm) {
6954            var value = $elm.attr('data-mce-style') || $elm.attr('style');
6955            value = styles.serialize(styles.parse(value), $elm[0].nodeName);
6956            return value;
6957          }
6958        }
6959      };
6960      if (keepValues) {
6961        attrHooks.href = attrHooks.src = keepUrlHook;
6962      }
6963      return attrHooks;
6964    };
6965    var updateInternalStyleAttr = function (styles, $elm) {
6966      var rawValue = $elm.attr('style');
6967      var value = styles.serialize(styles.parse(rawValue), $elm[0].nodeName);
6968      if (!value) {
6969        value = null;
6970      }
6971      $elm.attr('data-mce-style', value);
6972    };
6973    var findNodeIndex = function (node, normalized) {
6974      var idx = 0, lastNodeType, nodeType;
6975      if (node) {
6976        for (lastNodeType = node.nodeType, node = node.previousSibling; node; node = node.previousSibling) {
6977          nodeType = node.nodeType;
6978          if (normalized && nodeType === 3) {
6979            if (nodeType === lastNodeType || !node.nodeValue.length) {
6980              continue;
6981            }
6982          }
6983          idx++;
6984          lastNodeType = nodeType;
6985        }
6986      }
6987      return idx;
6988    };
6989    function DOMUtils(doc, settings) {
6990      var _this = this;
6991      if (settings === void 0) {
6992        settings = {};
6993      }
6994      var addedStyles = {};
6995      var win = window;
6996      var files = {};
6997      var counter = 0;
6998      var stdMode = true;
6999      var boxModel = true;
7000      var styleSheetLoader = instance.forElement(SugarElement.fromDom(doc), {
7001        contentCssCors: settings.contentCssCors,
7002        referrerPolicy: settings.referrerPolicy
7003      });
7004      var boundEvents = [];
7005      var schema = settings.schema ? settings.schema : Schema({});
7006      var styles = Styles({
7007        url_converter: settings.url_converter,
7008        url_converter_scope: settings.url_converter_scope
7009      }, settings.schema);
7010      var events = settings.ownEvents ? new EventUtils() : EventUtils.Event;
7011      var blockElementsMap = schema.getBlockElements();
7012      var $ = DomQuery.overrideDefaults(function () {
7013        return {
7014          context: doc,
7015          element: self.getRoot()
7016        };
7017      });
7018      var isBlock = function (node) {
7019        if (typeof node === 'string') {
7020          return !!blockElementsMap[node];
7021        } else if (node) {
7022          var type = node.nodeType;
7023          if (type) {
7024            return !!(type === 1 && blockElementsMap[node.nodeName]);
7025          }
7026        }
7027        return false;
7028      };
7029      var get = function (elm) {
7030        return elm && doc && isString(elm) ? doc.getElementById(elm) : elm;
7031      };
7032      var $$ = function (elm) {
7033        return $(typeof elm === 'string' ? get(elm) : elm);
7034      };
7035      var getAttrib = function (elm, name, defaultVal) {
7036        var hook, value;
7037        var $elm = $$(elm);
7038        if ($elm.length) {
7039          hook = attrHooks[name];
7040          if (hook && hook.get) {
7041            value = hook.get($elm, name);
7042          } else {
7043            value = $elm.attr(name);
7044          }
7045        }
7046        if (typeof value === 'undefined') {
7047          value = defaultVal || '';
7048        }
7049        return value;
7050      };
7051      var getAttribs = function (elm) {
7052        var node = get(elm);
7053        if (!node) {
7054          return [];
7055        }
7056        return node.attributes;
7057      };
7058      var setAttrib = function (elm, name, value) {
7059        if (value === '') {
7060          value = null;
7061        }
7062        var $elm = $$(elm);
7063        var originalValue = $elm.attr(name);
7064        if (!$elm.length) {
7065          return;
7066        }
7067        var hook = attrHooks[name];
7068        if (hook && hook.set) {
7069          hook.set($elm, value, name);
7070        } else {
7071          $elm.attr(name, value);
7072        }
7073        if (originalValue !== value && settings.onSetAttrib) {
7074          settings.onSetAttrib({
7075            attrElm: $elm,
7076            attrName: name,
7077            attrValue: value
7078          });
7079        }
7080      };
7081      var clone = function (node, deep) {
7082        if (!isIE || node.nodeType !== 1 || deep) {
7083          return node.cloneNode(deep);
7084        } else {
7085          var clone_1 = doc.createElement(node.nodeName);
7086          each$5(getAttribs(node), function (attr) {
7087            setAttrib(clone_1, attr.nodeName, getAttrib(node, attr.nodeName));
7088          });
7089          return clone_1;
7090        }
7091      };
7092      var getRoot = function () {
7093        return settings.root_element || doc.body;
7094      };
7095      var getViewPort = function (argWin) {
7096        var vp = getBounds(argWin);
7097        return {
7098          x: vp.x,
7099          y: vp.y,
7100          w: vp.width,
7101          h: vp.height
7102        };
7103      };
7104      var getPos$1 = function (elm, rootElm) {
7105        return getPos(doc.body, get(elm), rootElm);
7106      };
7107      var setStyle = function (elm, name, value) {
7108        var $elm = isString(name) ? $$(elm).css(name, value) : $$(elm).css(name);
7109        if (settings.update_styles) {
7110          updateInternalStyleAttr(styles, $elm);
7111        }
7112      };
7113      var setStyles = function (elm, stylesArg) {
7114        var $elm = $$(elm).css(stylesArg);
7115        if (settings.update_styles) {
7116          updateInternalStyleAttr(styles, $elm);
7117        }
7118      };
7119      var getStyle = function (elm, name, computed) {
7120        var $elm = $$(elm);
7121        if (computed) {
7122          return $elm.css(name);
7123        }
7124        name = name.replace(/-(\D)/g, function (a, b) {
7125          return b.toUpperCase();
7126        });
7127        if (name === 'float') {
7128          name = Env.browser.isIE() ? 'styleFloat' : 'cssFloat';
7129        }
7130        return $elm[0] && $elm[0].style ? $elm[0].style[name] : undefined;
7131      };
7132      var getSize = function (elm) {
7133        var w, h;
7134        elm = get(elm);
7135        w = getStyle(elm, 'width');
7136        h = getStyle(elm, 'height');
7137        if (w.indexOf('px') === -1) {
7138          w = 0;
7139        }
7140        if (h.indexOf('px') === -1) {
7141          h = 0;
7142        }
7143        return {
7144          w: parseInt(w, 10) || elm.offsetWidth || elm.clientWidth,
7145          h: parseInt(h, 10) || elm.offsetHeight || elm.clientHeight
7146        };
7147      };
7148      var getRect = function (elm) {
7149        elm = get(elm);
7150        var pos = getPos$1(elm);
7151        var size = getSize(elm);
7152        return {
7153          x: pos.x,
7154          y: pos.y,
7155          w: size.w,
7156          h: size.h
7157        };
7158      };
7159      var is = function (elm, selector) {
7160        var i;
7161        if (!elm) {
7162          return false;
7163        }
7164        if (!Array.isArray(elm)) {
7165          if (selector === '*') {
7166            return elm.nodeType === 1;
7167          }
7168          if (simpleSelectorRe.test(selector)) {
7169            var selectors = selector.toLowerCase().split(/,/);
7170            var elmName = elm.nodeName.toLowerCase();
7171            for (i = selectors.length - 1; i >= 0; i--) {
7172              if (selectors[i] === elmName) {
7173                return true;
7174              }
7175            }
7176            return false;
7177          }
7178          if (elm.nodeType && elm.nodeType !== 1) {
7179            return false;
7180          }
7181        }
7182        var elms = !Array.isArray(elm) ? [elm] : elm;
7183        return Sizzle(selector, elms[0].ownerDocument || elms[0], null, elms).length > 0;
7184      };
7185      var getParents = function (elm, selector, root, collect) {
7186        var result = [];
7187        var selectorVal;
7188        var node = get(elm);
7189        collect = collect === undefined;
7190        root = root || (getRoot().nodeName !== 'BODY' ? getRoot().parentNode : null);
7191        if (Tools.is(selector, 'string')) {
7192          selectorVal = selector;
7193          if (selector === '*') {
7194            selector = function (node) {
7195              return node.nodeType === 1;
7196            };
7197          } else {
7198            selector = function (node) {
7199              return is(node, selectorVal);
7200            };
7201          }
7202        }
7203        while (node) {
7204          if (node === root || !node.nodeType || node.nodeType === 9) {
7205            break;
7206          }
7207          if (!selector || typeof selector === 'function' && selector(node)) {
7208            if (collect) {
7209              result.push(node);
7210            } else {
7211              return [node];
7212            }
7213          }
7214          node = node.parentNode;
7215        }
7216        return collect ? result : null;
7217      };
7218      var getParent = function (node, selector, root) {
7219        var parents = getParents(node, selector, root, false);
7220        return parents && parents.length > 0 ? parents[0] : null;
7221      };
7222      var _findSib = function (node, selector, name) {
7223        var func = selector;
7224        if (node) {
7225          if (typeof selector === 'string') {
7226            func = function (node) {
7227              return is(node, selector);
7228            };
7229          }
7230          for (node = node[name]; node; node = node[name]) {
7231            if (typeof func === 'function' && func(node)) {
7232              return node;
7233            }
7234          }
7235        }
7236        return null;
7237      };
7238      var getNext = function (node, selector) {
7239        return _findSib(node, selector, 'nextSibling');
7240      };
7241      var getPrev = function (node, selector) {
7242        return _findSib(node, selector, 'previousSibling');
7243      };
7244      var select = function (selector, scope) {
7245        return Sizzle(selector, get(scope) || settings.root_element || doc, []);
7246      };
7247      var run = function (elm, func, scope) {
7248        var result;
7249        var node = typeof elm === 'string' ? get(elm) : elm;
7250        if (!node) {
7251          return false;
7252        }
7253        if (Tools.isArray(node) && (node.length || node.length === 0)) {
7254          result = [];
7255          each$5(node, function (elm, i) {
7256            if (elm) {
7257              result.push(func.call(scope, typeof elm === 'string' ? get(elm) : elm, i));
7258            }
7259          });
7260          return result;
7261        }
7262        var context = scope ? scope : _this;
7263        return func.call(context, node);
7264      };
7265      var setAttribs = function (elm, attrs) {
7266        $$(elm).each(function (i, node) {
7267          each$5(attrs, function (value, name) {
7268            setAttrib(node, name, value);
7269          });
7270        });
7271      };
7272      var setHTML = function (elm, html) {
7273        var $elm = $$(elm);
7274        if (isIE) {
7275          $elm.each(function (i, target) {
7276            if (target.canHaveHTML === false) {
7277              return;
7278            }
7279            while (target.firstChild) {
7280              target.removeChild(target.firstChild);
7281            }
7282            try {
7283              target.innerHTML = '<br>' + html;
7284              target.removeChild(target.firstChild);
7285            } catch (ex) {
7286              DomQuery('<div></div>').html('<br>' + html).contents().slice(1).appendTo(target);
7287            }
7288            return html;
7289          });
7290        } else {
7291          $elm.html(html);
7292        }
7293      };
7294      var add = function (parentElm, name, attrs, html, create) {
7295        return run(parentElm, function (parentElm) {
7296          var newElm = typeof name === 'string' ? doc.createElement(name) : name;
7297          setAttribs(newElm, attrs);
7298          if (html) {
7299            if (typeof html !== 'string' && html.nodeType) {
7300              newElm.appendChild(html);
7301            } else if (typeof html === 'string') {
7302              setHTML(newElm, html);
7303            }
7304          }
7305          return !create ? parentElm.appendChild(newElm) : newElm;
7306        });
7307      };
7308      var create = function (name, attrs, html) {
7309        return add(doc.createElement(name), name, attrs, html, true);
7310      };
7311      var decode = Entities.decode;
7312      var encode = Entities.encodeAllRaw;
7313      var createHTML = function (name, attrs, html) {
7314        var outHtml = '', key;
7315        outHtml += '<' + name;
7316        for (key in attrs) {
7317          if (attrs.hasOwnProperty(key) && attrs[key] !== null && typeof attrs[key] !== 'undefined') {
7318            outHtml += ' ' + key + '="' + encode(attrs[key]) + '"';
7319          }
7320        }
7321        if (typeof html !== 'undefined') {
7322          return outHtml + '>' + html + '</' + name + '>';
7323        }
7324        return outHtml + ' />';
7325      };
7326      var createFragment = function (html) {
7327        var node;
7328        var container = doc.createElement('div');
7329        var frag = doc.createDocumentFragment();
7330        frag.appendChild(container);
7331        if (html) {
7332          container.innerHTML = html;
7333        }
7334        while (node = container.firstChild) {
7335          frag.appendChild(node);
7336        }
7337        frag.removeChild(container);
7338        return frag;
7339      };
7340      var remove = function (node, keepChildren) {
7341        var $node = $$(node);
7342        if (keepChildren) {
7343          $node.each(function () {
7344            var child;
7345            while (child = this.firstChild) {
7346              if (child.nodeType === 3 && child.data.length === 0) {
7347                this.removeChild(child);
7348              } else {
7349                this.parentNode.insertBefore(child, this);
7350              }
7351            }
7352          }).remove();
7353        } else {
7354          $node.remove();
7355        }
7356        return $node.length >
7356 1 ? $node.toArray() : $node[0];
7357      };
7358      var removeAllAttribs = function (e) {
7359        return run(e, function (e) {
7360          var i;
7361          var attrs = e.attributes;
7362          for (i = attrs.length - 1; i >= 0; i--) {
7363            e.removeAttributeNode(attrs.item(i));
7364          }
7365        });
7366      };
7367      var parseStyle = function (cssText) {
7368        return styles.parse(cssText);
7369      };
7370      var serializeStyle = function (stylesArg, name) {
7371        return styles.serialize(stylesArg, name);
7372      };
7373      var addStyle = function (cssText) {
7374        var head, styleElm;
7375        if (self !== DOMUtils.DOM && doc === document) {
7376          if (addedStyles[cssText]) {
7377            return;
7378          }
7379          addedStyles[cssText] = true;
7380        }
7381        styleElm = doc.getElementById('mceDefaultStyles');
7382        if (!styleElm) {
7383          styleElm = doc.createElement('style');
7384          styleElm.id = 'mceDefaultStyles';
7385          styleElm.type = 'text/css';
7386          head = doc.getElementsByTagName('head')[0];
7387          if (head.firstChild) {
7388            head.insertBefore(styleElm, head.firstChild);
7389          } else {
7390            head.appendChild(styleElm);
7391          }
7392        }
7393        if (styleElm.styleSheet) {
7394          styleElm.styleSheet.cssText += cssText;
7395        } else {
7396          styleElm.appendChild(doc.createTextNode(cssText));
7397        }
7398      };
7399      var loadCSS = function (urls) {
7400        if (!urls) {
7401          urls = '';
7402        }
7403        each(urls.split(','), function (url) {
7404          files[url] = true;
7405          styleSheetLoader.load(url, noop);
7406        });
7407      };
7408      var toggleClass = function (elm, cls, state) {
7409        $$(elm).toggleClass(cls, state).each(function () {
7410          if (this.className === '') {
7411            DomQuery(this).attr('class', null);
7412          }
7413        });
7414      };
7415      var addClass = function (elm, cls) {
7416        $$(elm).addClass(cls);
7417      };
7418      var removeClass = function (elm, cls) {
7419        toggleClass(elm, cls, false);
7420      };
7421      var hasClass = function (elm, cls) {
7422        return $$(elm).hasClass(cls);
7423      };
7424      var show = function (elm) {
7425        $$(elm).show();
7426      };
7427      var hide = function (elm) {
7428        $$(elm).hide();
7429      };
7430      var isHidden = function (elm) {
7431        return $$(elm).css('display') === 'none';
7432      };
7433      var uniqueId = function (prefix) {
7434        return (!prefix ? 'mce_' : prefix) + counter++;
7435      };
7436      var getOuterHTML = function (elm) {
7437        var node = typeof elm === 'string' ? get(elm) : elm;
7438        return isElement$1(node) ? node.outerHTML : DomQuery('<div></div>').append(DomQuery(node).clone()).html();
7439      };
7440      var setOuterHTML = function (elm, html) {
7441        $$(elm).each(function () {
7442          try {
7443            if ('outerHTML' in this) {
7444              this.outerHTML = html;
7445              return;
7446            }
7447          } catch (ex) {
7448          }
7449          remove(DomQuery(this).html(html), true);
7450        });
7451      };
7452      var insertAfter = function (node, reference) {
7453        var referenceNode = get(reference);
7454        return run(node, function (node) {
7455          var parent = referenceNode.parentNode;
7456          var nextSibling = referenceNode.nextSibling;
7457          if (nextSibling) {
7458            parent.insertBefore(node, nextSibling);
7459          } else {
7460            parent.appendChild(node);
7461          }
7462          return node;
7463        });
7464      };
7465      var replace = function (newElm, oldElm, keepChildren) {
7466        return run(oldElm, function (oldElm) {
7467          if (Tools.is(oldElm, 'array')) {
7468            newElm = newElm.cloneNode(true);
7469          }
7470          if (keepChildren) {
7471            each$5(grep$1(oldElm.childNodes), function (node) {
7472              newElm.appendChild(node);
7473            });
7474          }
7475          return oldElm.parentNode.replaceChild(newElm, oldElm);
7476        });
7477      };
7478      var rename = function (elm, name) {
7479        var newElm;
7480        if (elm.nodeName !== name.toUpperCase()) {
7481          newElm = create(name);
7482          each$5(getAttribs(elm), function (attrNode) {
7483            setAttrib(newElm, attrNode.nodeName, getAttrib(elm, attrNode.nodeName));
7484          });
7485          replace(newElm, elm, true);
7486        }
7487        return newElm || elm;
7488      };
7489      var findCommonAncestor = function (a, b) {
7490        var ps = a, pe;
7491        while (ps) {
7492          pe = b;
7493          while (pe && ps !== pe) {
7494            pe = pe.parentNode;
7495          }
7496          if (ps === pe) {
7497            break;
7498          }
7499          ps = ps.parentNode;
7500        }
7501        if (!ps && a.ownerDocument) {
7502          return a.ownerDocument.documentElement;
7503        }
7504        return ps;
7505      };
7506      var toHex = function (rgbVal) {
7507        return styles.toHex(Tools.trim(rgbVal));
7508      };
7509      var isNonEmptyElement = function (node) {
7510        if (isElement$1(node)) {
7511          var isNamedAnchor = node.nodeName.toLowerCase() === 'a' && !getAttrib(node, 'href') && getAttrib(node, 'id');
7512          if (getAttrib(node, 'name') || getAttrib(node, 'data-mce-bookmark') || isNamedAnchor) {
7513            return true;
7514          }
7515        }
7516        return false;
7517      };
7518      var isEmpty = function (node, elements) {
7519        var type, name, brCount = 0;
7520        if (isNonEmptyElement(node)) {
7521          return false;
7522        }
7523        node = node.firstChild;
7524        if (node) {
7525          var walker = new DomTreeWalker(node, node.parentNode);
7526          var whitespace = schema ? schema.getWhiteSpaceElements() : {};
7527          elements = elements || (schema ? schema.getNonEmptyElements() : null);
7528          do {
7529            type = node.nodeType;
7530            if (isElement$1(node)) {
7531              var bogusVal = node.getAttribute('data-mce-bogus');
7532              if (bogusVal) {
7533                node = walker.next(bogusVal === 'all');
7534                continue;
7535              }
7536              name = node.nodeName.toLowerCase();
7537              if (elements && elements[name]) {
7538                if (name === 'br') {
7539                  brCount++;
7540                  node = walker.next();
7541                  continue;
7542                }
7543                return false;
7544              }
7545              if (isNonEmptyElement(node)) {
7546                return false;
7547              }
7548            }
7549            if (type === 8) {
7550              return false;
7551            }
7552            if (type === 3 && !isWhitespaceText(node.nodeValue)) {
7553              return false;
7554            }
7555            if (type === 3 && node.parentNode && whitespace[node.parentNode.nodeName] && isWhitespaceText(node.nodeValue)) {
7556              return false;
7557            }
7558            node = walker.next();
7559          } while (node);
7560        }
7561        return brCount <= 1;
7562      };
7563      var createRng = function () {
7564        return doc.createRange();
7565      };
7566      var split = function (parentElm, splitElm, replacementElm) {
7567        var range = createRng();
7568        var beforeFragment;
7569        var afterFragment;
7570        var parentNode;
7571        if (parentElm && splitElm) {
7572          range.setStart(parentElm.parentNode, findNodeIndex(parentElm));
7573          range.setEnd(splitElm.parentNode, findNodeIndex(splitElm));
7574          beforeFragment = range.extractContents();
7575          range = createRng();
7576          range.setStart(splitElm.parentNode, findNodeIndex(splitElm) + 1);
7577          range.setEnd(parentElm.parentNode, findNodeIndex(parentElm) + 1);
7578          afterFragment = range.extractContents();
7579          parentNode = parentElm.parentNode;
7580          parentNode.insertBefore(trimNode(self, beforeFragment), parentElm);
7581          if (replacementElm) {
7582            parentNode.insertBefore(replacementElm, parentElm);
7583          } else {
7584            parentNode.insertBefore(splitElm, parentElm);
7585          }
7586          parentNode.insertBefore(trimNode(self, afterFragment), parentElm);
7587          remove(parentElm);
7588          return replacementElm || splitElm;
7589        }
7590      };
7591      var bind = function (target, name, func, scope) {
7592        if (Tools.isArray(target)) {
7593          var i = target.length;
7594          var rv = [];
7595          while (i--) {
7596            rv[i] = bind(target[i], name, func, scope);
7597          }
7598          return rv;
7599        }
7600        if (settings.collect && (target === doc || target === win)) {
7601          boundEvents.push([
7602            target,
7603            name,
7604            func,
7605            scope
7606          ]);
7607        }
7608        var output = events.bind(target, name, func, scope || self);
7609        return output;
7610      };
7611      var unbind = function (target, name, func) {
7612        if (Tools.isArray(target)) {
7613          var i = target.length;
7614          var rv = [];
7615          while (i--) {
7616            rv[i] = unbind(target[i], name, func);
7617          }
7618          return rv;
7619        } else {
7620          if (boundEvents.length > 0 && (target === doc || target === win)) {
7621            var i = boundEvents.length;
7622            while (i--) {
7623              var item = boundEvents[i];
7624              if (target === item[0] && (!name || name === item[1]) && (!func || func === item[2])) {
7625                events.unbind(item[0], item[1], item[2]);
7626              }
7627            }
7628          }
7629          return events.unbind(target, name, func);
7630        }
7631      };
7632      var fire = function (target, name, evt) {
7633        return events.fire(target, name, evt);
7634      };
7635      var getContentEditable = function (node) {
7636        if (node && isElement$1(node)) {
7637          var contentEditable = node.getAttribute('data-mce-contenteditable');
7638          if (contentEditable && contentEditable !== 'inherit') {
7639            return contentEditable;
7640          }
7641          return node.contentEditable !== 'inherit' ? node.contentEditable : null;
7642        } else {
7643          return null;
7644        }
7645      };
7646      var getContentEditableParent = function (node) {
7647        var root = getRoot();
7648        var state = null;
7649        for (; node && node !== root; node = node.parentNode) {
7650          state = getContentEditable(node);
7651          if (state !== null) {
7652            break;
7653          }
7654        }
7655        return state;
7656      };
7657      var destroy = function () {
7658        if (boundEvents.length > 0) {
7659          var i = boundEvents.length;
7660          while (i--) {
7661            var item = boundEvents[i];
7662            events.unbind(item[0], item[1], item[2]);
7663          }
7664        }
7665        each$1(files, function (_, url) {
7666          styleSheetLoader.unload(url);
7667          delete files[url];
7668        });
7669        if (Sizzle.setDocument) {
7670          Sizzle.setDocument();
7671        }
7672      };
7673      var isChildOf = function (node, parent) {
7674        while (node) {
7675          if (parent === node) {
7676            return true;
7677          }
7678          node = node.parentNode;
7679        }
7680        return false;
7681      };
7682      var dumpRng = function (r) {
7683        return 'startContainer: ' + r.startContainer.nodeName + ', startOffset: ' + r.startOffset + ', endContainer: ' + r.endContainer.nodeName + ', endOffset: ' + r.endOffset;
7684      };
7685      var self = {
7686        doc: doc,
7687        settings: settings,
7688        win: win,
7689        files: files,
7690        stdMode: stdMode,
7691        boxModel: boxModel,
7692        styleSheetLoader: styleSheetLoader,
7693        boundEvents: boundEvents,
7694        styles: styles,
7695        schema: schema,
7696        events: events,
7697        isBlock: isBlock,
7698        $: $,
7699        $$: $$,
7700        root: null,
7701        clone: clone,
7702        getRoot: getRoot,
7703        getViewPort: getViewPort,
7704        getRect: getRect,
7705        getSize: getSize,
7706        getParent: getParent,
7707        getParents: getParents,
7708        get: get,
7709        getNext: getNext,
7710        getPrev: getPrev,
7711        select: select,
7712        is: is,
7713        add: add,
7714        create: create,
7715        createHTML: createHTML,
7716        createFragment: createFragment,
7717        remove: remove,
7718        setStyle: setStyle,
7719        getStyle: getStyle,
7720        setStyles: setStyles,
7721        removeAllAttribs: removeAllAttribs,
7722        setAttrib: setAttrib,
7723        setAttribs: setAttribs,
7724        getAttrib: getAttrib,
7725        getPos: getPos$1,
7726        parseStyle: parseStyle,
7727        serializeStyle: serializeStyle,
7728        addStyle: addStyle,
7729        loadCSS: loadCSS,
7730        addClass: addClass,
7731        removeClass: removeClass,
7732        hasClass: hasClass,
7733        toggleClass: toggleClass,
7734        show: show,
7735        hide: hide,
7736        isHidden: isHidden,
7737        uniqueId: uniqueId,
7738        setHTML: setHTML,
7739        getOuterHTML: getOuterHTML,
7740        setOuterHTML: setOuterHTML,
7741        decode: decode,
7742        encode: encode,
7743        insertAfter: insertAfter,
7744        replace: replace,
7745        rename: rename,
7746        findCommonAncestor: findCommonAncestor,
7747        toHex: toHex,
7748        run: run,
7749        getAttribs: getAttribs,
7750        isEmpty: isEmpty,
7751        createRng: createRng,
7752        nodeIndex: findNodeIndex,
7753        split: split,
7754        bind: bind,
7755        unbind: unbind,
7756        fire: fire,
7757        getContentEditable: getContentEditable,
7758        getContentEditableParent: getContentEditableParent,
7759        destroy: destroy,
7760        isChildOf: isChildOf,
7761        dumpRng: dumpRng
7762      };
7763      var attrHooks = setupAttrHooks(styles, settings, function () {
7764        return self;
7765      });
7766      return self;
7767    }
7768    (function (DOMUtils) {
7769      DOMUtils.DOM = DOMUtils(document);
7770      DOMUtils.nodeIndex = findNodeIndex;
7771    }(DOMUtils || (DOMUtils = {})));
7772    var DOMUtils$1 = DOMUtils;
7773
7774    var DOM = DOMUtils$1.DOM;
7775    var each$6 = Tools.each, grep$2 = Tools.grep;
7776    var QUEUED = 0;
7777    var LOADING = 1;
7778    var LOADED = 2;
7779    var FAILED = 3;
7780    var ScriptLoader = function () {
7781      function ScriptLoader(settings) {
7782        if (settings === void 0) {
7783          settings = {};
7784        }
7785        this.states = {};
7786        this.queue = [];
7787        this.scriptLoadedCallbacks = {};
7788        this.queueLoadedCallbacks = [];
7789        this.loading = 0;
7790        this.settings = settings;
7791      }
7792      ScriptLoader.prototype._setReferrerPolicy = function (referrerPolicy) {
7793        this.settings.referrerPolicy = referrerPolicy;
7794      };
7795      ScriptLoader.prototype.loadScript = function (url, success, failure) {
7796        var dom = DOM;
7797        var elm;
7798        var done = function () {
7799          dom.remove(id);
7800          if (elm) {
7801            elm.onreadystatechange = elm.onload = elm = null;
7802          }
7803          success();
7804        };
7805        var error = function () {
7806          if (isFunction(failure)) {
7807            failure();
7808          } else {
7809            if (typeof console !== 'undefined' && console.log) {
7810              console.log('Failed to load script: ' + url);
7811            }
7812          }
7813        };
7814        var id = dom.uniqueId();
7815        elm = document.createElement('script');
7816        elm.id = id;
7817        elm.type = 'text/javascript';
7818        elm.src = Tools._addCacheSuffix(url);
7819        if (this.settings.referrerPolicy) {
7820          dom.setAttrib(elm, 'referrerpolicy', this.settings.referrerPolicy);
7821        }
7822        elm.onload = done;
7823        elm.onerror = error;
7824        (document.getElementsByTagName('head')[0] || document.body).appendChild(elm);
7825      };
7826      ScriptLoader.prototype.isDone = function (url) {
7827        return this.states[url] === LOADED;
7828      };
7829      ScriptLoader.prototype.markDone = function (url) {
7830        this.states[url] = LOADED;
7831      };
7832      ScriptLoader.prototype.add = function (url, success, scope, failure) {
7833        var state = this.states[url];
7834        if (state === undefined) {
7835          this.queue.push(url);
7836          this.states[url] = QUEUED;
7837        }
7838        if (success) {
7839          if (!this.scriptLoadedCallbacks[url]) {
7840            this.scriptLoadedCallbacks[url] = [];
7841          }
7842          this.scriptLoadedCallbacks[url].push({
7843            success: success,
7844            failure: failure,
7845            scope: scope || this
7846          });
7847        }
7848      };
7849      ScriptLoader.prototype.load = function (url, success, scope, failure) {
7850        return this.add(url, success, scope, failure);
7851      };
7852      ScriptLoader.prototype.remove = function (url) {
7853        delete this.states[url];
7854        delete this.scriptLoadedCallbacks[url];
7855      };
7856      ScriptLoader.prototype.loadQueue = function (success, scope, failure) {
7857        this.loadScripts(this.queue, success, scope, failure);
7858      };
7859      ScriptLoader.prototype.loadScripts = function (scripts, success, scope, failure) {
7860        var self = this;
7861        var failures = [];
7862        var execCallbacks = function (name, url) {
7863          each$6(self.scriptLoadedCallbacks[url], function (callback) {
7864            if (isFunction(callback[name])) {
7865              callback[name].call(callback.scope);
7866            }
7867          });
7868          self.scriptLoadedCallbacks[url] = undefined;
7869        };
7870        self.queueLoadedCallbacks.push({
7871          success: success,
7872          failure: failure,
7873          scope: scope || this
7874        });
7875        var loadScripts = function () {
7876          var loadingScripts = grep$2(scripts);
7877          scripts.length = 0;
7878          each$6(loadingScripts, function (url) {
7879            if (self.states[url] === LOADED) {
7880              execCallbacks('success', url);
7881              return;
7882            }
7883            if (self.states[url] === FAILED) {
7884              execCallbacks('failure', url);
7885              return;
7886            }
7887            if (self.states[url] !== LOADING) {
7888              self.states[url] = LOADING;
7889              self.loading++;
7890              self.loadScript(url, function () {
7891                self.states[url] = LOADED;
7892                self.loading--;
7893                execCallbacks('success', url);
7894                loadScripts();
7895              }, function () {
7896                self.states[url] = FAILED;
7897                self.loading--;
7898                failures.push(url);
7899                execCallbacks('failure', url);
7900                loadScripts();
7901              });
7902            }
7903          });
7904          if (!self.loading) {
7905            var notifyCallbacks = self.queueLoadedCallbacks.slice(0);
7906            self.queueLoadedCallbacks.length = 0;
7907            each$6(notifyCallbacks, function (callback) {
7908              if (failures.length === 0) {
7909                if (isFunction(callback.success)) {
7910                  callback.success.call(callback.scope);
7911                }
7912              } else {
7913                if (isFunction(callback.failure)) {
7914                  callback.failure.call(callback.scope, failures);
7915                }
7916              }
7917            });
7918          }
7919        };
7920        loadScripts();
7921      };
7922      ScriptLoader.ScriptLoader = new ScriptLoader();
7923      return ScriptLoader;
7924    }();
7925
7926    var Cell = function (initial) {
7927      var value = initial;
7928      var get = function () {
7929        return value;
7930      };
7931      var set = function (v) {
7932        value = v;
7933      };
7934      return {
7935        get: get,
7936        set: set
7937      };
7938    };
7939
7940    var isRaw = function (str) {
7941      return isObject(str) && has(str, 'raw');
7942    };
7943    var isTokenised = function (str) {
7944      return isArray(str) && str.length > 1;
7945    };
7946    var data = {};
7947    var currentCode = Cell('en');
7948    var getLanguageData = function () {
7949      return get(data, currentCode.get());
7950    };
7951    var getData = function () {
7952      return map$1(data, function (value) {
7953        return __assign({}, value);
7954      });
7955    };
7956    var setCode = function (newCode) {
7957      if (newCode) {
7958        currentCode.set(newCode);
7959      }
7960    };
7961    var getCode = function () {
7962      return currentCode.get();
7963    };
7964    var add = function (code, items) {
7965      var langData = data[code];
7966      if (!langData) {
7967        data[code] = langData = {};
7968      }
7969      each$1(items, function (translation, name) {
7970        langData[name.toLowerCase()] = translation;
7971      });
7972    };
7973    var translate = function (text) {
7974      var langData = getLanguageData().getOr({});
7975      var toString = function (obj) {
7976        if (isFunction(obj)) {
7977          return Object.prototype.toString.call(obj);
7978        }
7979        return !isEmpty(obj) ? '' + obj : '';
7980      };
7981      var isEmpty = function (text) {
7982        return text === '' || text === null || text === undefined;
7983      };
7984      var getLangData = function (text) {
7985        var textstr = toString(text);
7986        return get(langData, textstr.toLowerCase()).map(toString).getOr(textstr);
7987      };
7988      var removeContext = function (str) {
7989        return str.replace(/{context:\w+}$/, '');
7990      };
7991      if (isEmpty(text)) {
7992        return '';
7993      }
7994      if (isRaw(text)) {
7995        return toString(text.raw);
7996      }
7997      if (isTokenised(text)) {
7998        var values_1 = text.slice(1);
7999        var substitued = getLangData(text[0]).replace(/\{([0-9]+)\}/g, function ($1, $2) {
8000          return has(values_1, $2) ? toString(values_1[$2]) : $1;
8001        });
8002        return removeContext(substitued);
8003      }
8004      return removeContext(getLangData(text));
8005    };
8006    var isRtl = function () {
8007      return getLanguageData().bind(function (items) {
8008        return get(items, '_dir');
8009      }).exists(function (dir) {
8010        return dir === 'rtl';
8011      });
8012    };
8013    var hasCode = function (code) {
8014      return has(data, code);
8015    };
8016    var I18n = {
8017      getData: getData,
8018      setCode: setCode,
8019      getCode: getCode,
8020      add: add,
8021      translate: translate,
8022      isRtl: isRtl,
8023      hasCode: hasCode
8024    };
8025
8026    function AddOnManager() {
8027      var _this = this;
8028      var items = [];
8029      var urls = {};
8030      var lookup = {};
8031      var _listeners = [];
8032      var runListeners = function (name, state) {
8033        var matchedListeners = filter(_listeners, function (listener) {
8034          return listener.name === name && listener.state === state;
8035        });
8036        each(matchedListeners, function (listener) {
8037          return listener.callback();
8038        });
8039      };
8040      var get = function (name) {
8041        if (lookup[name]) {
8042          return lookup[name].instance;
8043        }
8044        return undefined;
8045      };
8046      var dependencies = function (name) {
8047        var result;
8048        if (lookup[name]) {
8049          result = lookup[name].dependencies;
8050        }
8051        return result || [];
8052      };
8053      var requireLangPack = function (name, languages) {
8054        if (AddOnManager.languageLoad !== false) {
8055          waitFor(name, function () {
8056            var language = I18n.getCode();
8057            var wrappedLanguages = ',' + (languages || '') + ',';
8058            if (!language || languages && wrappedLanguages.indexOf(',' + language + ',') === -1) {
8059              return;
8060            }
8061            ScriptLoader.ScriptLoader.add(urls[name] + '/langs/' + language + '.js');
8062          }, 'loaded');
8063        }
8064      };
8065      var add = function (id, addOn, dependencies) {
8066        var addOnConstructor = addOn;
8067        items.push(addOnConstructor);
8068        lookup[id] = {
8069          instance: addOnConstructor,
8070          dependencies: dependencies
8071        };
8072        runListeners(id, 'added');
8073        return addOnConstructor;
8074      };
8075      var remove = function (name) {
8076        delete urls[name];
8077        delete lookup[name];
8078      };
8079      var createUrl = function (baseUrl, dep) {
8080        if (typeof dep === 'object') {
8081          return dep;
8082        }
8083        return typeof baseUrl === 'string' ? {
8084          prefix: '',
8085          resource: dep,
8086          suffix: ''
8087        } : {
8088          prefix: baseUrl.prefix,
8089          resource: dep,
8090          suffix: baseUrl.suffix
8091        };
8092      };
8093      var addComponents = function (pluginName, scripts) {
8094        var pluginUrl = _this.urls[pluginName];
8095        each(scripts, function (script) {
8096          ScriptLoader.ScriptLoader.add(pluginUrl + '/' + script);
8097        });
8098      };
8099      var loadDependencies = function (name, addOnUrl, success, scope) {
8100        var deps = dependencies(name);
8101        each(deps, function (dep) {
8102          var newUrl = createUrl(addOnUrl, dep);
8103          load(newUrl.resource, newUrl, undefined, undefined);
8104        });
8105        if (success) {
8106          if (scope) {
8107            success.call(scope);
8108          } else {
8109            success.call(ScriptLoader);
8110          }
8111        }
8112      };
8113      var load = function (name, addOnUrl, success, scope, failure) {
8114        if (urls[name]) {
8115          return;
8116        }
8117        var urlString = typeof addOnUrl === 'string' ? addOnUrl : addOnUrl.prefix + addOnUrl.resource + addOnUrl.suffix;
8118        if (urlString.indexOf('/') !== 0 && urlString.indexOf('://') === -1) {
8119          urlString = AddOnManager.baseURL + '/' + urlString;
8120        }
8121        urls[name] = urlString.substring(0, urlString.lastIndexOf('/'));
8122        var done = function () {
8123          runListeners(name, 'loaded');
8124          loadDependencies(name, addOnUrl, success, scope);
8125        };
8126        if (lookup[name]) {
8127          done();
8128        } else {
8129          ScriptLoader.ScriptLoader.add(urlString, done, scope, failure);
8130        }
8131      };
8132      var waitFor = function (name, callback, state) {
8133        if (state === void 0) {
8134          state = 'added';
8135        }
8136        if (has(lookup, name) && state === 'added') {
8137          callback();
8138        } else if (has(urls, name) && state === 'loaded') {
8139          callback();
8140        } else {
8141          _listeners.push({
8142            name: name,
8143            state: state,
8144            callback: callback
8145          });
8146        }
8147      };
8148      return {
8149        items: items,
8150        urls: urls,
8151        lookup: lookup,
8152        _listeners: _listeners,
8153        get: get,
8154        dependencies: dependencies,
8155        requireLangPack: requireLangPack,
8156        add: add,
8157        remove: remove,
8158        createUrl: createUrl,
8159        addComponents: addComponents,
8160        load: load,
8161        waitFor: waitFor
8162      };
8163    }
8164    (function (AddOnManager) {
8165      AddOnManager.PluginManager = AddOnManager();
8166      AddOnManager.ThemeManager = AddOnManager();
8167    }(AddOnManager || (AddOnManager = {})));
8168    var AddOnManager$1 = AddOnManager;
8169
8170    var first = function (fn, rate) {
8171      var timer = null;
8172      var cancel = function () {
8173        if (timer !== null) {
8174          clearTimeout(timer);
8175          timer = null;
8176        }
8177      };
8178      var throttle = function () {
8179        var args = [];
8180        for (var _i = 0; _i < arguments.length; _i++) {
8181          args[_i] = arguments[_i];
8182        }
8183        if (timer === null) {
8184          timer = setTimeout(function () {
8185            fn.apply(null, args);
8186            timer = null;
8187          }, rate);
8188        }
8189      };
8190      return {
8191        cancel: cancel,
8192        throttle: throttle
8193      };
8194    };
8195    var last$2 = function (fn, rate) {
8196      var timer = null;
8197      var cancel = function () {
8198        if (timer !== null) {
8199          clearTimeout(timer);
8200          timer = null;
8201        }
8202      };
8203      var throttle = function () {
8204        var args = [];
8205        for (var _i = 0; _i < arguments.length; _i++) {
8206          args[_i] = arguments[_i];
8207        }
8208        if (timer !== null) {
8209          clearTimeout(timer);
8210        }
8211        timer = setTimeout(function () {
8212          fn.apply(null, args);
8213          timer = null;
8214        }, rate);
8215      };
8216      return {
8217        cancel: cancel,
8218        throttle: throttle
8219      };
8220    };
8221
8222    var read = function (element, attr) {
8223      var value = get$3(element, attr);
8224      return value === undefined || value === '' ? [] : value.split(' ');
8225    };
8226    var add$1 = function (element, attr, id) {
8227      var old = read(element, attr);
8228      var nu = old.concat([id]);
8229      set(element, attr, nu.join(' '));
8230      return true;
8231    };
8232    var remove$2 = function (element, attr, id) {
8233      var nu = filter(read(element, attr), function (v) {
8234        return v !== id;
8235      });
8236      if (nu.length > 0) {
8237        set(element, attr, nu.join(' '));
8238      } else {
8239        remove$1(element, attr);
8240      }
8241      return false;
8242    };
8243
8244    var supports = function (element) {
8245      return element.dom.classList !== undefined;
8246    };
8247    var get$5 = function (element) {
8248      return read(element, 'class');
8249    };
8250    var add$2 = function (element, clazz) {
8251      return add$1(element, 'class', clazz);
8252    };
8253    var remove$3 = function (element, clazz) {
8254      return remove$2(element, 'class', clazz);
8255    };
8256
8257    var add$3 = function (element, clazz) {
8258      if (supports(element)) {
8259        element.dom.classList.add(clazz);
8260      } else {
8261        add$2(element, clazz);
8262      }
8263    };
8264    var cleanClass = function (element) {
8265      var classList = supports(element) ? element.dom.classList : get$5(element);
8266      if (classList.length === 0) {
8267        remove$1(element, 'class');
8268      }
8269    };
8270    var remove$4 = function (element, clazz) {
8271      if (supports(element)) {
8272        var classList = element.dom.classList;
8273        classList.remove(clazz);
8274      } else {
8275        remove$3(element, clazz);
8276      }
8277      cleanClass(element);
8278    };
8279    var has$2 = function (element, clazz) {
8280      return supports(element) && element.dom.classList.contains(clazz);
8281    };
8282
8283    var descendants = function (scope, predicate) {
8284      var result = [];
8285      each(children(scope), function (x) {
8286        if (predicate(x)) {
8287          result = result.concat([x]);
8288        }
8289        result = result.concat(descendants(x, predicate));
8290      });
8291      return result;
8292    };
8293
8294    var descendants$1 = function (scope, selector) {
8295      return all(selector, scope);
8296    };
8297
8298    var annotation = constant('mce-annotation');
8299    var dataAnnotation = constant('data-mce-annotation');
8300    var dataAnnotationId = constant('data-mce-annotation-uid');
8301
8302    var identify = function (editor, annotationName) {
8303      var rng = editor.selection.getRng();
8304      var start = SugarElement.fromDom(rng.startContainer);
8305      var root = SugarElement.fromDom(editor.getBody());
8306      var selector = annotationName.fold(function () {
8307        return '.' + annotation();
8308      }, function (an) {
8309        return '[' + dataAnnotation() + '="' + an + '"]';
8310      });
8311      var newStart = child(start, rng.startOffset).getOr(start);
8312      var closest = closest$1(newStart, selector, function (n) {
8313        return eq$2(n, root);
8314      });
8315      var getAttr = function (c, property) {
8316        if (has$1(c, property)) {
8317          return Optional.some(get$3(c, property));
8318        } else {
8319          return Optional.none();
8320        }
8321      };
8322      return closest.bind(function (c) {
8323        return getAttr(c, '' + dataAnnotationId()).bind(function (uid) {
8324          return getAttr(c, '' + dataAnnotation()).map(function (name) {
8325            var elements = findMarkers(editor, uid);
8326            return {
8327              uid: uid,
8328              name: name,
8329              elements: elements
8330            };
8331          });
8332        });
8333      });
8334    };
8335    var isAnnotation = function (elem) {
8336      return isElement(elem) && has$2(elem, annotation());
8337    };
8338    var findMarkers = function (editor, uid) {
8339      var body = SugarElement.fromDom(editor.getBody());
8340      return descendants$1(body, '[' + dataAnnotationId() + '="' + uid + '"]');
8341    };
8342    var findAll = function (editor, name) {
8343      var body = SugarElement.fromDom(editor.getBody());
8344      var markers = descendants$1(body, '[' + dataAnnotation() + '="' + name + '"]');
8345      var directory = {};
8346      each(markers, function (m) {
8347        var uid = get$3(m, dataAnnotationId());
8348        var nodesAlready = directory.hasOwnProperty(uid) ? directory[uid] : [];
8349        directory[uid] = nodesAlready.concat([m]);
8350      });
8351      return directory;
8352    };
8353
8354    var setup = function (editor, _registry) {
8355      var changeCallbacks = Cell({});
8356      var initData = function () {
8357        return {
8358          listeners: [],
8359          previous: Cell(Optional.none())
8360        };
8361      };
8362      var withCallbacks = function (name, f) {
8363        updateCallbacks(name, function (data) {
8364          f(data);
8365          return data;
8366        });
8367      };
8368      var updateCallbacks = function (name, f) {
8369        var callbackMap = changeCallbacks.get();
8370        var data = callbackMap.hasOwnProperty(name) ? callbackMap[name] : initData();
8371        var outputData = f(data);
8372        callbackMap[name] = outputData;
8373        changeCallbacks.set(callbackMap);
8374      };
8375      var fireCallbacks = function (name, uid, elements) {
8376        withCallbacks(name, function (data) {
8377          each(data.listeners, function (f) {
8378            return f(true, name, {
8379              uid: uid,
8380              nodes: map(elements, function (elem) {
8381                return elem.dom;
8382              })
8383            });
8384          });
8385        });
8386      };
8387      var fireNoAnnotation = function (name) {
8388        withCallbacks(name, function (data) {
8389          each(data.listeners, function (f) {
8390            return f(false, name);
8391          });
8392        });
8393      };
8394      var onNodeChange = last$2(function () {
8395        var callbackMap = changeCallbacks.get();
8396        var annotations = sort$1(keys(callbackMap));
8397        each(annotations, function (name) {
8398          updateCallbacks(name, function (data) {
8399            var prev = data.previous.get();
8400            identify(editor, Optional.some(name)).fold(function () {
8401              if (prev.isSome()) {
8402                fireNoAnnotation(name);
8403                data.previous.set(Optional.none());
8404              }
8405            }, function (_a) {
8406              var uid = _a.uid, name = _a.name, elements = _a.elements;
8407              if (!prev.is(uid)) {
8408                fireCallbacks(name, uid, elements);
8409                data.previous.set(Optional.some(uid));
8410              }
8411            });
8412            return {
8413              previous: data.previous,
8414              listeners: data.listeners
8415            };
8416          });
8417        });
8418      }, 30);
8419      editor.on('remove', function () {
8420        onNodeChange.cancel();
8421      });
8422      editor.on('NodeChange', function () {
8423        onNodeChange.throttle();
8424      });
8425      var addListener = function (name, f) {
8426        updateCallbacks(name, function (data) {
8427          return {
8428            previous: data.previous,
8429            listeners: data.listeners.concat([f])
8430          };
8431        });
8432      };
8433      return { addListener: addListener };
8434    };
8435
8436    var setup$1 = function (editor, registry) {
8437      var identifyParserNode = function (span) {
8438        return Optional.from(span.attr(dataAnnotation())).bind(registry.lookup);
8439      };
8440      editor.on('init', function () {
8441        editor.serializer.addNodeFilter('span', function (spans) {
8442          each(spans, function (span) {
8443            identifyParserNode(span).each(function (settings) {
8444              if (settings.persistent === false) {
8445                span.unwrap();
8446              }
8447            });
8448          });
8449        });
8450      });
8451    };
8452
8453    var create$2 = function () {
8454      var annotations = {};
8455      var register = function (name, settings) {
8456        annotations[name] = {
8457          name: name,
8458          settings: settings
8459        };
8460      };
8461      var lookup = function (name) {
8462        return annotations.hasOwnProperty(name) ? Optional.from(annotations[name]).map(function (a) {
8463          return a.settings;
8464        }) : Optional.none();
8465      };
8466      return {
8467        register: register,
8468        lookup: lookup
8469      };
8470    };
8471
8472    var unique = 0;
8473    var generate$1 = function (prefix) {
8474      var date = new Date();
8475      var time = date.getTime();
8476      var random = Math.floor(Math.random() * 1000000000);
8477      unique++;
8478      return prefix + '_' + random + unique + String(time);
8479    };
8480
8481    var add$4 = function (element, classes) {
8482      each(classes, function (x) {
8483        add$3(element, x);
8484      });
8485    };
8486
8487    var fromHtml$1 = function (html, scope) {
8488      var doc = scope || document;
8489      var div = doc.createElement('div');
8490      div.innerHTML = html;
8491      return children(SugarElement.fromDom(div));
8492    };
8493
8494    var get$6 = function (element) {
8495      return element.dom.innerHTML;
8496    };
8497    var set$1 = function (element, content) {
8498      var owner$1 = owner(element);
8499      var docDom = owner$1.dom;
8500      var fragment = SugarElement.fromDom(docDom.createDocumentFragment());
8501      var contentElements = fromHtml$1(content, docDom);
8502      append$1(fragment, contentElements);
8503      empty(element);
8504      append(element, fragment);
8505    };
8506
8507    var clone$1 = function (original, isDeep) {
8508      return SugarElement.fromDom(original.dom.cloneNode(isDeep));
8509    };
8510    var shallow = function (original) {
8511      return clone$1(original, false);
8512    };
8513    var deep = function (original) {
8514      return clone$1(original, true);
8515    };
8516
8517    var TextWalker = function (startNode, rootNode, isBoundary) {
8518      if (isBoundary === void 0) {
8519        isBoundary = never;
8520      }
8521      var walker = new DomTreeWalker(startNode, rootNode);
8522      var walk = function (direction) {
8523        var next;
8524        do {
8525          next = walker[direction]();
8526        } while (next && !isText$1(next) && !isBoundary(next));
8527        return Optional.from(next).filter(isText$1);
8528      };
8529      return {
8530        current: function () {
8531          return Optional.from(walker.current()).filter(isText$1);
8532        },
8533        next: function () {
8534          return walk('next');
8535        },
8536        prev: function () {
8537          return walk('prev');
8538        },
8539        prev2: function () {
8540          return walk('prev2');
8541        }
8542      };
8543    };
8544
8545    var TextSeeker = function (dom, isBoundary) {
8546      var isBlockBoundary = isBoundary ? isBoundary : function (node) {
8547        return dom.isBlock(node) || isBr(node) || isContentEditableFalse(node);
8548      };
8549      var walk = function (node, offset, walker, process) {
8550        if (isText$1(node)) {
8551          var newOffset = process(node, offset, node.data);
8552          if (newOffset !== -1) {
8553            return Optional.some({
8554              container: node,
8555              offset: newOffset
8556            });
8557          }
8558        }
8559        return walker().bind(function (next) {
8560          return walk(next.container, next.offset, walker, process);
8561        });
8562      };
8563      var backwards = function (node, offset, process, root) {
8564        var walker = TextWalker(node, root, isBlockBoundary);
8565        return walk(node, offset, function () {
8566          return walker.prev().map(function (prev) {
8567            return {
8568              container: prev,
8569              offset: prev.length
8570            };
8571          });
8572        }, process).getOrNull();
8573      };
8574      var forwards = function (node, offset, process, root) {
8575        var walker = TextWalker(node, root, isBlockBoundary);
8576        return walk(node, offset, function () {
8577          return walker.next().map(function (next) {
8578            return {
8579              container: next,
8580              offset: 0
8581            };
8582          });
8583        }, process).getOrNull();
8584      };
8585      return {
8586        backwards: backwards,
8587        forwards: forwards
8588      };
8589    };
8590
8591    var cat = function (arr) {
8592      var r = [];
8593      var push = function (x) {
8594        r.push(x);
8595      };
8596      for (var i = 0; i < arr.length; i++) {
8597        arr[i].each(push);
8598      }
8599      return r;
8600    };
8601    var lift2 = function (oa, ob, f) {
8602      return oa.isSome() && ob.isSome() ? Optional.some(f(oa.getOrDie(), ob.getOrDie())) : Optional.none();
8603    };
8604    var lift3 = function (oa, ob, oc, f) {
8605      return oa.isSome() && ob.isSome() && oc.isSome() ? Optional.some(f(oa.getOrDie(), ob.getOrDie(), oc.getOrDie())) : Optional.none();
8606    };
8607    var someIf = function (b, a) {
8608      return b ? Optional.some(a) : Optional.none();
8609    };
8610
8611    var round = Math.round;
8612    var clone$2 = function (rect) {
8613      if (!rect) {
8614        return {
8615          left: 0,
8616          top: 0,
8617          bottom: 0,
8618          right: 0,
8619          width: 0,
8620          height: 0
8621        };
8622      }
8623      return {
8624        left: round(rect.left),
8625        top: round(rect.top),
8626        bottom: round(rect.bottom),
8627        right: round(rect.right),
8628        width: round(rect.width),
8629        height: round(rect.height)
8630      };
8631    };
8632    var collapse = function (rect, toStart) {
8633      rect = clone$2(rect);
8634      if (toStart) {
8635        rect.right = rect.left;
8636      } else {
8637        rect.left = rect.left + rect.width;
8638        rect.right = rect.left;
8639      }
8640      rect.width = 0;
8641      return rect;
8642    };
8643    var isEqual = function (rect1, rect2) {
8644      return rect1.left === rect2.left && rect1.top === rect2.top && rect1.bottom === rect2.bottom && rect1.right === rect2.right;
8645    };
8646    var isValidOverflow = function (overflowY, rect1, rect2) {
8647      return overflowY >= 0 && overflowY <= Math.min(rect1.height, rect2.height) / 2;
8648    };
8649    var isAbove = function (rect1, rect2) {
8650      var halfHeight = Math.min(rect2.height / 2, rect1.height / 2);
8651      if (rect1.bottom - halfHeight < rect2.top) {
8652        return true;
8653      }
8654      if (rect1.top > rect2.bottom) {
8655        return false;
8656      }
8657      return isValidOverflow(rect2.top - rect1.bottom, rect1, rect2);
8658    };
8659    var isBelow = function (rect1, rect2) {
8660      if (rect1.top > rect2.bottom) {
8661        return true;
8662      }
8663      if (rect1.bottom < rect2.top) {
8664        return false;
8665      }
8666      return isValidOverflow(rect2.bottom - rect1.top, rect1, rect2);
8667    };
8668    var containsXY = function (rect, clientX, clientY) {
8669      return clientX >= rect.left && clientX <= rect.right && clientY >= rect.top && clientY <= rect.bottom;
8670    };
8671
8672    var getSelectedNode = function (range) {
8673      var startContainer = range.startContainer, startOffset = range.startOffset;
8674      if (startContainer.hasChildNodes() && range.endOffset === startOffset + 1) {
8675        return startContainer.childNodes[startOffset];
8676      }
8677      return null;
8678    };
8679    var getNode = function (container, offset) {
8680      if (container.nodeType === 1 && container.hasChildNodes()) {
8681        if (offset >= container.childNodes.length) {
8682          offset = container.childNodes.length - 1;
8683        }
8684        container = container.childNodes[offset];
8685      }
8686      return container;
8687    };
8688
8689    var extendingChars = new RegExp('[\u0300-\u036f\u0483-\u0487\u0488-\u0489\u0591-\u05bd\u05bf\u05c1-\u05c2\u05c4-\u05c5\u05c7\u0610-\u061a' + '\u064b-\u065f\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7-\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0' + '\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08e3-\u0902\u093a\u093c' + '\u0941-\u0948\u094d\u0951-\u0957\u0962-\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2-\u09e3' + '\u0a01-\u0a02\u0a3c\u0a41-\u0a42\u0a47-\u0a48\u0a4b-\u0a4d\u0a51\u0a70-\u0a71\u0a75\u0a81-\u0a82\u0abc' + '\u0ac1-\u0ac5\u0ac7-\u0ac8\u0acd\u0ae2-\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57' + '\u0b62-\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c00\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55-\u0c56' + '\u0c62-\u0c63\u0c81\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc-\u0ccd\u0cd5-\u0cd6\u0ce2-\u0ce3\u0d01\u0d3e\u0d41-\u0d44' + '\u0d4d\u0d57\u0d62-\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9' + '\u0ebb-\u0ebc\u0ec8-\u0ecd\u0f18-\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86-\u0f87\u0f8d-\u0f97' + '\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039-\u103a\u103d-\u103e\u1058-\u1059\u105e-\u1060\u1071-\u1074' + '\u1082\u1085-\u1086\u108d\u109d\u135d-\u135f\u1712-\u1714\u1732-\u1734\u1752-\u1753\u1772-\u1773\u17b4-\u17b5' + '\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927-\u1928\u1932\u1939-\u193b\u1a17-\u1a18' + '\u1a1b\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1ab0-\u1abd\u1ABE\u1b00-\u1b03\u1b34' + '\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80-\u1b81\u1ba2-\u1ba5\u1ba8-\u1ba9\u1bab-\u1bad\u1be6\u1be8-\u1be9' + '\u1bed\u1bef-\u1bf1\u1c2c-\u1c33\u1c36-\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1cf4\u1cf8-\u1cf9' + '\u1dc0-\u1df5\u1dfc-\u1dff\u200c-\u200d\u20d0-\u20dc\u20DD-\u20E0\u20e1\u20E2-\u20E4\u20e5-\u20f0\u2cef-\u2cf1' + '\u2d7f\u2de0-\u2dff\u302a-\u302d\u302e-\u302f\u3099-\u309a\ua66f\uA670-\uA672\ua674-\ua67d\ua69e-\ua69f\ua6f0-\ua6f1' + '\ua802\ua806\ua80b\ua825-\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc' + '\ua9e5\uaa29-\uaa2e\uaa31-\uaa32\uaa35-\uaa36\uaa43\uaa4c\uaa7c\uaab0\uaab2-\uaab4\uaab7-\uaab8\uaabe-\uaabf\uaac1' + '\uaaec-\uaaed\uaaf6\uabe5\uabe8\uabed\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\uff9e-\uff9f]');
8690    var isExtendingChar = function (ch) {
8691      return typeof ch === 'string' && ch.charCodeAt(0) >= 768 && extendingChars.test(ch);
8692    };
8693
8694    var or = function () {
8695      var args = [];
8696      for (var _i = 0; _i < arguments.length; _i++) {
8697        args[_i] = arguments[_i];
8698      }
8699      return function (x) {
8700        for (var i = 0; i < args.length; i++) {
8701          if (args[i](x)) {
8702            return true;
8703          }
8704        }
8705        return false;
8706      };
8707    };
8708    var and = function () {
8709      var args = [];
8710      for (var _i = 0; _i < arguments.length; _i++) {
8711        args[_i] = arguments[_i];
8712      }
8713      return function (x) {
8714        for (var i = 0; i < args.length; i++) {
8715          if (!args[i](x)) {
8716            return false;
8717          }
8718        }
8719        return true;
8720      };
8721    };
8722
8723    var isElement$3 = isElement$1;
8724    var isCaretCandidate$1 = isCaretCandidate;
8725    var isBlock$1 = matchStyleValues('display', 'block table');
8726    var isFloated = matchStyleValues('float', 'left right');
8727    var isValidElementCaretCandidate = and(isElement$3, isCaretCandidate$1, not(isFloated));
8728    var isNotPre = not(matchStyleValues('white-space', 'pre pre-line pre-wrap'));
8729    var isText$4 = isText$1;
8730    var isBr$3 = isBr;
8731    var nodeIndex = DOMUtils$1.nodeIndex;
8732    var resolveIndex = getNode;
8733    var createRange = function (doc) {
8734      return 'createRange' in doc ? doc.createRange() : DOMUtils$1.DOM.createRng();
8735    };
8736    var isWhiteSpace = function (chr) {
8737      return chr && /[\r\n\t ]/.test(chr);
8738    };
8739    var isRange = function (rng) {
8740      return !!rng.setStart && !!rng.setEnd;
8741    };
8742    var isHiddenWhiteSpaceRange = function (range) {
8743      var container = range.startContainer;
8744      var offset = range.startOffset;
8745      var text;
8746      if (isWhiteSpace(range.toString()) && isNotPre(container.parentNode) && isText$1(container)) {
8747        text = container.data;
8748        if (isWhiteSpace(text[offset - 1]) || isWhiteSpace(text[offset + 1])) {
8749          return true;
8750        }
8751      }
8752      return false;
8753    };
8754    var getBrClientRect = function (brNode) {
8755      var doc = brNode.ownerDocument;
8756      var rng = createRange(doc);
8757      var nbsp$1 = doc.createTextNode(nbsp);
8758      var parentNode = brNode.parentNode;
8759      parentNode.insertBefore(nbsp$1, brNode);
8760      rng.setStart(nbsp$1, 0);
8761      rng.setEnd(nbsp$1, 1);
8762      var clientRect = clone$2(rng.getBoundingClientRect());
8763      parentNode.removeChild(nbsp$1);
8764      return clientRect;
8765    };
8766    var getBoundingClientRectWebKitText = function (rng) {
8767      var sc = rng.startContainer;
8768      var ec = rng.endContainer;
8769      var so = rng.startOffset;
8770      var eo = rng.endOffset;
8771      if (sc === ec && isText$1(ec) && so === 0 && eo === 1) {
8772        var newRng = rng.cloneRange();
8773        newRng.setEndAfter(ec);
8774        return getBoundingClientRect(newRng);
8775      } else {
8776        return null;
8777      }
8778    };
8779    var isZeroRect = function (r) {
8780      return r.left === 0 && r.right === 0 && r.top === 0 && r.bottom === 0;
8781    };
8782    var getBoundingClientRect = function (item) {
8783      var clientRect;
8784      var clientRects = item.getClientRects();
8785      if (clientRects.length > 0) {
8786        clientRect = clone$2(clientRects[0]);
8787      } else {
8788        clientRect = clone$2(item.getBoundingClientRect());
8789      }
8790      if (!isRange(item) && isBr$3(item) && isZeroRect(clientRect)) {
8791        return getBrClientRect(item);
8792      }
8793      if (isZeroRect(clientRect) && isRange(item)) {
8794        return getBoundingClientRectWebKitText(item);
8795      }
8796      return clientRect;
8797    };
8798    var collapseAndInflateWidth = function (clientRect, toStart) {
8799      var newClientRect = collapse(clientRect, toStart);
8800      newClientRect.width = 1;
8801      newClientRect.right = newClientRect.left + 1;
8802      return newClientRect;
8803    };
8804    var getCaretPositionClientRects = function (caretPosition) {
8805      var clientRects = [];
8806      var beforeNode, node;
8807      var addUniqueAndValidRect = function (clientRect) {
8808        if (clientRect.height === 0) {
8809          return;
8810        }
8811        if (clientRects.length > 0) {
8812          if (isEqual(clientRect, clientRects[clientRects.length - 1])) {
8813            return;
8814          }
8815        }
8816        clientRects.push(clientRect);
8817      };
8818      var addCharacterOffset = function (container, offset) {
8819        var range = createRange(container.ownerDocument);
8820        if (offset < container.data.length) {
8821          if (isExtendingChar(container.data[offset])) {
8822            return clientRects;
8823          }
8824          if (isExtendingChar(container.data[offset - 1])) {
8825            range.setStart(container, offset);
8826            range.setEnd(container, offset + 1);
8827            if (!isHiddenWhiteSpaceRange(range)) {
8828              addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(range), false));
8829              return clientRects;
8830            }
8831          }
8832        }
8833        if (offset > 0) {
8834          range.setStart(container, offset - 1);
8835          range.setEnd(container, offset);
8836          if (!isHiddenWhiteSpaceRange(range)) {
8837            addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(range), false));
8838          }
8839        }
8840        if (offset < container.data.length) {
8841          range.setStart(container, offset);
8842          range.setEnd(container, offset + 1);
8843          if (!isHiddenWhiteSpaceRange(range)) {
8844            addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(range), true));
8845          }
8846        }
8847      };
8848      if (isText$4(caretPosition.container())) {
8849        addCharacterOffset(caretPosition.container(), caretPosition.offset());
8850        return clientRects;
8851      }
8852      if (isElement$3(caretPosition.container())) {
8853        if (caretPosition.isAtEnd()) {
8854          node = resolveIndex(caretPosition.container(), caretPosition.offset());
8855          if (isText$4(node)) {
8856            addCharacterOffset(node, node.data.length);
8857          }
8858          if (isValidElementCaretCandidate(node) && !isBr$3(node)) {
8859            addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(node), false));
8860          }
8861        } else {
8862          node = resolveIndex(caretPosition.container(), caretPosition.offset());
8863          if (isText$4(node)) {
8864            addCharacterOffset(node, 0);
8865          }
8866          if (isValidElementCaretCandidate(node) && caretPosition.isAtEnd()) {
8867            addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(node), false));
8868            return clientRects;
8869          }
8870          beforeNode = resolveIndex(caretPosition.container(), caretPosition.offset() - 1);
8871          if (isValidElementCaretCandidate(beforeNode) && !isBr$3(beforeNode)) {
8872            if (isBlock$1(beforeNode) || isBlock$1(node) || !isValidElementCaretCandidate(node)) {
8873              addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(beforeNode), false));
8874            }
8875          }
8876          if (isValidElementCaretCandidate(node)) {
8877            addUniqueAndValidRect(collapseAndInflateWidth(getBoundingClientRect(node), true));
8878          }
8879        }
8880      }
8881      return clientRects;
8882    };
8883    function CaretPosition(container, offset, clientRects) {
8884      var isAtStart = function () {
8885        if (isText$4(container)) {
8886          return offset === 0;
8887        }
8888        return offset === 0;
8889      };
8890      var isAtEnd = function () {
8891        if (isText$4(container)) {
8892          return offset >= container.data.length;
8893        }
8894        return offset >= container.childNodes.length;
8895      };
8896      var toRange = function () {
8897        var range = createRange(container.ownerDocument);
8898        range.setStart(container, offset);
8899        range.setEnd(container, offset);
8900        return range;
8901      };
8902      var getClientRects = function () {
8903        if (!clientRects) {
8904          clientRects = getCaretPositionClientRects(CaretPosition(container, offset));
8905        }
8906        return clientRects;
8907      };
8908      var isVisible = function () {
8909        return getClientRects().length > 0;
8910      };
8911      var isEqual = function (caretPosition) {
8912        return caretPosition && container === caretPosition.container() && offset === caretPosition.offset();
8913      };
8914      var getNode = function (before) {
8915        return resolveIndex(container, before ? offset - 1 : offset);
8916      };
8917      return {
8918        container: constant(container),
8919        offset: constant(offset),
8920        toRange: toRange,
8921        getClientRects: getClientRects,
8922        isVisible: isVisible,
8923        isAtStart: isAtStart,
8924        isAtEnd: isAtEnd,
8925        isEqual: isEqual,
8926        getNode: getNode
8927      };
8928    }
8929    (function (CaretPosition) {
8930      CaretPosition.fromRangeStart = function (range) {
8931        return CaretPosition(range.startContainer, range.startOffset);
8932      };
8933      CaretPosition.fromRangeEnd = function (range) {
8934        return CaretPosition(range.endContainer, range.endOffset);
8935      };
8936      CaretPosition.after = function (node) {
8937        return CaretPosition(node.parentNode, nodeIndex(node) + 1);
8938      };
8939      CaretPosition.before = function (node) {
8940        return CaretPosition(node.parentNode, nodeIndex(node));
8941      };
8942      CaretPosition.isAbove = function (pos1, pos2) {
8943        return lift2(head(pos2.getClientRects()), last(pos1.getClientRects()), isAbove).getOr(false);
8944      };
8945      CaretPosition.isBelow = function (pos1, pos2) {
8946        return lift2(last(pos2.getClientRects()), head(pos1.getClientRects()), isBelow).getOr(false);
8947      };
8948      CaretPosition.isAtStart = function (pos) {
8949        return pos ? pos.isAtStart() : false;
8950      };
8951      CaretPosition.isAtEnd = function (pos) {
8952        return pos ? pos.isAtEnd() : false;
8953      };
8954      CaretPosition.isTextPosition = function (pos) {
8955        return pos ? isText$1(pos.container()) : false;
8956      };
8957      CaretPosition.isElementPosition = function (pos) {
8958        return CaretPosition.isTextPosition(pos) === false;
8959      };
8960    }(CaretPosition || (CaretPosition = {})));
8961    var CaretPosition$1 = CaretPosition;
8962
8963    var trimEmptyTextNode = function (dom, node) {
8964      if (isText$1(node) && node.data.length === 0) {
8965        dom.remove(node);
8966      }
8967    };
8968    var insertNode = function (dom, rng, node) {
8969      rng.insertNode(node);
8970      trimEmptyTextNode(dom, node.previousSibling);
8971      trimEmptyTextNode(dom, node.nextSibling);
8972    };
8973    var insertFragment = function (dom, rng, frag) {
8974      var firstChild = Optional.from(frag.firstChild);
8975      var lastChild = Optional.from(frag.lastChild);
8976      rng.insertNode(frag);
8977      firstChild.each(function (child) {
8978        return trimEmptyTextNode(dom, child.previousSibling);
8979      });
8980      lastChild.each(function (child) {
8981        return trimEmptyTextNode(dom, child.nextSibling);
8982      });
8983    };
8984    var rangeInsertNode = function (dom, rng, node) {
8985      if (isDocumentFragment$1(node)) {
8986        insertFragment(dom, rng, node);
8987      } else {
8988        insertNode(dom, rng, node);
8989      }
8990    };
8991
8992    var isText$5 = isText$1;
8993    var isBogus$2 = isBogus;
8994    var nodeIndex$1 = DOMUtils$1.nodeIndex;
8995    var normalizedParent = function (node) {
8996      var parentNode = node.parentNode;
8997      if (isBogus$2(parentNode)) {
8998        return normalizedParent(parentNode);
8999      }
9000      return parentNode;
9001    };
9002    var getChildNodes = function (node) {
9003      if (!node) {
9004        return [];
9005      }
9006      return reduce(node.childNodes, function (result, node) {
9007        if (isBogus$2(node) && node.nodeName !== 'BR') {
9008          result = result.concat(getChildNodes(node));
9009        } else {
9010          result.push(node);
9011        }
9012        return result;
9013      }, []);
9014    };
9015    var normalizedTextOffset = function (node, offset) {
9016      while (node = node.previousSibling) {
9017        if (!isText$5(node)) {
9018          break;
9019        }
9020        offset += node.data.length;
9021      }
9022      return offset;
9023    };
9024    var equal$1 = function (a) {
9025      return function (b) {
9026        return a === b;
9027      };
9028    };
9029    var normalizedNodeIndex = function (node) {
9030      var nodes, index;
9031      nodes = getChildNodes(normalizedParent(node));
9032      index = findIndex$1(nodes, equal$1(node), node);
9033      nodes = nodes.slice(0, index + 1);
9034      var numTextFragments = reduce(nodes, function (result, node, i) {
9035        if (isText$5(node) && isText$5(nodes[i - 1])) {
9036          result++;
9037        }
9038        return result;
9039      }, 0);
9040      nodes = filter$2(nodes, matchNodeNames([node.nodeName]));
9041      index = findIndex$1(nodes, equal$1(node), node);
9042      return index - numTextFragments;
9043    };
9044    var createPathItem = function (node) {
9045      var name;
9046      if (isText$5(node)) {
9047        name = 'text()';
9048      } else {
9049        name = node.nodeName.toLowerCase();
9050      }
9051      return name + '[' + normalizedNodeIndex(node) + ']';
9052    };
9053    var parentsUntil = function (root, node, predicate) {
9054      var parents = [];
9055      for (node = node.parentNode; node !== root; node = node.parentNode) {
9056        if (predicate && predicate(node)) {
9057          break;
9058        }
9059        parents.push(node);
9060      }
9061      return parents;
9062    };
9063    var create$3 = function (root, caretPosition) {
9064      var container, offset, path = [], outputOffset, childNodes, parents;
9065      container = caretPosition.container();
9066      offset = caretPosition.offset();
9067      if (isText$5(container)) {
9068        outputOffset = normalizedTextOffset(container, offset);
9069      } else {
9070        childNodes = container.childNodes;
9071        if (offset >= childNodes.length) {
9072          outputOffset = 'after';
9073          offset = childNodes.length - 1;
9074        } else {
9075          outputOffset = 'before';
9076        }
9077        container = childNodes[offset];
9078      }
9079      path.push(createPathItem(container));
9080      parents = parentsUntil(root, container);
9081      parents = filter$2(parents, not(isBogus));
9082      path = path.concat(map$2(parents, function (node) {
9083        return createPathItem(node);
9084      }));
9085      return path.reverse().join('/') + ',' + outputOffset;
9086    };
9087    var resolvePathItem = function (node, name, index) {
9088      var nodes = getChildNodes(node);
9089      nodes = filter$2(nodes, function (node, index) {
9090        return !isText$5(node) || !isText$5(nodes[index - 1]);
9091      });
9092      nodes = filter$2(nodes, matchNodeNames([name]));
9093      return nodes[index];
9094    };
9095    var findTextPosition = function (container, offset) {
9096      var node = container, targetOffset = 0, dataLen;
9097      while (isText$5(node)) {
9098        dataLen = node.data.length;
9099        if (offset >= targetOffset && offset <= targetOffset + dataLen) {
9100          container = node;
9101          offset = offset - targetOffset;
9102          break;
9103        }
9104        if (!isText$5(node.nextSibling)) {
9105          container = node;
9106          offset = dataLen;
9107          break;
9108        }
9109        targetOffset += dataLen;
9110        node = node.nextSibling;
9111      }
9112      if (isText$5(container) && offset > container.data.length) {
9113        offset = container.data.length;
9114      }
9115      return CaretPosition$1(container, offset);
9116    };
9117    var resolve$1 = function (root, path) {
9118      var offset;
9119      if (!path) {
9120        return null;
9121      }
9122      var parts = path.split(',');
9123      var paths = parts[0].split('/');
9124      offset = parts.length > 1 ? parts[1] : 'before';
9125      var container = reduce(paths, function (result, value) {
9126        var match = /([\w\-\(\)]+)\[([0-9]+)\]/.exec(value);
9127        if (!match) {
9128          return null;
9129        }
9130        if (match[1] === 'text()') {
9131          match[1] = '#text';
9132        }
9133        return resolvePathItem(result, match[1], parseInt(match[2], 10));
9134      }, root);
9135      if (!container) {
9136        return null;
9137      }
9138      if (!isText$5(container)) {
9139        if (offset === 'after') {
9140          offset = nodeIndex$1(container) + 1;
9141        } else {
9142          offset = nodeIndex$1(container);
9143        }
9144        return CaretPosition$1(container.parentNode, offset);
9145      }
9146      return findTextPosition(container, parseInt(offset, 10));
9147    };
9148
9149    var isContentEditableFalse$2 = isContentEditableFalse;
9150    var getNormalizedTextOffset = function (trim, container, offset) {
9151      var node, trimmedOffset;
9152      trimmedOffset = trim(container.data.slice(0, offset)).length;
9153      for (node = container.previousSibling; node && isText$1(node); node = node.previousSibling) {
9154        trimmedOffset += trim(node.data).length;
9155      }
9156      return trimmedOffset;
9157    };
9158    var getPoint = function (dom, trim, normalized, rng, start) {
9159      var container = rng[start ? 'startContainer' : 'endContainer'];
9160      var offset = rng[start ? 'startOffset' : 'endOffset'];
9161      var point = [];
9162      var childNodes, after = 0;
9163      var root = dom.getRoot();
9164      if (isText$1(container)) {
9165        point.push(normalized ? getNormalizedTextOffset(trim, container, offset) : offset);
9166      } else {
9167        childNodes = container.childNodes;
9168        if (offset >= childNodes.length && childNodes.length) {
9169          after = 1;
9170          offset = Math.max(0, childNodes.length - 1);
9171        }
9172        point.push(dom.nodeIndex(childNodes[offset], normalized) + after);
9173      }
9174      for (; container && container !== root; container = container.parentNode) {
9175        point.push(dom.nodeIndex(container, normalized));
9176      }
9177      return point;
9178    };
9179    var getLocation = function (trim, selection, normalized, rng) {
9180      var dom = selection.dom, bookmark = {};
9181      bookmark.start = getPoint(dom, trim, normalized, rng, true);
9182      if (!selection.isCollapsed()) {
9183        bookmark.end = getPoint(dom, trim, normalized, rng, false);
9184      }
9185      return bookmark;
9186    };
9187    var findIndex$2 = function (dom, name, element) {
9188      var count = 0;
9189      Tools.each(dom.select(name), function (node) {
9190        if (node.getAttribute('data-mce-bogus') === 'all') {
9191          return;
9192        }
9193        if (node === element) {
9194          return false;
9195        }
9196        count++;
9197      });
9198      return count;
9199    };
9200    var moveEndPoint = function (rng, start) {
9201      var container, offset, childNodes;
9202      var prefix = start ? 'start' : 'end';
9203      container = rng[prefix + 'Container'];
9204      offset = rng[prefix + 'Offset'];
9205      if (isElement$1(container) && container.nodeName === 'TR') {
9206        childNodes = container.childNodes;
9207        container = childNodes[Math.min(start ? offset : offset - 1, childNodes.length - 1)];
9208        if (container) {
9209          offset = start ? 0 : container.childNodes.length;
9210          rng['set' + (start ? 'Start' : 'End')](container, offset);
9211        }
9212      }
9213    };
9214    var normalizeTableCellSelection = function (rng) {
9215      moveEndPoint(rng, true);
9216      moveEndPoint(rng, false);
9217      return rng;
9218    };
9219    var findSibling = function (node, offset) {
9220      var sibling;
9221      if (isElement$1(node)) {
9222        node = getNode(node, offset);
9223        if (isContentEditableFalse$2(node)) {
9224          return node;
9225        }
9226      }
9227      if (isCaretContainer(node)) {
9228        if (isText$1(node) && isCaretContainerBlock(node)) {
9229          node = node.parentNode;
9230        }
9231        sibling = node.previousSibling;
9232        if (isContentEditableFalse$2(sibling)) {
9233          return sibling;
9234        }
9235        sibling = node.nextSibling;
9236        if (isContentEditableFalse$2(sibling)) {
9237          return sibling;
9238        }
9239      }
9240    };
9241    var findAdjacentContentEditableFalseElm = function (rng) {
9242      return findSibling(rng.startContainer, rng.startOffset) || findSibling(rng.endContainer, rng.endOffset);
9243    };
9244    var getOffsetBookmark = function (trim, normalized, selection) {
9245      var element = selection.getNode();
9246      var name = element ? element.nodeName : null;
9247      var rng = selection.getRng();
9248      if (isContentEditableFalse$2(element) || name === 'IMG') {
9249        return {
9250          name: name,
9251          index: findIndex$2(selection.dom, name, element)
9252        };
9253      }
9254      var sibling = findAdjacentContentEditableFalseElm(rng);
9255      if (sibling) {
9256        name = sibling.tagName;
9257        return {
9258          name: name,
9259          index: findIndex$2(selection.dom, name, sibling)
9260        };
9261      }
9262      return getLocation(trim, selection, normalized, rng);
9263    };
9264    var getCaretBookmark = function (selection) {
9265      var rng = selection.getRng();
9266      return {
9267        start: create$3(selection.dom.getRoot(), CaretPosition$1.fromRangeStart(rng)),
9268        end: create$3(selection.dom.getRoot(), CaretPosition$1.fromRangeEnd(rng))
9269      };
9270    };
9271    var getRangeBookmark = function (selection) {
9272      return { rng: selection.getRng() };
9273    };
9274    var createBookmarkSpan = function (dom, id, filled) {
9275      var args = {
9276        'data-mce-type': 'bookmark',
9277        id: id,
9278        'style': 'overflow:hidden;line-height:0px'
9279      };
9280      return filled ? dom.create('span', args, '&#xFEFF;') : dom.create('span', args);
9281    };
9282    var getPersistentBookmark = function (selection, filled) {
9283      var dom = selection.dom;
9284      var rng = selection.getRng();
9285      var id = dom.uniqueId();
9286      var collapsed = selection.isCollapsed();
9287      var element = selection.getNode();
9288      var name = element.nodeName;
9289      if (name === 'IMG') {
9290        return {
9291          name: name,
9292          index: findIndex$2(dom, name, element)
9293        };
9294      }
9295      var rng2 = normalizeTableCellSelection(rng.cloneRange());
9296      if (!collapsed) {
9297        rng2.collapse(false);
9298        var endBookmarkNode = createBookmarkSpan(dom, id + '_end', filled);
9299        rangeInsertNode(dom, rng2, endBookmarkNode);
9300      }
9301      rng = normalizeTableCellSelection(rng);
9302      rng.collapse(true);
9303      var startBookmarkNode = createBookmarkSpan(dom, id + '_start', filled);
9304      rangeInsertNode(dom, rng, startBookmarkNode);
9305      selection.moveToBookmark({
9306        id: id,
9307        keep: true
9308      });
9309      return { id: id };
9310    };
9311    var getBookmark = function (selection, type, normalized) {
9312      if (type === 2) {
9313        return getOffsetBookmark(trim$2, normalized, selection);
9314      } else if (type === 3) {
9315        return getCaretBookmark(selection);
9316      } else if (type) {
9317        return getRangeBookmark(selection);
9318      } else {
9319        return getPersistentBookmark(selection, false);
9320      }
9321    };
9322    var getUndoBookmark = curry(getOffsetBookmark, identity, true);
9323
9324    var DOM$1 = DOMUtils$1.DOM;
9325    var defaultPreviewStyles = 'font-family font-size font-weight font-style text-decoration text-transform color background-color border border-radius outline text-shadow';
9326    var getBodySetting = function (editor, name, defaultValue) {
9327      var value = editor.getParam(name, defaultValue);
9328      if (value.indexOf('=') !== -1) {
9329        var bodyObj = editor.getParam(name, '', 'hash');
9330        return bodyObj.hasOwnProperty(editor.id) ? bodyObj[editor.id] : defaultValue;
9331      } else {
9332        return value;
9333      }
9334    };
9335    var getIframeAttrs = function (editor) {
9336      return editor.getParam('iframe_attrs', {});
9337    };
9338    var getDocType = function (editor) {
9339      return editor.getParam('doctype', '<!DOCTYPE html>');
9340    };
9341    var getDocumentBaseUrl = function (editor) {
9342      return editor.getParam('document_base_url', '');
9343    };
9344    var getBodyId = function (editor) {
9345      return getBodySetting(editor, 'body_id', 'tinymce');
9346    };
9347    var getBodyClass = function (editor) {
9348      return getBodySetting(editor, 'body_class', '');
9349    };
9350    var getContentSecurityPolicy = function (editor) {
9351      return editor.getParam('content_security_policy', '');
9352    };
9353    var shouldPutBrInPre = function (editor) {
9354      return editor.getParam('br_in_pre', true);
9355    };
9356    var getForcedRootBlock = function (editor) {
9357      if (editor.getParam('force_p_newlines', false)) {
9358        return 'p';
9359      }
9360      var block = editor.getParam('forced_root_block', 'p');
9361      if (block === false) {
9362        return '';
9363      } else if (block === true) {
9364        return 'p';
9365      } else {
9366        return block;
9367      }
9368    };
9369    var getForcedRootBlockAttrs = function (editor) {
9370      return editor.getParam('forced_root_block_attrs', {});
9371    };
9372    var getBrNewLineSelector = function (editor) {
9373      return editor.getParam('br_newline_selector', '.mce-toc h2,figcaption,caption');
9374    };
9375    var getNoNewLineSelector = function (editor) {
9376      return editor.getParam('no_newline_selector', '');
9377    };
9378    var shouldKeepStyles = function (editor) {
9379      return editor.getParam('keep_styles', true);
9380    };
9381    var shouldEndContainerOnEmptyBlock = function (editor) {
9382      return editor.getParam('end_container_on_empty_block', false);
9383    };
9384    var getFontStyleValues = function (editor) {
9385      return Tools.explode(editor.getParam('font_size_style_values', 'xx-small,x-small,small,medium,large,x-large,xx-large'));
9386    };
9387    var getFontSizeClasses = function (editor) {
9388      return Tools.explode(editor.getParam('font_size_classes', ''));
9389    };
9390    var getImagesDataImgFilter = function (editor) {
9391      return editor.getParam('images_dataimg_filter', always, 'function');
9392    };
9393    var isAutomaticUploadsEnabled = function (editor) {
9394      return editor.getParam('automatic_uploads', true, 'boolean');
9395    };
9396    var shouldReuseFileName = function (editor) {
9397      return editor.getParam('images_reuse_filename', false, 'boolean');
9398    };
9399    var shouldReplaceBlobUris = function (editor) {
9400      return editor.getParam('images_replace_blob_uris', true, 'boolean');
9401    };
9402    var getIconPackName = function (editor) {
9403      return editor.getParam('icons', '', 'string');
9404    };
9405    var getIconsUrl = function (editor) {
9406      return editor.getParam('icons_url', '', 'string');
9407    };
9408    var getImageUploadUrl = function (editor) {
9409      return editor.getParam('images_upload_url', '', 'string');
9410    };
9411    var getImageUploadBasePath = function (editor) {
9412      return editor.getParam('images_upload_base_path', '', 'string');
9413    };
9414    var getImagesUploadCredentials = function (editor) {
9415      return editor.getParam('images_upload_credentials', false, 'boolean');
9416    };
9417    var getImagesUploadHandler = function (editor) {
9418      return editor.getParam('images_upload_handler', null, 'function');
9419    };
9420    var shouldUseContentCssCors = function (editor) {
9421      return editor.getParam('content_css_cors', false, 'boolean');
9422    };
9423    var getReferrerPolicy = function (editor) {
9424      return editor.getParam('referrer_policy', '', 'string');
9425    };
9426    var getLanguageCode = function (editor) {
9427      return editor.getParam('language', 'en', 'string');
9428    };
9429    var getLanguageUrl = function (editor) {
9430      return editor.getParam('language_url', '', 'string');
9431    };
9432    var shouldIndentUseMargin = function (editor) {
9433      return editor.getParam('indent_use_margin', false);
9434    };
9435    var getIndentation = function (editor) {
9436      return editor.getParam('indentation', '40px', 'string');
9437    };
9438    var getContentCss = function (editor) {
9439      var contentCss = editor.getParam('content_css');
9440      if (isString(contentCss)) {
9441        return map(contentCss.split(','), trim);
9442      } else if (isArray(contentCss)) {
9443        return contentCss;
9444      } else if (contentCss === false || editor.inline) {
9445        return [];
9446      } else {
9447        return ['default'];
9448      }
9449    };
9450    var getDirectionality = function (editor) {
9451      return editor.getParam('directionality', I18n.isRtl() ? 'rtl' : undefined);
9452    };
9453    var getInlineBoundarySelector = function (editor) {
9454      return editor.getParam('inline_boundaries_selector', 'a[href],code,.mce-annotation', 'string');
9455    };
9456    var getObjectResizing = function (editor) {
9457      var selector = editor.getParam('object_resizing');
9458      if (selector === false || Env.iOS) {
9459        return false;
9460      } else {
9461        return isString(selector) ? selector : 'table,img,figure.image,div';
9462      }
9463    };
9464    var getResizeImgProportional = function (editor) {
9465      return editor.getParam('resize_img_proportional', true, 'boolean');
9466    };
9467    var getPlaceholder = function (editor) {
9468      return editor.getParam('placeholder', DOM$1.getAttrib(editor.getElement(), 'placeholder'), 'string');
9469    };
9470    var getEventRoot = function (editor) {
9471      return editor.getParam('event_root');
9472    };
9473    var getServiceMessage = function (editor) {
9474      return editor.getParam('service_message');
9475    };
9476    var getTheme = function (editor) {
9477      return editor.getParam('theme');
9478    };
9479    var shouldValidate = function (editor) {
9480      return editor.getParam('validate');
9481    };
9482    var isInlineBoundariesEnabled = function (editor) {
9483      return editor.getParam('inline_boundaries') !== false;
9484    };
9485    var getFormats = function (editor) {
9486      return editor.getParam('formats');
9487    };
9488    var getPreviewStyles = function (editor) {
9489      var style = editor.getParam('preview_styles', defaultPreviewStyles);
9490      if (isString(style)) {
9491        return style;
9492      } else {
9493        return '';
9494      }
9495    };
9496    var getCustomUiSelector = function (editor) {
9497      return editor.getParam('custom_ui_selector', '', 'string');
9498    };
9499    var getThemeUrl = function (editor) {
9500      return editor.getParam('theme_url');
9501    };
9502    var isInline$1 = function (editor) {
9503      return editor.getParam('inline');
9504    };
9505    var hasHiddenInput = function (editor) {
9506      return editor.getParam('hidden_input');
9507    };
9508    var shouldPatchSubmit = function (editor) {
9509      return editor.getParam('submit_patch');
9510    };
9511    var isEncodingXml = function (editor) {
9512      return editor.getParam('encoding') === 'xml';
9513    };
9514    var shouldAddFormSubmitTrigger = function (editor) {
9515      return editor.getParam('add_form_submit_trigger');
9516    };
9517    var shouldAddUnloadTrigger = function (editor) {
9518      return editor.getParam('add_unload_trigger');
9519    };
9520    var hasForcedRootBlock = function (editor) {
9521      return getForcedRootBlock(editor) !== '';
9522    };
9523    var getCustomUndoRedoLevels = function (editor) {
9524      return editor.getParam('custom_undo_redo_levels', 0, 'number');
9525    };
9526    var shouldDisableNodeChange = function (editor) {
9527      return editor.getParam('disable_nodechange');
9528    };
9529    var isReadOnly = function (editor) {
9530      return editor.getParam('readonly');
9531    };
9532    var hasContentCssCors = function (editor) {
9533      return editor.getParam('content_css_cors');
9534    };
9535    var getPlugins = function (editor) {
9536      return editor.getParam('plugins', '', 'string');
9537    };
9538    var getExternalPlugins = function (editor) {
9539      return editor.getParam('external_plugins');
9540    };
9541    var shouldBlockUnsupportedDrop = function (editor) {
9542      return editor.getParam('block_unsupported_drop', true, 'boolean');
9543    };
9544
9545    var isElement$4 = isElement$1;
9546    var isText$6 = isText$1;
9547    var removeNode = function (node) {
9548      var parentNode = node.parentNode;
9549      if (parentNode) {
9550        parentNode.removeChild(node);
9551      }
9552    };
9553    var trimCount = function (text) {
9554      var trimmedText = trim$2(text);
9555      return {
9556        count: text.length - trimmedText.length,
9557        text: trimmedText
9558      };
9559    };
9560    var deleteZwspChars = function (caretContainer) {
9561      var idx;
9562      while ((idx = caretContainer.data.lastIndexOf(ZWSP)) !== -1) {
9563        caretContainer.deleteData(idx, 1);
9564      }
9565    };
9566    var removeUnchanged = function (caretContainer, pos) {
9567      remove$5(caretContainer);
9568      return pos;
9569    };
9570    var removeTextAndReposition = function (caretContainer, pos) {
9571      var before = trimCount(caretContainer.data.substr(0, pos.offset()));
9572      var after = trimCount(caretContainer.data.substr(pos.offset()));
9573      var text = before.text + after.text;
9574      if (text.length > 0) {
9575        deleteZwspChars(caretContainer);
9576        return CaretPosition$1(caretContainer, pos.offset() - before.count);
9577      } else {
9578        return pos;
9579      }
9580    };
9581    var removeElementAndReposition = function (caretContainer, pos) {
9582      var parentNode = pos.container();
9583      var newPosition = indexOf(from$1(parentNode.childNodes), caretContainer).map(function (index) {
9584        return index < pos.offset() ? CaretPosition$1(parentNode, pos.offset() - 1) : pos;
9585      }).getOr(pos);
9586      remove$5(caretContainer);
9587      return newPosition;
9588    };
9589    var removeTextCaretContainer = function (caretContainer, pos) {
9590      return isText$6(caretContainer) && pos.container() === caretContainer ? removeTextAndReposition(caretContainer, pos) : removeUnchanged(caretContainer, pos);
9591    };
9592    var removeElementCaretContainer = function (caretContainer, pos) {
9593      return pos.container() === caretContainer.parentNode ? removeElementAndReposition(caretContainer, pos) : removeUnchanged(caretContainer, pos);
9594    };
9595    var removeAndReposition = function (container, pos) {
9596      return CaretPosition$1.isTextPosition(pos) ? removeTextCaretContainer(container, pos) : removeElementCaretContainer(container, pos);
9597    };
9598    var remove$5 = function (caretContainerNode) {
9599      if (isElement$4(caretContainerNode) && isCaretContainer(caretContainerNode)) {
9600        if (hasContent(caretContainerNode)) {
9601          caretContainerNode.removeAttribute('data-mce-caret');
9602        } else {
9603          removeNode(caretContainerNode);
9604        }
9605      }
9606      if (isText$6(caretContainerNode)) {
9607        deleteZwspChars(caretContainerNode);
9608        if (caretContainerNode.data.length === 0) {
9609          removeNode(caretContainerNode);
9610        }
9611      }
9612    };
9613
9614    var browser$2 = detect$3().browser;
9615    var isContentEditableFalse$3 = isContentEditableFalse;
9616    var isMedia$1 = isMedia;
9617    var isTableCell$2 = isTableCell;
9618    var inlineFakeCaretSelector = '*[contentEditable=false],video,audio,embed,object';
9619    var getAbsoluteClientRect = function (root, element, before) {
9620      var clientRect = collapse(element.getBoundingClientRect(), before);
9621      var docElm, scrollX, scrollY, margin, rootRect;
9622      if (root.tagName === 'BODY') {
9623        docElm = root.ownerDocument.documentElement;
9624        scrollX = root.scrollLeft || docElm.scrollLeft;
9625        scrollY = root.scrollTop || docElm.scrollTop;
9626      } else {
9627        rootRect = root.getBoundingClientRect();
9628        scrollX = root.scrollLeft - rootRect.left;
9629        scrollY = root.scrollTop - rootRect.top;
9630      }
9631      clientRect.left += scrollX;
9632      clientRect.right += scrollX;
9633      clientRect.top += scrollY;
9634      clientRect.bottom += scrollY;
9635      clientRect.width = 1;
9636      margin = element.offsetWidth - element.clientWidth;
9637      if (margin > 0) {
9638        if (before) {
9639          margin *= -1;
9640        }
9641        clientRect.left += margin;
9642        clientRect.right += margin;
9643      }
9644      return clientRect;
9645    };
9646    var trimInlineCaretContainers = function (root) {
9647      var fakeCaretTargetNodes = descendants$1(SugarElement.fromDom(root), inlineFakeCaretSelector);
9648      for (var i = 0; i < fakeCaretTargetNodes.length; i++) {
9649        var node = fakeCaretTargetNodes[i].dom;
9650        var sibling = node.previousSibling;
9651        if (endsWithCaretContainer(sibling)) {
9652          var data = sibling.data;
9653          if (data.length === 1) {
9654            sibling.parentNode.removeChild(sibling);
9655          } else {
9656            sibling.deleteData(data.length - 1, 1);
9657          }
9658        }
9659        sibling = node.nextSibling;
9660        if (startsWithCaretContainer(sibling)) {
9661          var data = sibling.data;
9662          if (data.length === 1) {
9663            sibling.parentNode.removeChild(sibling);
9664          } else {
9665            sibling.deleteData(0, 1);
9666          }
9667        }
9668      }
9669    };
9670    var FakeCaret = function (editor, root, isBlock, hasFocus) {
9671      var lastVisualCaret = Cell(Optional.none());
9672      var cursorInterval, caretContainerNode;
9673      var rootBlock = getForcedRootBlock(editor);
9674      var caretBlock = rootBlock.length > 0 ? rootBlock : 'p';
9675      var show = function (before, element) {
9676        var clientRect, rng;
9677        hide();
9678        if (isTableCell$2(element)) {
9679          return null;
9680        }
9681        if (isBlock(element)) {
9682          caretContainerNode = insertBlock(caretBlock, element, before);
9683          clientRect = getAbsoluteClientRect(root, element, before);
9684          DomQuery(caretContainerNode).css('top', clientRect.top);
9685          var caret = DomQuery('<div class="mce-visual-caret" data-mce-bogus="all"></div>').css(clientRect).appendTo(root)[0];
9686          lastVisualCaret.set(Optional.some({
9687            caret: caret,
9688            element: element,
9689            before: before
9690          }));
9691          lastVisualCaret.get().each(function (caretState) {
9692            if (before) {
9693              DomQuery(caretState.caret).addClass('mce-visual-caret-before');
9694            }
9695          });
9696          startBlink();
9697          rng = element.ownerDocument.createRange();
9698          rng.setStart(caretContainerNode, 0);
9699          rng.setEnd(caretContainerNode, 0);
9700        } else {
9701          caretContainerNode = insertInline(element, before);
9702          rng = element.ownerDocument.createRange();
9703          if (isInlineFakeCaretTarget(caretContainerNode.nextSibling)) {
9704            rng.setStart(caretContainerNode, 0);
9705            rng.setEnd(caretContainerNode, 0);
9706          } else {
9707            rng.setStart(caretContainerNode, 1);
9708            rng.setEnd(caretContainerNode, 1);
9709          }
9710          return rng;
9711        }
9712        return rng;
9713      };
9714      var hide = function () {
9715        trimInlineCaretContainers(root);
9716        if (caretContainerNode) {
9717          remove$5(caretContainerNode);
9718          caretContainerNode = null;
9719        }
9720        lastVisualCaret.get().each(function (caretState) {
9721          DomQuery(caretState.caret).remove();
9722          lastVisualCaret.set(Optional.none());
9723        });
9724        if (cursorInterval) {
9725          Delay.clearInterval(cursorInterval);
9726          cursorInterval = null;
9727        }
9728      };
9729      var startBlink = function () {
9730        cursorInterval = Delay.setInterval(function () {
9731          if (hasFocus()) {
9732            DomQuery('div.mce-visual-caret', root).toggleClass('mce-visual-caret-hidden');
9733          } else {
9734            DomQuery('div.mce-visual-caret', root).addClass('mce-visual-caret-hidden');
9735          }
9736        }, 500);
9737      };
9738      var reposition = function () {
9739        lastVisualCaret.get().each(function (caretState) {
9740          var clientRect = getAbsoluteClientRect(root, caretState.element, caretState.before);
9741          DomQuery(caretState.caret).css(__assign({}, clientRect));
9742        });
9743      };
9744      var destroy = function () {
9745        return Delay.clearInterval(cursorInterval);
9746      };
9747      var getCss = function () {
9748        return '.mce-visual-caret {' + 'position: absolute;' + 'background-color: black;' + 'background-color: currentcolor;' + '}' + '.mce-visual-caret-hidden {' + 'display: none;' + '}' + '*[data-mce-caret] {' + 'position: absolute;' + 'left: -1000px;' + 'right: auto;' + 'top: 0;' + 'margin: 0;' + 'padding: 0;' + '}';
9749      };
9750      return {
9751        show: show,
9752        hide: hide,
9753        getCss: getCss,
9754        reposition: reposition,
9755        destroy: destroy
9756      };
9757    };
9758    var isFakeCaretTableBrowser = function () {
9759      return browser$2.isIE() || browser$2.isEdge() || browser$2.isFirefox();
9760    };
9761    var isInlineFakeCaretTarget = function (node) {
9762      return isContentEditableFalse$3(node) || isMedia$1(node);
9763    };
9764    var isFakeCaretTarget = function (node) {
9765      return isInlineFakeCaretTarget(node) || isTable(node) && isFakeCaretTableBrowser();
9766    };
9767
9768    var isContentEditableFalse$4 = isContentEditableFalse;
9769    var isMedia$2 = isMedia;
9770    var isBlockLike = matchStyleValues('display', 'block table table-cell table-caption list-item');
9771    var isCaretContainer$2 = isCaretContainer;
9772    var isCaretContainerBlock$1 = isCaretContainerBlock;
9773    var isElement$5 = isElement$1;
9774    var isCaretCandidate$2 = isCaretCandidate;
9775    var isForwards = function (direction) {
9776      return direction > 0;
9777    };
9778    var isBackwards = function (direction) {
9779      return direction < 0;
9780    };
9781    var skipCaretContainers = function (walk, shallow) {
9782      var node;
9783      while (node = walk(shallow)) {
9784        if (!isCaretContainerBlock$1(node)) {
9785          return node;
9786        }
9787      }
9788      return null;
9789    };
9790    var findNode = function (node, direction, predicateFn, rootNode, shallow) {
9791      var walker = new DomTreeWalker(node, rootNode);
9792      var isCefOrCaretContainer = isContentEditableFalse$4(node) || isCaretContainerBlock$1(node);
9793      if (isBackwards(direction)) {
9794        if (isCefOrCaretContainer) {
9795          node = skipCaretContainers(walker.prev, true);
9796          if (predicateFn(node)) {
9797            return node;
9798          }
9799        }
9800        while (node = skipCaretContainers(walker.prev, shallow)) {
9801          if (predicateFn(node)) {
9802            return node;
9803          }
9804        }
9805      }
9806      if (isForwards(direction)) {
9807        if (isCefOrCaretContainer) {
9808          node = skipCaretContainers(walker.next, true);
9809          if (predicateFn(node)) {
9810            return node;
9811          }
9812        }
9813        while (node = skipCaretContainers(walker.next, shallow)) {
9814          if (predicateFn(node)) {
9815            return node;
9816          }
9817        }
9818      }
9819      return null;
9820    };
9821    var getParentBlock = function (node, rootNode) {
9822      while (node && node !== rootNode) {
9823        if (isBlockLike(node)) {
9824          return node;
9825        }
9826        node = node.parentNode;
9827      }
9828      return null;
9829    };
9830    var isInSameBlock = function (caretPosition1, caretPosition2, rootNode) {
9831      return getParentBlock(caretPosition1.container(), rootNode) === getParentBlock(caretPosition2.container(), rootNode);
9832    };
9833    var getChildNodeAtRelativeOffset = function (relativeOffset, caretPosition) {
9834      if (!caretPosition) {
9835        return null;
9836      }
9837      var container = caretPosition.container();
9838      var offset = caretPosition.offset();
9839      if (!isElement$5(container)) {
9840        return null;
9841      }
9842      return container.childNodes[offset + relativeOffset];
9843    };
9844    var beforeAfter = function (before, node) {
9845      var range = node.ownerDocument.createRange();
9846      if (before) {
9847        range.setStartBefore(node);
9848        range.setEndBefore(node);
9849      } else {
9850        range.setStartAfter(node);
9851        range.setEndAfter(node);
9852      }
9853      return range;
9854    };
9855    var isNodesInSameBlock = function (root, node1, node2) {
9856      return getParentBlock(node1, root) === getParentBlock(node2, root);
9857    };
9858    var lean = function (left, root, node) {
9859      var sibling, siblingName;
9860      if (left) {
9861        siblingName = 'previousSibling';
9862      } else {
9863        siblingName = 'nextSibling';
9864      }
9865      while (node && node !== root) {
9866        sibling = node[siblingName];
9867        if (isCaretContainer$2(sibling)) {
9868          sibling = sibling[siblingName];
9869        }
9870        if (isContentEditableFalse$4(sibling) || isMedia$2(sibling)) {
9871          if (isNodesInSameBlock(root, sibling, node)) {
9872            return sibling;
9873          }
9874          break;
9875        }
9876        if (isCaretCandidate$2(sibling)) {
9877          break;
9878        }
9879        node = node.parentNode;
9880      }
9881      return null;
9882    };
9883    var before$2 = curry(beforeAfter, true);
9884    var after$1 = curry(beforeAfter, false);
9885    var normalizeRange = function (direction, root, range) {
9886      var node, container, location;
9887      var leanLeft = curry(lean, true, root);
9888      var leanRight = curry(lean, false, root);
9889      container = range.startContainer;
9890      var offset = range.startOffset;
9891      if (isCaretContainerBlock(container)) {
9892        if (!isElement$5(container)) {
9893          container = container.parentNode;
9894        }
9895        location = container.getAttribute('data-mce-caret');
9896        if (location === 'before') {
9897          node = container.nextSibling;
9898          if (isFakeCaretTarget(node)) {
9899            return before$2(node);
9900          }
9901        }
9902        if (location === 'after') {
9903          node = container.previousSibling;
9904          if (isFakeCaretTarget(node)) {
9905            return after$1(node);
9906          }
9907        }
9908      }
9909      if (!range.coll
9909apsed) {
9910        return range;
9911      }
9912      if (isText$1(container)) {
9913        if (isCaretContainer$2(container)) {
9914          if (direction === 1) {
9915            node = leanRight(container);
9916            if (node) {
9917              return before$2(node);
9918            }
9919            node = leanLeft(container);
9920            if (node) {
9921              return after$1(node);
9922            }
9923          }
9924          if (direction === -1) {
9925            node = leanLeft(container);
9926            if (node) {
9927              return after$1(node);
9928            }
9929            node = leanRight(container);
9930            if (node) {
9931              return before$2(node);
9932            }
9933          }
9934          return range;
9935        }
9936        if (endsWithCaretContainer(container) && offset >= container.data.length - 1) {
9937          if (direction === 1) {
9938            node = leanRight(container);
9939            if (node) {
9940              return before$2(node);
9941            }
9942          }
9943          return range;
9944        }
9945        if (startsWithCaretContainer(container) && offset <= 1) {
9946          if (direction === -1) {
9947            node = leanLeft(container);
9948            if (node) {
9949              return after$1(node);
9950            }
9951          }
9952          return range;
9953        }
9954        if (offset === container.data.length) {
9955          node = leanRight(container);
9956          if (node) {
9957            return before$2(node);
9958          }
9959          return range;
9960        }
9961        if (offset === 0) {
9962          node = leanLeft(container);
9963          if (node) {
9964            return after$1(node);
9965          }
9966          return range;
9967        }
9968      }
9969      return range;
9970    };
9971    var getRelativeCefElm = function (forward, caretPosition) {
9972      return Optional.from(getChildNodeAtRelativeOffset(forward ? 0 : -1, caretPosition)).filter(isContentEditableFalse$4);
9973    };
9974    var getNormalizedRangeEndPoint = function (direction, root, range) {
9975      var normalizedRange = normalizeRange(direction, root, range);
9976      if (direction === -1) {
9977        return CaretPosition.fromRangeStart(normalizedRange);
9978      }
9979      return CaretPosition.fromRangeEnd(normalizedRange);
9980    };
9981    var getElementFromPosition = function (pos) {
9982      return Optional.from(pos.getNode()).map(SugarElement.fromDom);
9983    };
9984    var getElementFromPrevPosition = function (pos) {
9985      return Optional.from(pos.getNode(true)).map(SugarElement.fromDom);
9986    };
9987    var getVisualCaretPosition = function (walkFn, caretPosition) {
9988      while (caretPosition = walkFn(caretPosition)) {
9989        if (caretPosition.isVisible()) {
9990          return caretPosition;
9991        }
9992      }
9993      return caretPosition;
9994    };
9995    var isMoveInsideSameBlock = function (from, to) {
9996      var inSameBlock = isInSameBlock(from, to);
9997      if (!inSameBlock && isBr(from.getNode())) {
9998        return true;
9999      }
10000      return inSameBlock;
10001    };
10002
10003    var HDirection;
10004    (function (HDirection) {
10005      HDirection[HDirection['Backwards'] = -1] = 'Backwards';
10006      HDirection[HDirection['Forwards'] = 1] = 'Forwards';
10007    }(HDirection || (HDirection = {})));
10008    var isContentEditableFalse$5 = isContentEditableFalse;
10009    var isText$7 = isText$1;
10010    var isElement$6 = isElement$1;
10011    var isBr$4 = isBr;
10012    var isCaretCandidate$3 = isCaretCandidate;
10013    var isAtomic$1 = isAtomic;
10014    var isEditableCaretCandidate$1 = isEditableCaretCandidate;
10015    var getParents = function (node, root) {
10016      var parents = [];
10017      while (node && node !== root) {
10018        parents.push(node);
10019        node = node.parentNode;
10020      }
10021      return parents;
10022    };
10023    var nodeAtIndex = function (container, offset) {
10024      if (container.hasChildNodes() && offset < container.childNodes.length) {
10025        return container.childNodes[offset];
10026      }
10027      return null;
10028    };
10029    var getCaretCandidatePosition = function (direction, node) {
10030      if (isForwards(direction)) {
10031        if (isCaretCandidate$3(node.previousSibling) && !isText$7(node.previousSibling)) {
10032          return CaretPosition$1.before(node);
10033        }
10034        if (isText$7(node)) {
10035          return CaretPosition$1(node, 0);
10036        }
10037      }
10038      if (isBackwards(direction)) {
10039        if (isCaretCandidate$3(node.nextSibling) && !isText$7(node.nextSibling)) {
10040          return CaretPosition$1.after(node);
10041        }
10042        if (isText$7(node)) {
10043          return CaretPosition$1(node, node.data.length);
10044        }
10045      }
10046      if (isBackwards(direction)) {
10047        if (isBr$4(node)) {
10048          return CaretPosition$1.before(node);
10049        }
10050        return CaretPosition$1.after(node);
10051      }
10052      return CaretPosition$1.before(node);
10053    };
10054    var moveForwardFromBr = function (root, nextNode) {
10055      var nextSibling = nextNode.nextSibling;
10056      if (nextSibling && isCaretCandidate$3(nextSibling)) {
10057        if (isText$7(nextSibling)) {
10058          return CaretPosition$1(nextSibling, 0);
10059        } else {
10060          return CaretPosition$1.before(nextSibling);
10061        }
10062      } else {
10063        return findCaretPosition(HDirection.Forwards, CaretPosition$1.after(nextNode), root);
10064      }
10065    };
10066    var findCaretPosition = function (direction, startPos, root) {
10067      var node, nextNode, innerNode;
10068      var caretPosition;
10069      if (!isElement$6(root) || !startPos) {
10070        return null;
10071      }
10072      if (startPos.isEqual(CaretPosition$1.after(root)) && root.lastChild) {
10073        caretPosition = CaretPosition$1.after(root.lastChild);
10074        if (isBackwards(direction) && isCaretCandidate$3(root.lastChild) && isElement$6(root.lastChild)) {
10075          return isBr$4(root.lastChild) ? CaretPosition$1.before(root.lastChild) : caretPosition;
10076        }
10077      } else {
10078        caretPosition = startPos;
10079      }
10080      var container = caretPosition.container();
10081      var offset = caretPosition.offset();
10082      if (isText$7(container)) {
10083        if (isBackwards(direction) && offset > 0) {
10084          return CaretPosition$1(container, --offset);
10085        }
10086        if (isForwards(direction) && offset < container.length) {
10087          return CaretPosition$1(container, ++offset);
10088        }
10089        node = container;
10090      } else {
10091        if (isBackwards(direction) && offset > 0) {
10092          nextNode = nodeAtIndex(container, offset - 1);
10093          if (isCaretCandidate$3(nextNode)) {
10094            if (!isAtomic$1(nextNode)) {
10095              innerNode = findNode(nextNode, direction, isEditableCaretCandidate$1, nextNode);
10096              if (innerNode) {
10097                if (isText$7(innerNode)) {
10098                  return CaretPosition$1(innerNode, innerNode.data.length);
10099                }
10100                return CaretPosition$1.after(innerNode);
10101              }
10102            }
10103            if (isText$7(nextNode)) {
10104              return CaretPosition$1(nextNode, nextNode.data.length);
10105            }
10106            return CaretPosition$1.before(nextNode);
10107          }
10108        }
10109        if (isForwards(direction) && offset < container.childNodes.length) {
10110          nextNode = nodeAtIndex(container, offset);
10111          if (isCaretCandidate$3(nextNode)) {
10112            if (isBr$4(nextNode)) {
10113              return moveForwardFromBr(root, nextNode);
10114            }
10115            if (!isAtomic$1(nextNode)) {
10116              innerNode = findNode(nextNode, direction, isEditableCaretCandidate$1, nextNode);
10117              if (innerNode) {
10118                if (isText$7(innerNode)) {
10119                  return CaretPosition$1(innerNode, 0);
10120                }
10121                return CaretPosition$1.before(innerNode);
10122              }
10123            }
10124            if (isText$7(nextNode)) {
10125              return CaretPosition$1(nextNode, 0);
10126            }
10127            return CaretPosition$1.after(nextNode);
10128          }
10129        }
10130        node = nextNode ? nextNode : caretPosition.getNode();
10131      }
10132      if (isForwards(direction) && caretPosition.isAtEnd() || isBackwards(direction) && caretPosition.isAtStart()) {
10133        node = findNode(node, direction, always, root, true);
10134        if (isEditableCaretCandidate$1(node, root)) {
10135          return getCaretCandidatePosition(direction, node);
10136        }
10137      }
10138      nextNode = findNode(node, direction, isEditableCaretCandidate$1, root);
10139      var rootContentEditableFalseElm = last$1(filter(getParents(container, root), isContentEditableFalse$5));
10140      if (rootContentEditableFalseElm && (!nextNode || !rootContentEditableFalseElm.contains(nextNode))) {
10141        if (isForwards(direction)) {
10142          caretPosition = CaretPosition$1.after(rootContentEditableFalseElm);
10143        } else {
10144          caretPosition = CaretPosition$1.before(rootContentEditableFalseElm);
10145        }
10146        return caretPosition;
10147      }
10148      if (nextNode) {
10149        return getCaretCandidatePosition(direction, nextNode);
10150      }
10151      return null;
10152    };
10153    var CaretWalker = function (root) {
10154      return {
10155        next: function (caretPosition) {
10156          return findCaretPosition(HDirection.Forwards, caretPosition, root);
10157        },
10158        prev: function (caretPosition) {
10159          return findCaretPosition(HDirection.Backwards, caretPosition, root);
10160        }
10161      };
10162    };
10163
10164    var walkToPositionIn = function (forward, root, start) {
10165      var position = forward ? CaretPosition$1.before(start) : CaretPosition$1.after(start);
10166      return fromPosition(forward, root, position);
10167    };
10168    var afterElement = function (node) {
10169      return isBr(node) ? CaretPosition$1.before(node) : CaretPosition$1.after(node);
10170    };
10171    var isBeforeOrStart = function (position) {
10172      if (CaretPosition$1.isTextPosition(position)) {
10173        return position.offset() === 0;
10174      } else {
10175        return isCaretCandidate(position.getNode());
10176      }
10177    };
10178    var isAfterOrEnd = function (position) {
10179      if (CaretPosition$1.isTextPosition(position)) {
10180        var container = position.container();
10181        return position.offset() === container.data.length;
10182      } else {
10183        return isCaretCandidate(position.getNode(true));
10184      }
10185    };
10186    var isBeforeAfterSameElement = function (from, to) {
10187      return !CaretPosition$1.isTextPosition(from) && !CaretPosition$1.isTextPosition(to) && from.getNode() === to.getNode(true);
10188    };
10189    var isAtBr = function (position) {
10190      return !CaretPosition$1.isTextPosition(position) && isBr(position.getNode());
10191    };
10192    var shouldSkipPosition = function (forward, from, to) {
10193      if (forward) {
10194        return !isBeforeAfterSameElement(from, to) && !isAtBr(from) && isAfterOrEnd(from) && isBeforeOrStart(to);
10195      } else {
10196        return !isBeforeAfterSameElement(to, from) && isBeforeOrStart(from) && isAfterOrEnd(to);
10197      }
10198    };
10199    var fromPosition = function (forward, root, pos) {
10200      var walker = CaretWalker(root);
10201      return Optional.from(forward ? walker.next(pos) : walker.prev(pos));
10202    };
10203    var navigate = function (forward, root, from) {
10204      return fromPosition(forward, root, from).bind(function (to) {
10205        if (isInSameBlock(from, to, root) && shouldSkipPosition(forward, from, to)) {
10206          return fromPosition(forward, root, to);
10207        } else {
10208          return Optional.some(to);
10209        }
10210      });
10211    };
10212    var navigateIgnore = function (forward, root, from, ignoreFilter) {
10213      return navigate(forward, root, from).bind(function (pos) {
10214        return ignoreFilter(pos) ? navigateIgnore(forward, root, pos, ignoreFilter) : Optional.some(pos);
10215      });
10216    };
10217    var positionIn = function (forward, element) {
10218      var startNode = forward ? element.firstChild : element.lastChild;
10219      if (isText$1(startNode)) {
10220        return Optional.some(CaretPosition$1(startNode, forward ? 0 : startNode.data.length));
10221      } else if (startNode) {
10222        if (isCaretCandidate(startNode)) {
10223          return Optional.some(forward ? CaretPosition$1.before(startNode) : afterElement(startNode));
10224        } else {
10225          return walkToPositionIn(forward, element, startNode);
10226        }
10227      } else {
10228        return Optional.none();
10229      }
10230    };
10231    var nextPosition = curry(fromPosition, true);
10232    var prevPosition = curry(fromPosition, false);
10233    var firstPositionIn = curry(positionIn, true);
10234    var lastPositionIn = curry(positionIn, false);
10235
10236    var CARET_ID = '_mce_caret';
10237    var isCaretNode = function (node) {
10238      return isElement$1(node) && node.id === CARET_ID;
10239    };
10240    var getParentCaretContainer = function (body, node) {
10241      while (node && node !== body) {
10242        if (node.id === CARET_ID) {
10243          return node;
10244        }
10245        node = node.parentNode;
10246      }
10247      return null;
10248    };
10249
10250    var isStringPathBookmark = function (bookmark) {
10251      return typeof bookmark.start === 'string';
10252    };
10253    var isRangeBookmark = function (bookmark) {
10254      return bookmark.hasOwnProperty('rng');
10255    };
10256    var isIdBookmark = function (bookmark) {
10257      return bookmark.hasOwnProperty('id');
10258    };
10259    var isIndexBookmark = function (bookmark) {
10260      return bookmark.hasOwnProperty('name');
10261    };
10262    var isPathBookmark = function (bookmark) {
10263      return Tools.isArray(bookmark.start);
10264    };
10265
10266    var addBogus = function (dom, node) {
10267      if (isElement$1(node) && dom.isBlock(node) && !node.innerHTML && !Env.ie) {
10268        node.innerHTML = '<br data-mce-bogus="1" />';
10269      }
10270      return node;
10271    };
10272    var resolveCaretPositionBookmark = function (dom, bookmark) {
10273      var pos;
10274      var rng = dom.createRng();
10275      pos = resolve$1(dom.getRoot(), bookmark.start);
10276      rng.setStart(pos.container(), pos.offset());
10277      pos = resolve$1(dom.getRoot(), bookmark.end);
10278      rng.setEnd(pos.container(), pos.offset());
10279      return rng;
10280    };
10281    var insertZwsp = function (node, rng) {
10282      var textNode = node.ownerDocument.createTextNode(ZWSP);
10283      node.appendChild(textNode);
10284      rng.setStart(textNode, 0);
10285      rng.setEnd(textNode, 0);
10286    };
10287    var isEmpty$1 = function (node) {
10288      return node.hasChildNodes() === false;
10289    };
10290    var tryFindRangePosition = function (node, rng) {
10291      return lastPositionIn(node).fold(function () {
10292        return false;
10293      }, function (pos) {
10294        rng.setStart(pos.container(), pos.offset());
10295        rng.setEnd(pos.container(), pos.offset());
10296        return true;
10297      });
10298    };
10299    var padEmptyCaretContainer = function (root, node, rng) {
10300      if (isEmpty$1(node) && getParentCaretContainer(root, node)) {
10301        insertZwsp(node, rng);
10302        return true;
10303      } else {
10304        return false;
10305      }
10306    };
10307    var setEndPoint = function (dom, start, bookmark, rng) {
10308      var point = bookmark[start ? 'start' : 'end'];
10309      var i, node, offset, children;
10310      var root = dom.getRoot();
10311      if (point) {
10312        offset = point[0];
10313        for (node = root, i = point.length - 1; i >= 1; i--) {
10314          children = node.childNodes;
10315          if (padEmptyCaretContainer(root, node, rng)) {
10316            return true;
10317          }
10318          if (point[i] > children.length - 1) {
10319            if (padEmptyCaretContainer(root, node, rng)) {
10320              return true;
10321            }
10322            return tryFindRangePosition(node, rng);
10323          }
10324          node = children[point[i]];
10325        }
10326        if (node.nodeType === 3) {
10327          offset = Math.min(point[0], node.nodeValue.length);
10328        }
10329        if (node.nodeType === 1) {
10330          offset = Math.min(point[0], node.childNodes.length);
10331        }
10332        if (start) {
10333          rng.setStart(node, offset);
10334        } else {
10335          rng.setEnd(node, offset);
10336        }
10337      }
10338      return true;
10339    };
10340    var isValidTextNode = function (node) {
10341      return isText$1(node) && node.data.length > 0;
10342    };
10343    var restoreEndPoint = function (dom, suffix, bookmark) {
10344      var marker = dom.get(bookmark.id + '_' + suffix), node, idx, next, prev;
10345      var keep = bookmark.keep;
10346      var container, offset;
10347      if (marker) {
10348        node = marker.parentNode;
10349        if (suffix === 'start') {
10350          if (!keep) {
10351            idx = dom.nodeIndex(marker);
10352          } else {
10353            if (marker.hasChildNodes()) {
10354              node = marker.firstChild;
10355              idx = 1;
10356            } else if (isValidTextNode(marker.nextSibling)) {
10357              node = marker.nextSibling;
10358              idx = 0;
10359            } else if (isValidTextNode(marker.previousSibling)) {
10360              node = marker.previousSibling;
10361              idx = marker.previousSibling.data.length;
10362            } else {
10363              node = marker.parentNode;
10364              idx = dom.nodeIndex(marker) + 1;
10365            }
10366          }
10367          container = node;
10368          offset = idx;
10369        } else {
10370          if (!keep) {
10371            idx = dom.nodeIndex(marker);
10372          } else {
10373            if (marker.hasChildNodes()) {
10374              node = marker.firstChild;
10375              idx = 1;
10376            } else if (isValidTextNode(marker.previousSibling)) {
10377              node = marker.previousSibling;
10378              idx = marker.previousSibling.data.length;
10379            } else {
10380              node = marker.parentNode;
10381              idx = dom.nodeIndex(marker);
10382            }
10383          }
10384          container = node;
10385          offset = idx;
10386        }
10387        if (!keep) {
10388          prev = marker.previousSibling;
10389          next = marker.nextSibling;
10390          Tools.each(Tools.grep(marker.childNodes), function (node) {
10391            if (isText$1(node)) {
10392              node.nodeValue = node.nodeValue.replace(/\uFEFF/g, '');
10393            }
10394          });
10395          while (marker = dom.get(bookmark.id + '_' + suffix)) {
10396            dom.remove(marker, true);
10397          }
10398          if (prev && next && prev.nodeType === next.nodeType && isText$1(prev) && !Env.opera) {
10399            idx = prev.nodeValue.length;
10400            prev.appendData(next.nodeValue);
10401            dom.remove(next);
10402            container = prev;
10403            offset = idx;
10404          }
10405        }
10406        return Optional.some(CaretPosition$1(container, offset));
10407      } else {
10408        return Optional.none();
10409      }
10410    };
10411    var resolvePaths = function (dom, bookmark) {
10412      var rng = dom.createRng();
10413      if (setEndPoint(dom, true, bookmark, rng) && setEndPoint(dom, false, bookmark, rng)) {
10414        return Optional.some(rng);
10415      } else {
10416        return Optional.none();
10417      }
10418    };
10419    var resolveId = function (dom, bookmark) {
10420      var startPos = restoreEndPoint(dom, 'start', bookmark);
10421      var endPos = restoreEndPoint(dom, 'end', bookmark);
10422      return lift2(startPos, endPos.or(startPos), function (spos, epos) {
10423        var rng = dom.createRng();
10424        rng.setStart(addBogus(dom, spos.container()), spos.offset());
10425        rng.setEnd(addBogus(dom, epos.container()), epos.offset());
10426        return rng;
10427      });
10428    };
10429    var resolveIndex$1 = function (dom, bookmark) {
10430      return Optional.from(dom.select(bookmark.name)[bookmark.index]).map(function (elm) {
10431        var rng = dom.createRng();
10432        rng.selectNode(elm);
10433        return rng;
10434      });
10435    };
10436    var resolve$2 = function (selection, bookmark) {
10437      var dom = selection.dom;
10438      if (bookmark) {
10439        if (isPathBookmark(bookmark)) {
10440          return resolvePaths(dom, bookmark);
10441        } else if (isStringPathBookmark(bookmark)) {
10442          return Optional.some(resolveCaretPositionBookmark(dom, bookmark));
10443        } else if (isIdBookmark(bookmark)) {
10444          return resolveId(dom, bookmark);
10445        } else if (isIndexBookmark(bookmark)) {
10446          return resolveIndex$1(dom, bookmark);
10447        } else if (isRangeBookmark(bookmark)) {
10448          return Optional.some(bookmark.rng);
10449        }
10450      }
10451      return Optional.none();
10452    };
10453
10454    var getBookmark$1 = function (selection, type, normalized) {
10455      return getBookmark(selection, type, normalized);
10456    };
10457    var moveToBookmark = function (selection, bookmark) {
10458      resolve$2(selection, bookmark).each(function (rng) {
10459        selection.setRng(rng);
10460      });
10461    };
10462    var isBookmarkNode$1 = function (node) {
10463      return isElement$1(node) && node.tagName === 'SPAN' && node.getAttribute('data-mce-type') === 'bookmark';
10464    };
10465
10466    var is$2 = function (expected) {
10467      return function (actual) {
10468        return expected === actual;
10469      };
10470    };
10471    var isNbsp = is$2(nbsp);
10472    var isWhiteSpace$1 = function (chr) {
10473      return chr !== '' && ' \f\n\r\t\x0B'.indexOf(chr) !== -1;
10474    };
10475    var isContent$1 = function (chr) {
10476      return !isWhiteSpace$1(chr) && !isNbsp(chr);
10477    };
10478
10479    var isNode = function (node) {
10480      return !!node.nodeType;
10481    };
10482    var isInlineBlock = function (node) {
10483      return node && /^(IMG)$/.test(node.nodeName);
10484    };
10485    var moveStart = function (dom, selection, rng) {
10486      var offset = rng.startOffset;
10487      var container = rng.startContainer, walker, node, nodes;
10488      if (rng.startContainer === rng.endContainer) {
10489        if (isInlineBlock(rng.startContainer.childNodes[rng.startOffset])) {
10490          return;
10491        }
10492      }
10493      if (container.nodeType === 1) {
10494        nodes = container.childNodes;
10495        if (offset < nodes.length) {
10496          container = nodes[offset];
10497          walker = new DomTreeWalker(container, dom.getParent(container, dom.isBlock));
10498        } else {
10499          container = nodes[nodes.length - 1];
10500          walker = new DomTreeWalker(container, dom.getParent(container, dom.isBlock));
10501          walker.next(true);
10502        }
10503        for (node = walker.current(); node; node = walker.next()) {
10504          if (node.nodeType === 3 && !isWhiteSpaceNode(node)) {
10505            rng.setStart(node, 0);
10506            selection.setRng(rng);
10507            return;
10508          }
10509        }
10510      }
10511    };
10512    var getNonWhiteSpaceSibling = function (node, next, inc) {
10513      if (node) {
10514        var nextName = next ? 'nextSibling' : 'previousSibling';
10515        for (node = inc ? node : node[nextName]; node; node = node[nextName]) {
10516          if (node.nodeType === 1 || !isWhiteSpaceNode(node)) {
10517            return node;
10518          }
10519        }
10520      }
10521    };
10522    var isTextBlock$1 = function (editor, name) {
10523      if (isNode(name)) {
10524        name = name.nodeName;
10525      }
10526      return !!editor.schema.getTextBlockElements()[name.toLowerCase()];
10527    };
10528    var isValid = function (ed, parent, child) {
10529      return ed.schema.isValidChild(parent, child);
10530    };
10531    var isWhiteSpaceNode = function (node) {
10532      return node && isText$1(node) && /^([\t \r\n]+|)$/.test(node.nodeValue);
10533    };
10534    var isEmptyTextNode = function (node) {
10535      return node && isText$1(node) && node.length === 0;
10536    };
10537    var replaceVars = function (value, vars) {
10538      if (typeof value !== 'string') {
10539        value = value(vars);
10540      } else if (vars) {
10541        value = value.replace(/%(\w+)/g, function (str, name) {
10542          return vars[name] || str;
10543        });
10544      }
10545      return value;
10546    };
10547    var isEq = function (str1, str2) {
10548      str1 = str1 || '';
10549      str2 = str2 || '';
10550      str1 = '' + (str1.nodeName || str1);
10551      str2 = '' + (str2.nodeName || str2);
10552      return str1.toLowerCase() === str2.toLowerCase();
10553    };
10554    var normalizeStyleValue = function (dom, value, name) {
10555      if (name === 'color' || name === 'backgroundColor') {
10556        value = dom.toHex(value);
10557      }
10558      if (name === 'fontWeight' && value === 700) {
10559        value = 'bold';
10560      }
10561      if (name === 'fontFamily') {
10562        value = value.replace(/[\'\"]/g, '').replace(/,\s+/g, ',');
10563      }
10564      return '' + value;
10565    };
10566    var getStyle = function (dom, node, name) {
10567      return normalizeStyleValue(dom, dom.getStyle(node, name), name);
10568    };
10569    var getTextDecoration = function (dom, node) {
10570      var decoration;
10571      dom.getParent(node, function (n) {
10572        decoration = dom.getStyle(n, 'text-decoration');
10573        return decoration && decoration !== 'none';
10574      });
10575      return decoration;
10576    };
10577    var getParents$1 = function (dom, node, selector) {
10578      return dom.getParents(node, selector, dom.getRoot());
10579    };
10580    var isVariableFormatName = function (editor, formatName) {
10581      var hasVariableValues = function (format) {
10582        var isVariableValue = function (val) {
10583          return val.length > 1 && val.charAt(0) === '%';
10584        };
10585        return exists([
10586          'styles',
10587          'attributes'
10588        ], function (key) {
10589          return get(format, key).exists(function (field) {
10590            var fieldValues = isArray(field) ? field : values(field);
10591            return exists(fieldValues, isVariableValue);
10592          });
10593        });
10594      };
10595      return exists(editor.formatter.get(formatName), hasVariableValues);
10596    };
10597    var areSimilarFormats = function (editor, formatName, otherFormatName) {
10598      var validKeys = [
10599        'inline',
10600        'block',
10601        'selector',
10602        'attributes',
10603        'styles',
10604        'classes'
10605      ];
10606      var filterObj = function (format) {
10607        return filter$1(format, function (_, key) {
10608          return exists(validKeys, function (validKey) {
10609            return validKey === key;
10610          });
10611        });
10612      };
10613      return exists(editor.formatter.get(formatName), function (fmt1) {
10614        var filteredFmt1 = filterObj(fmt1);
10615        return exists(editor.formatter.get(otherFormatName), function (fmt2) {
10616          var filteredFmt2 = filterObj(fmt2);
10617          return equal(filteredFmt1, filteredFmt2);
10618        });
10619      });
10620    };
10621
10622    var isBookmarkNode$2 = isBookmarkNode$1;
10623    var getParents$2 = getParents$1;
10624    var isWhiteSpaceNode$1 = isWhiteSpaceNode;
10625    var isTextBlock$2 = isTextBlock$1;
10626    var isBogusBr = function (node) {
10627      return node.nodeName === 'BR' && node.getAttribute('data-mce-bogus') && !node.nextSibling;
10628    };
10629    var findParentContentEditable = function (dom, node) {
10630      var parent = node;
10631      while (parent) {
10632        if (isElement$1(parent) && dom.getContentEditable(parent)) {
10633          return dom.getContentEditable(parent) === 'false' ? parent : node;
10634        }
10635        parent = parent.parentNode;
10636      }
10637      return node;
10638    };
10639    var walkText = function (start, node, offset, predicate) {
10640      var str = node.data;
10641      for (var i = offset; start ? i >= 0 : i < str.length; start ? i-- : i++) {
10642        if (predicate(str.charAt(i))) {
10643          return start ? i + 1 : i;
10644        }
10645      }
10646      return -1;
10647    };
10648    var findSpace = function (start, node, offset) {
10649      return walkText(start, node, offset, function (c) {
10650        return isNbsp(c) || isWhiteSpace$1(c);
10651      });
10652    };
10653    var findContent = function (start, node, offset) {
10654      return walkText(start, node, offset, isContent$1);
10655    };
10656    var findWordEndPoint = function (dom, body, container, offset, start, includeTrailingSpaces) {
10657      var lastTextNode;
10658      var rootNode = dom.getParent(container, dom.isBlock) || body;
10659      var walk = function (container, offset, pred) {
10660        var textSeeker = TextSeeker(dom);
10661        var walker = start ? textSeeker.backwards : textSeeker.forwards;
10662        return Optional.from(walker(container, offset, function (text, textOffset) {
10663          if (isBookmarkNode$2(text.parentNode)) {
10664            return -1;
10665          } else {
10666            lastTextNode = text;
10667            return pred(start, text, textOffset);
10668          }
10669        }, rootNode));
10670      };
10671      var spaceResult = walk(container, offset, findSpace);
10672      return spaceResult.bind(function (result) {
10673        return includeTrailingSpaces ? walk(result.container, result.offset + (start ? -1 : 0), findContent) : Optional.some(result);
10674      }).orThunk(function () {
10675        return lastTextNode ? Optional.some({
10676          container: lastTextNode,
10677          offset: start ? 0 : lastTextNode.length
10678        }) : Optional.none();
10679      });
10680    };
10681    var findSelectorEndPoint = function (dom, format, rng, container, siblingName) {
10682      if (isText$1(container) && container.nodeValue.length === 0 && container[siblingName]) {
10683        container = container[siblingName];
10684      }
10685      var parents = getParents$2(dom, container);
10686      for (var i = 0; i < parents.length; i++) {
10687        for (var y = 0; y < format.length; y++) {
10688          var curFormat = format[y];
10689          if ('collapsed' in curFormat && curFormat.collapsed !== rng.collapsed) {
10690            continue;
10691          }
10692          if (dom.is(parents[i], curFormat.selector)) {
10693            return parents[i];
10694          }
10695        }
10696      }
10697      return container;
10698    };
10699    var findBlockEndPoint = function (editor, format, container, siblingName) {
10700      var node;
10701      var dom = editor.dom;
10702      var root = dom.getRoot();
10703      if (!format[0].wrapper) {
10704        node = dom.getParent(container, format[0].block, root);
10705      }
10706      if (!node) {
10707        var scopeRoot = dom.getParent(container, 'LI,TD,TH');
10708        node = dom.getParent(isText$1(container) ? container.parentNode : container, function (node) {
10709          return node !== root && isTextBlock$2(editor, node);
10710        }, scopeRoot);
10711      }
10712      if (node && format[0].wrapper) {
10713        node = getParents$2(dom, node, 'ul,ol').reverse()[0] || node;
10714      }
10715      if (!node) {
10716        node = container;
10717        while (node[siblingName] && !dom.isBlock(node[siblingName])) {
10718          node = node[siblingName];
10719          if (isEq(node, 'br')) {
10720            break;
10721          }
10722        }
10723      }
10724      return node || container;
10725    };
10726    var findParentContainer = function (dom, format, startContainer, startOffset, endContainer, endOffset, start) {
10727      var container, parent, sibling;
10728      container = parent = start ? startContainer : endContainer;
10729      var siblingName = start ? 'previousSibling' : 'nextSibling';
10730      var root = dom.getRoot();
10731      if (isText$1(container) && !isWhiteSpaceNode$1(container)) {
10732        if (start ? startOffset > 0 : endOffset < container.nodeValue.length) {
10733          return container;
10734        }
10735      }
10736      while (true) {
10737        if (!format[0].block_expand && dom.isBlock(parent)) {
10738          return parent;
10739        }
10740        for (sibling = parent[siblingName]; sibling; sibling = sibling[siblingName]) {
10741          if (!isBookmarkNode$2(sibling) && !isWhiteSpaceNode$1(sibling) && !isBogusBr(sibling)) {
10742            return parent;
10743          }
10744        }
10745        if (parent === root || parent.parentNode === root) {
10746          container = parent;
10747          break;
10748        }
10749        parent = parent.parentNode;
10750      }
10751      return container;
10752    };
10753    var expandRng = function (editor, rng, format, includeTrailingSpace) {
10754      if (includeTrailingSpace === void 0) {
10755        includeTrailingSpace = false;
10756      }
10757      var startContainer = rng.startContainer, startOffset = rng.startOffset, endContainer = rng.endContainer, endOffset = rng.endOffset;
10758      var dom = editor.dom;
10759      if (isElement$1(startContainer) && startContainer.hasChildNodes()) {
10760        startContainer = getNode(startContainer, startOffset);
10761        if (isText$1(startContainer)) {
10762          startOffset = 0;
10763        }
10764      }
10765      if (isElement$1(endContainer) && endContainer.hasChildNodes()) {
10766        endContainer = getNode(endContainer, rng.collapsed ? endOffset : endOffset - 1);
10767        if (isText$1(endContainer)) {
10768          endOffset = endContainer.nodeValue.length;
10769        }
10770      }
10771      startContainer = findParentContentEditable(dom, startContainer);
10772      endContainer = findParentContentEditable(dom, endContainer);
10773      if (isBookmarkNode$2(startContainer.parentNode) || isBookmarkNode$2(startContainer)) {
10774        startContainer = isBookmarkNode$2(startContainer) ? startContainer : startContainer.parentNode;
10775        if (rng.collapsed) {
10776          startContainer = startContainer.previousSibling || startContainer;
10777        } else {
10778          startContainer = startContainer.nextSibling || startContainer;
10779        }
10780        if (isText$1(startContainer)) {
10781          startOffset = rng.collapsed ? startContainer.length : 0;
10782        }
10783      }
10784      if (isBookmarkNode$2(endContainer.parentNode) || isBookmarkNode$2(endContainer)) {
10785        endContainer = isBookmarkNode$2(endContainer) ? endContainer : endContainer.parentNode;
10786        if (rng.collapsed) {
10787          endContainer = endContainer.nextSibling || endContainer;
10788        } else {
10789          endContainer = endContainer.previousSibling || endContainer;
10790        }
10791        if (isText$1(endContainer)) {
10792          endOffset = rng.collapsed ? 0 : endContainer.length;
10793        }
10794      }
10795      if (rng.collapsed) {
10796        var startPoint = findWordEndPoint(dom, editor.getBody(), startContainer, startOffset, true, includeTrailingSpace);
10797        startPoint.each(function (_a) {
10798          var container = _a.container, offset = _a.offset;
10799          startContainer = container;
10800          startOffset = offset;
10801        });
10802        var endPoint = findWordEndPoint(dom, editor.getBody(), endContainer, endOffset, false, includeTrailingSpace);
10803        endPoint.each(function (_a) {
10804          var container = _a.container, offset = _a.offset;
10805          endContainer = container;
10806          endOffset = offset;
10807        });
10808      }
10809      if (format[0].inline || format[0].block_expand) {
10810        if (!format[0].inline || (!isText$1(startContainer) || startOffset === 0)) {
10811          startContainer = findParentContainer(dom, format, startContainer, startOffset, endContainer, endOffset, true);
10812        }
10813        if (!format[0].inline || (!isText$1(endContainer) || endOffset === endContainer.nodeValue.length)) {
10814          endContainer = findParentContainer(dom, format, startContainer, startOffset, endContainer, endOffset, false);
10815        }
10816      }
10817      if (format[0].selector && format[0].expand !== false && !format[0].inline) {
10818        startContainer = findSelectorEndPoint(dom, format, rng, startContainer, 'previousSibling');
10819        endContainer = findSelectorEndPoint(dom, format, rng, endContainer, 'nextSibling');
10820      }
10821      if (format[0].block || format[0].selector) {
10822        startContainer = findBlockEndPoint(editor, format, startContainer, 'previousSibling');
10823        endContainer = findBlockEndPoint(editor, format, endContainer, 'nextSibling');
10824        if (format[0].block) {
10825          if (!dom.isBlock(startContainer)) {
10826            startContainer = findParentContainer(dom, format, startContainer, startOffset, endContainer, endOffset, true);
10827          }
10828          if (!dom.isBlock(endContainer)) {
10829            endContainer = findParentContainer(dom, format, startContainer, startOffset, endContainer, endOffset, false);
10830          }
10831        }
10832      }
10833      if (isElement$1(startContainer)) {
10834        startOffset = dom.nodeIndex(startContainer);
10835        startContainer = startContainer.parentNode;
10836      }
10837      if (isElement$1(endContainer)) {
10838        endOffset = dom.nodeIndex(endContainer) + 1;
10839        endContainer = endContainer.parentNode;
10840      }
10841      return {
10842        startContainer: startContainer,
10843        startOffset: startOffset,
10844        endContainer: endContainer,
10845        endOffset: endOffset
10846      };
10847    };
10848
10849    var clampToExistingChildren = function (container, index) {
10850      var childNodes = container.childNodes;
10851      if (index >= childNodes.length) {
10852        index = childNodes.length - 1;
10853      } else if (index < 0) {
10854        index = 0;
10855      }
10856      return childNodes[index] || container;
10857    };
10858    var getEndChild = function (container, index) {
10859      return clampToExistingChildren(container, index - 1);
10860    };
10861    var walk$1 = function (dom, rng, callback) {
10862      var startContainer = rng.startContainer;
10863      var startOffset = rng.startOffset;
10864      var endContainer = rng.endContainer;
10865      var endOffset = rng.endOffset;
10866      var exclude = function (nodes) {
10867        var node;
10868        node = nodes[0];
10869        if (node.nodeType === 3 && node === startContainer && startOffset >= node.nodeValue.length) {
10870          nodes.splice(0, 1);
10871        }
10872        node = nodes[nodes.length - 1];
10873        if (endOffset === 0 && nodes.length > 0 && node === endContainer && node.nodeType === 3) {
10874          nodes.splice(nodes.length - 1, 1);
10875        }
10876        return nodes;
10877      };
10878      var collectSiblings = function (node, name, endNode) {
10879        var siblings = [];
10880        for (; node && node !== endNode; node = node[name]) {
10881          siblings.push(node);
10882        }
10883        return siblings;
10884      };
10885      var findEndPoint = function (node, root) {
10886        do {
10887          if (node.parentNode === root) {
10888            return node;
10889          }
10890          node = node.parentNode;
10891        } while (node);
10892      };
10893      var walkBoundary = function (startNode, endNode, next) {
10894        var siblingName = next ? 'nextSibling' : 'previousSibling';
10895        for (var node = startNode, parent_1 = node.parentNode; node && node !== endNode; node = parent_1) {
10896          parent_1 = node.parentNode;
10897          var siblings_1 = collectSiblings(node === startNode ? node : node[siblingName], siblingName);
10898          if (siblings_1.length) {
10899            if (!next) {
10900              siblings_1.reverse();
10901            }
10902            callback(exclude(siblings_1));
10903          }
10904        }
10905      };
10906      if (startContainer.nodeType === 1 && startContainer.hasChildNodes()) {
10907        startContainer = clampToExistingChildren(startContainer, startOffset);
10908      }
10909      if (endContainer.nodeType === 1 && endContainer.hasChildNodes()) {
10910        endContainer = getEndChild(endContainer, endOffset);
10911      }
10912      if (startContainer === endContainer) {
10913        return callback(exclude([startContainer]));
10914      }
10915      var ancestor = dom.findCommonAncestor(startContainer, endContainer);
10916      for (var node = startContainer; node; node = node.parentNode) {
10917        if (node === endContainer) {
10918          return walkBoundary(startContainer, ancestor, true);
10919        }
10920        if (node === ancestor) {
10921          break;
10922        }
10923      }
10924      for (var node = endContainer; node; node = node.parentNode) {
10925        if (node === startContainer) {
10926          return walkBoundary(endContainer, ancestor);
10927        }
10928        if (node === ancestor) {
10929          break;
10930        }
10931      }
10932      var startPoint = findEndPoint(startContainer, ancestor) || startContainer;
10933      var endPoint = findEndPoint(endContainer, ancestor) || endContainer;
10934      walkBoundary(startContainer, startPoint, true);
10935      var siblings = collectSiblings(startPoint === startContainer ? startPoint : startPoint.nextSibling, 'nextSibling', endPoint === endContainer ? endPoint.nextSibling : endPoint);
10936      if (siblings.length) {
10937        callback(exclude(siblings));
10938      }
10939      walkBoundary(endContainer, endPoint);
10940    };
10941
10942    var getRanges = function (selection) {
10943      var ranges = [];
10944      if (selection) {
10945        for (var i = 0; i < selection.rangeCount; i++) {
10946          ranges.push(selection.getRangeAt(i));
10947        }
10948      }
10949      return ranges;
10950    };
10951    var getSelectedNodes = function (ranges) {
10952      return bind(ranges, function (range) {
10953        var node = getSelectedNode(range);
10954        return node ? [SugarElement.fromDom(node)] : [];
10955      });
10956    };
10957    var hasMultipleRanges = function (selection) {
10958      return getRanges(selection).length > 1;
10959    };
10960
10961    var getCellsFromRanges = function (ranges) {
10962      return filter(getSelectedNodes(ranges), isTableCell$1);
10963    };
10964    var getCellsFromElement = function (elm) {
10965      return descendants$1(elm, 'td[data-mce-selected],th[data-mce-selected]');
10966    };
10967    var getCellsFromElementOrRanges = function (ranges, element) {
10968      var selectedCells = getCellsFromElement(element);
10969      return selectedCells.length > 0 ? selectedCells : getCellsFromRanges(ranges);
10970    };
10971    var getCellsFromEditor = function (editor) {
10972      return getCellsFromElementOrRanges(getRanges(editor.selection.getSel()), SugarElement.fromDom(editor.getBody()));
10973    };
10974
10975    var getStartNode = function (rng) {
10976      var sc = rng.startContainer, so = rng.startOffset;
10977      if (isText$1(sc)) {
10978        return so === 0 ? Optional.some(SugarElement.fromDom(sc)) : Optional.none();
10979      } else {
10980        return Optional.from(sc.childNodes[so]).map(SugarElement.fromDom);
10981      }
10982    };
10983    var getEndNode = function (rng) {
10984      var ec = rng.endContainer, eo = rng.endOffset;
10985      if (isText$1(ec)) {
10986        return eo === ec.data.length ? Optional.some(SugarElement.fromDom(ec)) : Optional.none();
10987      } else {
10988        return Optional.from(ec.childNodes[eo - 1]).map(SugarElement.fromDom);
10989      }
10990    };
10991    var getFirstChildren = function (node) {
10992      return firstChild(node).fold(constant([node]), function (child) {
10993        return [node].concat(getFirstChildren(child));
10994      });
10995    };
10996    var getLastChildren = function (node) {
10997      return lastChild(node).fold(constant([node]), function (child) {
10998        if (name(child) === 'br') {
10999          return prevSibling(child).map(function (sibling) {
11000            return [node].concat(getLastChildren(sibling));
11001          }).getOr([]);
11002        } else {
11003          return [node].concat(getLastChildren(child));
11004        }
11005      });
11006    };
11007    var hasAllContentsSelected = function (elm, rng) {
11008      return lift2(getStartNode(rng), getEndNode(rng), function (startNode, endNode) {
11009        var start = find(getFirstChildren(elm), curry(eq$2, startNode));
11010        var end = find(getLastChildren(elm), curry(eq$2, endNode));
11011        return start.isSome() && end.isSome();
11012      }).getOr(false);
11013    };
11014    var moveEndPoint$1 = function (dom, rng, node, start) {
11015      var root = node, walker = new DomTreeWalker(node, root);
11016      var moveCaretBeforeOnEnterElementsMap = filter$1(dom.schema.getMoveCaretBeforeOnEnterElements(), function (_, name) {
11017        return !contains([
11018          'td',
11019          'th',
11020          'table'
11021        ], name.toLowerCase());
11022      });
11023      do {
11024        if (isText$1(node) && Tools.trim(node.nodeValue).length !== 0) {
11025          if (start) {
11026            rng.setStart(node, 0);
11027          } else {
11028            rng.setEnd(node, node.nodeValue.length);
11029          }
11030          return;
11031        }
11032        if (moveCaretBeforeOnEnterElementsMap[node.nodeName]) {
11033          if (start) {
11034            rng.setStartBefore(node);
11035          } else {
11036            if (node.nodeName === 'BR') {
11037              rng.setEndBefore(node);
11038            } else {
11039              rng.setEndAfter(node);
11040            }
11041          }
11042          return;
11043        }
11044      } while (node = start ? walker.next() : walker.prev());
11045      if (root.nodeName === 'BODY') {
11046        if (start) {
11047          rng.setStart(root, 0);
11048        } else {
11049          rng.setEnd(root, root.childNodes.length);
11050        }
11051      }
11052    };
11053    var hasAnyRanges = function (editor) {
11054      var sel = editor.selection.getSel();
11055      return sel && sel.rangeCount > 0;
11056    };
11057    var runOnRanges = function (editor, executor) {
11058      var fakeSelectionNodes = getCellsFromEditor(editor);
11059      if (fakeSelectionNodes.length > 0) {
11060        each(fakeSelectionNodes, function (elem) {
11061          var node = elem.dom;
11062          var fakeNodeRng = editor.dom.createRng();
11063          fakeNodeRng.setStartBefore(node);
11064          fakeNodeRng.setEndAfter(node);
11065          executor(fakeNodeRng, true);
11066        });
11067      } else {
11068        executor(editor.selection.getRng(), false);
11069      }
11070    };
11071    var preserve = function (selection, fillBookmark, executor) {
11072      var bookmark = getPersistentBookmark(selection, fillBookmark);
11073      executor(bookmark);
11074      selection.moveToBookmark(bookmark);
11075    };
11076
11077    function NodeValue (is, name) {
11078      var get = function (element) {
11079        if (!is(element)) {
11080          throw new Error('Can only get ' + name + ' value of a ' + name + ' node');
11081        }
11082        return getOption(element).getOr('');
11083      };
11084      var getOption = function (element) {
11085        return is(element) ? Optional.from(element.dom.nodeValue) : Optional.none();
11086      };
11087      var set = function (element, value) {
11088        if (!is(element)) {
11089          throw new Error('Can only set raw ' + name + ' value of a ' + n
11089ame + ' node');
11090        }
11091        element.dom.nodeValue = value;
11092      };
11093      return {
11094        get: get,
11095        getOption: getOption,
11096        set: set
11097      };
11098    }
11099
11100    var api = NodeValue(isText, 'text');
11101    var get$7 = function (element) {
11102      return api.get(element);
11103    };
11104
11105    var isZeroWidth = function (elem) {
11106      return isText(elem) && get$7(elem) === ZWSP;
11107    };
11108    var context = function (editor, elem, wrapName, nodeName) {
11109      return parent(elem).fold(function () {
11110        return 'skipping';
11111      }, function (parent) {
11112        if (nodeName === 'br' || isZeroWidth(elem)) {
11113          return 'valid';
11114        } else if (isAnnotation(elem)) {
11115          return 'existing';
11116        } else if (isCaretNode(elem.dom)) {
11117          return 'caret';
11118        } else if (!isValid(editor, wrapName, nodeName) || !isValid(editor, name(parent), wrapName)) {
11119          return 'invalid-child';
11120        } else {
11121          return 'valid';
11122        }
11123      });
11124    };
11125
11126    var applyWordGrab = function (editor, rng) {
11127      var r = expandRng(editor, rng, [{ inline: true }]);
11128      rng.setStart(r.startContainer, r.startOffset);
11129      rng.setEnd(r.endContainer, r.endOffset);
11130      editor.selection.setRng(rng);
11131    };
11132    var makeAnnotation = function (eDoc, _a, annotationName, decorate) {
11133      var _b = _a.uid, uid = _b === void 0 ? generate$1('mce-annotation') : _b, data = __rest(_a, ['uid']);
11134      var master = SugarElement.fromTag('span', eDoc);
11135      add$3(master, annotation());
11136      set(master, '' + dataAnnotationId(), uid);
11137      set(master, '' + dataAnnotation(), annotationName);
11138      var _c = decorate(uid, data), _d = _c.attributes, attributes = _d === void 0 ? {} : _d, _e = _c.classes, classes = _e === void 0 ? [] : _e;
11139      setAll(master, attributes);
11140      add$4(master, classes);
11141      return master;
11142    };
11143    var annotate = function (editor, rng, annotationName, decorate, data) {
11144      var newWrappers = [];
11145      var master = makeAnnotation(editor.getDoc(), data, annotationName, decorate);
11146      var wrapper = Cell(Optional.none());
11147      var finishWrapper = function () {
11148        wrapper.set(Optional.none());
11149      };
11150      var getOrOpenWrapper = function () {
11151        return wrapper.get().getOrThunk(function () {
11152          var nu = shallow(master);
11153          newWrappers.push(nu);
11154          wrapper.set(Optional.some(nu));
11155          return nu;
11156        });
11157      };
11158      var processElements = function (elems) {
11159        each(elems, processElement);
11160      };
11161      var processElement = function (elem) {
11162        var ctx = context(editor, elem, 'span', name(elem));
11163        switch (ctx) {
11164        case 'invalid-child': {
11165            finishWrapper();
11166            var children$1 = children(elem);
11167            processElements(children$1);
11168            finishWrapper();
11169            break;
11170          }
11171        case 'valid': {
11172            var w = getOrOpenWrapper();
11173            wrap(elem, w);
11174            break;
11175          }
11176        }
11177      };
11178      var processNodes = function (nodes) {
11179        var elems = map(nodes, SugarElement.fromDom);
11180        processElements(elems);
11181      };
11182      walk$1(editor.dom, rng, function (nodes) {
11183        finishWrapper();
11184        processNodes(nodes);
11185      });
11186      return newWrappers;
11187    };
11188    var annotateWithBookmark = function (editor, name, settings, data) {
11189      editor.undoManager.transact(function () {
11190        var selection = editor.selection;
11191        var initialRng = selection.getRng();
11192        var hasFakeSelection = getCellsFromEditor(editor).length > 0;
11193        if (initialRng.collapsed && !hasFakeSelection) {
11194          applyWordGrab(editor, initialRng);
11195        }
11196        if (selection.getRng().collapsed && !hasFakeSelection) {
11197          var wrapper = makeAnnotation(editor.getDoc(), data, name, settings.decorate);
11198          set$1(wrapper, nbsp);
11199          selection.getRng().insertNode(wrapper.dom);
11200          selection.select(wrapper.dom);
11201        } else {
11202          preserve(selection, false, function () {
11203            runOnRanges(editor, function (selectionRng) {
11204              annotate(editor, selectionRng, name, settings.decorate, data);
11205            });
11206          });
11207        }
11208      });
11209    };
11210
11211    var Annotator = function (editor) {
11212      var registry = create$2();
11213      setup$1(editor, registry);
11214      var changes = setup(editor);
11215      return {
11216        register: function (name, settings) {
11217          registry.register(name, settings);
11218        },
11219        annotate: function (name, data) {
11220          registry.lookup(name).each(function (settings) {
11221            annotateWithBookmark(editor, name, settings, data);
11222          });
11223        },
11224        annotationChanged: function (name, callback) {
11225          changes.addListener(name, callback);
11226        },
11227        remove: function (name) {
11228          identify(editor, Optional.some(name)).each(function (_a) {
11229            var elements = _a.elements;
11230            each(elements, unwrap);
11231          });
11232        },
11233        getAll: function (name) {
11234          var directory = findAll(editor, name);
11235          return map$1(directory, function (elems) {
11236            return map(elems, function (elem) {
11237              return elem.dom;
11238            });
11239          });
11240        }
11241      };
11242    };
11243
11244    function BookmarkManager(selection) {
11245      return {
11246        getBookmark: curry(getBookmark$1, selection),
11247        moveToBookmark: curry(moveToBookmark, selection)
11248      };
11249    }
11250    (function (BookmarkManager) {
11251      BookmarkManager.isBookmarkNode = isBookmarkNode$1;
11252    }(BookmarkManager || (BookmarkManager = {})));
11253    var BookmarkManager$1 = BookmarkManager;
11254
11255    var getContentEditableRoot = function (root, node) {
11256      while (node && node !== root) {
11257        if (isContentEditableTrue(node) || isContentEditableFalse(node)) {
11258          return node;
11259        }
11260        node = node.parentNode;
11261      }
11262      return null;
11263    };
11264
11265    var isXYWithinRange = function (clientX, clientY, range) {
11266      if (range.collapsed) {
11267        return false;
11268      }
11269      if (Env.browser.isIE() && range.startOffset === range.endOffset - 1 && range.startContainer === range.endContainer) {
11270        var elm = range.startContainer.childNodes[range.startOffset];
11271        if (isElement$1(elm)) {
11272          return exists(elm.getClientRects(), function (rect) {
11273            return containsXY(rect, clientX, clientY);
11274          });
11275        }
11276      }
11277      return exists(range.getClientRects(), function (rect) {
11278        return containsXY(rect, clientX, clientY);
11279      });
11280    };
11281
11282    var firePreProcess = function (editor, args) {
11283      return editor.fire('PreProcess', args);
11284    };
11285    var firePostProcess = function (editor, args) {
11286      return editor.fire('PostProcess', args);
11287    };
11288    var fireRemove = function (editor) {
11289      return editor.fire('remove');
11290    };
11291    var fireDetach = function (editor) {
11292      return editor.fire('detach');
11293    };
11294    var fireSwitchMode = function (editor, mode) {
11295      return editor.fire('SwitchMode', { mode: mode });
11296    };
11297    var fireObjectResizeStart = function (editor, target, width, height, origin) {
11298      editor.fire('ObjectResizeStart', {
11299        target: target,
11300        width: width,
11301        height: height,
11302        origin: origin
11303      });
11304    };
11305    var fireObjectResized = function (editor, target, width, height, origin) {
11306      editor.fire('ObjectResized', {
11307        target: target,
11308        width: width,
11309        height: height,
11310        origin: origin
11311      });
11312    };
11313    var firePreInit = function (editor) {
11314      return editor.fire('PreInit');
11315    };
11316    var firePostRender = function (editor) {
11317      return editor.fire('PostRender');
11318    };
11319    var fireInit = function (editor) {
11320      return editor.fire('Init');
11321    };
11322    var firePlaceholderToggle = function (editor, state) {
11323      return editor.fire('PlaceholderToggle', { state: state });
11324    };
11325    var fireError = function (editor, errorType, error) {
11326      return editor.fire(errorType, error);
11327    };
11328
11329    var VK = {
11330      BACKSPACE: 8,
11331      DELETE: 46,
11332      DOWN: 40,
11333      ENTER: 13,
11334      LEFT: 37,
11335      RIGHT: 39,
11336      SPACEBAR: 32,
11337      TAB: 9,
11338      UP: 38,
11339      END: 35,
11340      HOME: 36,
11341      modifierPressed: function (e) {
11342        return e.shiftKey || e.ctrlKey || e.altKey || this.metaKeyPressed(e);
11343      },
11344      metaKeyPressed: function (e) {
11345        return Env.mac ? e.metaKey : e.ctrlKey && !e.altKey;
11346      }
11347    };
11348
11349    var isContentEditableFalse$6 = isContentEditableFalse;
11350    var ControlSelection = function (selection, editor) {
11351      var dom = editor.dom, each = Tools.each;
11352      var selectedElm, selectedElmGhost, resizeHelper, selectedHandle;
11353      var startX, startY, selectedElmX, selectedElmY, startW, startH, ratio, resizeStarted;
11354      var width, height;
11355      var editableDoc = editor.getDoc(), rootDocument = document;
11356      var abs = Math.abs, round = Math.round, rootElement = editor.getBody();
11357      var startScrollWidth, startScrollHeight;
11358      var resizeHandles = {
11359        nw: [
11360          0,
11361          0,
11362          -1,
11363          -1
11364        ],
11365        ne: [
11366          1,
11367          0,
11368          1,
11369          -1
11370        ],
11371        se: [
11372          1,
11373          1,
11374          1,
11375          1
11376        ],
11377        sw: [
11378          0,
11379          1,
11380          -1,
11381          1
11382        ]
11383      };
11384      var isImage = function (elm) {
11385        return elm && (elm.nodeName === 'IMG' || editor.dom.is(elm, 'figure.image'));
11386      };
11387      var isEventOnImageOutsideRange = function (evt, range) {
11388        if (evt.type === 'longpress' || evt.type.indexOf('touch') === 0) {
11389          var touch = evt.touches[0];
11390          return isImage(evt.target) && !isXYWithinRange(touch.clientX, touch.clientY, range);
11391        } else {
11392          return isImage(evt.target) && !isXYWithinRange(evt.clientX, evt.clientY, range);
11393        }
11394      };
11395      var contextMenuSelectImage = function (evt) {
11396        var target = evt.target;
11397        if (isEventOnImageOutsideRange(evt, editor.selection.getRng()) && !evt.isDefaultPrevented()) {
11398          editor.selection.select(target);
11399        }
11400      };
11401      var getResizeTarget = function (elm) {
11402        return editor.dom.is(elm, 'figure.image') ? elm.querySelector('img') : elm;
11403      };
11404      var isResizable = function (elm) {
11405        var selector = getObjectResizing(editor);
11406        if (!selector) {
11407          return false;
11408        }
11409        if (elm.getAttribute('data-mce-resize') === 'false') {
11410          return false;
11411        }
11412        if (elm === editor.getBody()) {
11413          return false;
11414        }
11415        return is$1(SugarElement.fromDom(elm), selector);
11416      };
11417      var setGhostElmSize = function (ghostElm, width, height) {
11418        dom.setStyles(getResizeTarget(ghostElm), {
11419          width: width,
11420          height: height
11421        });
11422      };
11423      var resizeGhostElement = function (e) {
11424        var deltaX, deltaY, proportional;
11425        var resizeHelperX, resizeHelperY;
11426        deltaX = e.screenX - startX;
11427        deltaY = e.screenY - startY;
11428        width = deltaX * selectedHandle[2] + startW;
11429        height = deltaY * selectedHandle[3] + startH;
11430        width = width < 5 ? 5 : width;
11431        height = height < 5 ? 5 : height;
11432        if (isImage(selectedElm) && getResizeImgProportional(editor) !== false) {
11433          proportional = !VK.modifierPressed(e);
11434        } else {
11435          proportional = VK.modifierPressed(e);
11436        }
11437        if (proportional) {
11438          if (abs(deltaX) > abs(deltaY)) {
11439            height = round(width * ratio);
11440            width = round(height / ratio);
11441          } else {
11442            width = round(height / ratio);
11443            height = round(width * ratio);
11444          }
11445        }
11446        setGhostElmSize(selectedElmGhost, width, height);
11447        resizeHelperX = selectedHandle.startPos.x + deltaX;
11448        resizeHelperY = selectedHandle.startPos.y + deltaY;
11449        resizeHelperX = resizeHelperX > 0 ? resizeHelperX : 0;
11450        resizeHelperY = resizeHelperY > 0 ? resizeHelperY : 0;
11451        dom.setStyles(resizeHelper, {
11452          left: resizeHelperX,
11453          top: resizeHelperY,
11454          display: 'block'
11455        });
11456        resizeHelper.innerHTML = width + ' &times; ' + height;
11457        if (selectedHandle[2] < 0 && selectedElmGhost.clientWidth <= width) {
11458          dom.setStyle(selectedElmGhost, 'left', selectedElmX + (startW - width));
11459        }
11460        if (selectedHandle[3] < 0 && selectedElmGhost.clientHeight <= height) {
11461          dom.setStyle(selectedElmGhost, 'top', selectedElmY + (startH - height));
11462        }
11463        deltaX = rootElement.scrollWidth - startScrollWidth;
11464        deltaY = rootElement.scrollHeight - startScrollHeight;
11465        if (deltaX + deltaY !== 0) {
11466          dom.setStyles(resizeHelper, {
11467            left: resizeHelperX - deltaX,
11468            top: resizeHelperY - deltaY
11469          });
11470        }
11471        if (!resizeStarted) {
11472          fireObjectResizeStart(editor, selectedElm, startW, startH, 'corner-' + selectedHandle.name);
11473          resizeStarted = true;
11474        }
11475      };
11476      var endGhostResize = function () {
11477        var wasResizeStarted = resizeStarted;
11478        resizeStarted = false;
11479        var setSizeProp = function (name, value) {
11480          if (value) {
11481            if (selectedElm.style[name] || !editor.schema.isValid(selectedElm.nodeName.toLowerCase(), name)) {
11482              dom.setStyle(getResizeTarget(selectedElm), name, value);
11483            } else {
11484              dom.setAttrib(getResizeTarget(selectedElm), name, '' + value);
11485            }
11486          }
11487        };
11488        if (wasResizeStarted) {
11489          setSizeProp('width', width);
11490          setSizeProp('height', height);
11491        }
11492        dom.unbind(editableDoc, 'mousemove', resizeGhostElement);
11493        dom.unbind(editableDoc, 'mouseup', endGhostResize);
11494        if (rootDocument !== editableDoc) {
11495          dom.unbind(rootDocument, 'mousemove', resizeGhostElement);
11496          dom.unbind(rootDocument, 'mouseup', endGhostResize);
11497        }
11498        dom.remove(selectedElmGhost);
11499        dom.remove(resizeHelper);
11500        showResizeRect(selectedElm);
11501        if (wasResizeStarted) {
11502          fireObjectResized(editor, selectedElm, width, height, 'corner-' + selectedHandle.name);
11503          dom.setAttrib(selectedElm, 'style', dom.getAttrib(selectedElm, 'style'));
11504        }
11505        editor.nodeChanged();
11506      };
11507      var showResizeRect = function (targetElm) {
11508        hideResizeRect();
11509        unbindResizeHandleEvents();
11510        var position = dom.getPos(targetElm, rootElement);
11511        var selectedElmX = position.x;
11512        var selectedElmY = position.y;
11513        var rect = targetElm.getBoundingClientRect();
11514        var targetWidth = rect.width || rect.right - rect.left;
11515        var targetHeight = rect.height || rect.bottom - rect.top;
11516        if (selectedElm !== targetElm) {
11517          selectedElm = targetElm;
11518          width = height = 0;
11519        }
11520        var e = editor.fire('ObjectSelected', { target: targetElm });
11521        if (isResizable(targetElm) && !e.isDefaultPrevented()) {
11522          each(resizeHandles, function (handle, name) {
11523            var handleElm;
11524            var startDrag = function (e) {
11525              startX = e.screenX;
11526              startY = e.screenY;
11527              startW = getResizeTarget(selectedElm).clientWidth;
11528              startH = getResizeTarget(selectedElm).clientHeight;
11529              ratio = startH / startW;
11530              selectedHandle = handle;
11531              selectedHandle.name = name;
11532              selectedHandle.startPos = {
11533                x: targetWidth * handle[0] + selectedElmX,
11534                y: targetHeight * handle[1] + selectedElmY
11535              };
11536              startScrollWidth = rootElement.scrollWidth;
11537              startScrollHeight = rootElement.scrollHeight;
11538              selectedElmGhost = selectedElm.cloneNode(true);
11539              dom.addClass(selectedElmGhost, 'mce-clonedresizable');
11540              dom.setAttrib(selectedElmGhost, 'data-mce-bogus', 'all');
11541              selectedElmGhost.contentEditable = false;
11542              selectedElmGhost.unSelectabe = true;
11543              dom.setStyles(selectedElmGhost, {
11544                left: selectedElmX,
11545                top: selectedElmY,
11546                margin: 0
11547              });
11548              setGhostElmSize(selectedElmGhost, targetWidth, targetHeight);
11549              selectedElmGhost.removeAttribute('data-mce-selected');
11550              rootElement.appendChild(selectedElmGhost);
11551              dom.bind(editableDoc, 'mousemove', resizeGhostElement);
11552              dom.bind(editableDoc, 'mouseup', endGhostResize);
11553              if (rootDocument !== editableDoc) {
11554                dom.bind(rootDocument, 'mousemove', resizeGhostElement);
11555                dom.bind(rootDocument, 'mouseup', endGhostResize);
11556              }
11557              resizeHelper = dom.add(rootElement, 'div', {
11558                'class': 'mce-resize-helper',
11559                'data-mce-bogus': 'all'
11560              }, startW + ' &times; ' + startH);
11561            };
11562            handleElm = dom.get('mceResizeHandle' + name);
11563            if (handleElm) {
11564              dom.remove(handleElm);
11565            }
11566            handleElm = dom.add(rootElement, 'div', {
11567              'id': 'mceResizeHandle' + name,
11568              'data-mce-bogus': 'all',
11569              'class': 'mce-resizehandle',
11570              'unselectable': true,
11571              'style': 'cursor:' + name + '-resize; margin:0; padding:0'
11572            });
11573            if (Env.ie === 11) {
11574              handleElm.contentEditable = false;
11575            }
11576            dom.bind(handleElm, 'mousedown', function (e) {
11577              e.stopImmediatePropagation();
11578              e.preventDefault();
11579              startDrag(e);
11580            });
11581            handle.elm = handleElm;
11582            dom.setStyles(handleElm, {
11583              left: targetWidth * handle[0] + selectedElmX - handleElm.offsetWidth / 2,
11584              top: targetHeight * handle[1] + selectedElmY - handleElm.offsetHeight / 2
11585            });
11586          });
11587        } else {
11588          hideResizeRect();
11589        }
11590        selectedElm.setAttribute('data-mce-selected', '1');
11591      };
11592      var hideResizeRect = function () {
11593        unbindResizeHandleEvents();
11594        if (selectedElm) {
11595          selectedElm.removeAttribute('data-mce-selected');
11596        }
11597        each$1(resizeHandles, function (value, name) {
11598          var handleElm = dom.get('mceResizeHandle' + name);
11599          if (handleElm) {
11600            dom.unbind(handleElm);
11601            dom.remove(handleElm);
11602          }
11603        });
11604      };
11605      var updateResizeRect = function (e) {
11606        var startElm, controlElm;
11607        var isChildOrEqual = function (node, parent) {
11608          if (node) {
11609            do {
11610              if (node === parent) {
11611                return true;
11612              }
11613            } while (node = node.parentNode);
11614          }
11615        };
11616        if (resizeStarted || editor.removed) {
11617          return;
11618        }
11619        each(dom.select('img[data-mce-selected],hr[data-mce-selected]'), function (img) {
11620          img.removeAttribute('data-mce-selected');
11621        });
11622        controlElm = e.type === 'mousedown' ? e.target : selection.getNode();
11623        controlElm = dom.$(controlElm).closest('table,img,figure.image,hr')[0];
11624        if (isChildOrEqual(controlElm, rootElement)) {
11625          disableGeckoResize();
11626          startElm = selection.getStart(true);
11627          if (isChildOrEqual(startElm, controlElm) && isChildOrEqual(selection.getEnd(true), controlElm)) {
11628            showResizeRect(controlElm);
11629            return;
11630          }
11631        }
11632        hideResizeRect();
11633      };
11634      var isWithinContentEditableFalse = function (elm) {
11635        return isContentEditableFalse$6(getContentEditableRoot(editor.getBody(), elm));
11636      };
11637      var unbindResizeHandleEvents = function () {
11638        each$1(resizeHandles, function (handle) {
11639          if (handle.elm) {
11640            dom.unbind(handle.elm);
11641            delete handle.elm;
11642          }
11643        });
11644      };
11645      var disableGeckoResize = function () {
11646        try {
11647          editor.getDoc().execCommand('enableObjectResizing', false, 'false');
11648        } catch (ex) {
11649        }
11650      };
11651      editor.on('init', function () {
11652        disableGeckoResize();
11653        if (Env.browser.isIE() || Env.browser.isEdge()) {
11654          editor.on('mousedown click', function (e) {
11655            var target = e.target, nodeName = target.nodeName;
11656            if (!resizeStarted && /^(TABLE|IMG|HR)$/.test(nodeName) && !isWithinContentEditableFalse(target)) {
11657              if (e.button !== 2) {
11658                editor.selection.select(target, nodeName === 'TABLE');
11659              }
11660              if (e.type === 'mousedown') {
11661                editor.nodeChanged();
11662              }
11663            }
11664          });
11665          var handleMSControlSelect_1 = function (e) {
11666            var delayedSelect = function (node) {
11667              Delay.setEditorTimeout(editor, function () {
11668                return editor.selection.select(node);
11669              });
11670            };
11671            if (isWithinContentEditableFalse(e.target) || isMedia(e.target)) {
11672              e.preventDefault();
11673              delayedSelect(e.target);
11674              return;
11675            }
11676            if (/^(TABLE|IMG|HR)$/.test(e.target.nodeName)) {
11677              e.preventDefault();
11678              if (e.target.tagName === 'IMG') {
11679                delayedSelect(e.target);
11680              }
11681            }
11682          };
11683          dom.bind(rootElement, 'mscontrolselect', handleMSControlSelect_1);
11684          editor.on('remove', function () {
11685            return dom.unbind(rootElement, 'mscontrolselect', handleMSControlSelect_1);
11686          });
11687        }
11688        var throttledUpdateResizeRect = Delay.throttle(function (e) {
11689          if (!editor.composing) {
11690            updateResizeRect(e);
11691          }
11692        });
11693        editor.on('nodechange ResizeEditor ResizeWindow ResizeContent drop FullscreenStateChanged', throttledUpdateResizeRect);
11694        editor.on('keyup compositionend', function (e) {
11695          if (selectedElm && selectedElm.nodeName === 'TABLE') {
11696            throttledUpdateResizeRect(e);
11697          }
11698        });
11699        editor.on('hide blur', hideResizeRect);
11700        editor.on('contextmenu longpress', contextMenuSelectImage, true);
11701      });
11702      editor.on('remove', unbindResizeHandleEvents);
11703      var destroy = function () {
11704        selectedElm = selectedElmGhost = null;
11705      };
11706      return {
11707        isResizable: isResizable,
11708        showResizeRect: showResizeRect,
11709        hideResizeRect: hideResizeRect,
11710        updateResizeRect: updateResizeRect,
11711        destroy: destroy
11712      };
11713    };
11714
11715    var hasCeProperty = function (node) {
11716      return isContentEditableTrue(node) || isContentEditableFalse(node);
11717    };
11718    var findParent = function (node, rootNode, predicate) {
11719      while (node && node !== rootNode) {
11720        if (predicate(node)) {
11721          return node;
11722        }
11723        node = node.parentNode;
11724      }
11725      return null;
11726    };
11727    var findClosestIeRange = function (clientX, clientY, doc) {
11728      var rects;
11729      var element = doc.elementFromPoint(clientX, clientY);
11730      var rng = doc.body.createTextRange();
11731      if (!element || element.tagName === 'HTML') {
11732        element = doc.body;
11733      }
11734      rng.moveToElementText(element);
11735      rects = Tools.toArray(rng.getClientRects());
11736      rects = rects.sort(function (a, b) {
11737        a = Math.abs(Math.max(a.top - clientY, a.bottom - clientY));
11738        b = Math.abs(Math.max(b.top - clientY, b.bottom - clientY));
11739        return a - b;
11740      });
11741      if (rects.length > 0) {
11742        clientY = (rects[0].bottom + rects[0].top) / 2;
11743        try {
11744          rng.moveToPoint(clientX, clientY);
11745          rng.collapse(true);
11746          return rng;
11747        } catch (ex) {
11748        }
11749      }
11750      return null;
11751    };
11752    var moveOutOfContentEditableFalse = function (rng, rootNode) {
11753      var parentElement = rng && rng.parentElement ? rng.parentElement() : null;
11754      return isContentEditableFalse(findParent(parentElement, rootNode, hasCeProperty)) ? null : rng;
11755    };
11756    var fromPoint$1 = function (clientX, clientY, doc) {
11757      var rng, point;
11758      var pointDoc = doc;
11759      if (pointDoc.caretPositionFromPoint) {
11760        point = pointDoc.caretPositionFromPoint(clientX, clientY);
11761        if (point) {
11762          rng = doc.createRange();
11763          rng.setStart(point.offsetNode, point.offset);
11764          rng.collapse(true);
11765        }
11766      } else if (doc.caretRangeFromPoint) {
11767        rng = doc.caretRangeFromPoint(clientX, clientY);
11768      } else if (pointDoc.body.createTextRange) {
11769        rng = pointDoc.body.createTextRange();
11770        try {
11771          rng.moveToPoint(clientX, clientY);
11772          rng.collapse(true);
11773        } catch (ex) {
11774          rng = findClosestIeRange(clientX, clientY, doc);
11775        }
11776        return moveOutOfContentEditableFalse(rng, doc.body);
11777      }
11778      return rng;
11779    };
11780
11781    var isEq$1 = function (rng1, rng2) {
11782      return rng1 && rng2 && (rng1.startContainer === rng2.startContainer && rng1.startOffset === rng2.startOffset) && (rng1.endContainer === rng2.endContainer && rng1.endOffset === rng2.endOffset);
11783    };
11784
11785    var findParent$1 = function (node, rootNode, predicate) {
11786      while (node && node !== rootNode) {
11787        if (predicate(node)) {
11788          return node;
11789        }
11790        node = node.parentNode;
11791      }
11792      return null;
11793    };
11794    var hasParent = function (node, rootNode, predicate) {
11795      return findParent$1(node, rootNode, predicate) !== null;
11796    };
11797    var hasParentWithName = function (node, rootNode, name) {
11798      return hasParent(node, rootNode, function (node) {
11799        return node.nodeName === name;
11800      });
11801    };
11802    var isTable$3 = function (node) {
11803      return node && node.nodeName === 'TABLE';
11804    };
11805    var isTableCell$3 = function (node) {
11806      return node && /^(TD|TH|CAPTION)$/.test(node.nodeName);
11807    };
11808    var isCeFalseCaretContainer = function (node, rootNode) {
11809      return isCaretContainer(node) && hasParent(node, rootNode, isCaretNode) === false;
11810    };
11811    var hasBrBeforeAfter = function (dom, node, left) {
11812      var walker = new DomTreeWalker(node, dom.getParent(node.parentNode, dom.isBlock) || dom.getRoot());
11813      while (node = walker[left ? 'prev' : 'next']()) {
11814        if (isBr(node)) {
11815          return true;
11816        }
11817      }
11818    };
11819    var isPrevNode = function (node, name) {
11820      return node.previousSibling && node.previousSibling.nodeName === name;
11821    };
11822    var hasContentEditableFalseParent = function (body, node) {
11823      while (node && node !== body) {
11824        if (isContentEditableFalse(node)) {
11825          return true;
11826        }
11827        node = node.parentNode;
11828      }
11829      return false;
11830    };
11831    var findTextNodeRelative = function (dom, isAfterNode, collapsed, left, startNode) {
11832      var lastInlineElement;
11833      var body = dom.getRoot();
11834      var node;
11835      var nonEmptyElementsMap = dom.schema.getNonEmptyElements();
11836      var parentBlockContainer = dom.getParent(startNode.parentNode, dom.isBlock) || body;
11837      if (left && isBr(startNode) && isAfterNode && dom.isEmpty(parentBlockContainer)) {
11838        return Optional.some(CaretPosition(startNode.parentNode, dom.nodeIndex(startNode)));
11839      }
11840      var walker = new DomTreeWalker(startNode, parentBlockContainer);
11841      while (node = walker[left ? 'prev' : 'next']()) {
11842        if (dom.getContentEditableParent(node) === 'false' || isCeFalseCaretContainer(node, body)) {
11843          return Optional.none();
11844        }
11845        if (isText$1(node) && node.nodeValue.length > 0) {
11846          if (hasParentWithName(node, body, 'A') === false) {
11847            return Optional.some(CaretPosition(node, left ? node.nodeValue.length : 0));
11848          }
11849          return Optional.none();
11850        }
11851        if (dom.isBlock(node) || nonEmptyElementsMap[node.nodeName.toLowerCase()]) {
11852          return Optional.none();
11853        }
11854        lastInlineElement = node;
11855      }
11856      if (collapsed && lastInlineElement) {
11857        return Optional.some(CaretPosition(lastInlineElement, 0));
11858      }
11859      return Optional.none();
11860    };
11861    var normalizeEndPoint = function (dom, collapsed, start, rng) {
11862      var container, offset;
11863      var body = dom.getRoot();
11864      var node;
11865      var directionLeft, normalized = false;
11866      container = rng[(start ? 'start' : 'end') + 'Container'];
11867      offset = rng[(start ? 'start' : 'end') + 'Offset'];
11868      var isAfterNode = isElement$1(container) && offset === container.childNodes.length;
11869      var nonEmptyElementsMap = dom.schema.getNonEmptyElements();
11870      directionLeft = start;
11871      if (isCaretContainer(container)) {
11872        return Optional.none();
11873      }
11874      if (isElement$1(container) && offset > container.childNodes.length - 1) {
11875        directionLeft = false;
11876      }
11877      if (isDocument$1(container)) {
11878        container = body;
11879        offset = 0;
11880      }
11881      if (container === body) {
11882        if (directionLeft) {
11883          node = container.childNodes[offset > 0 ? offset - 1 : 0];
11884          if (node) {
11885            if (isCaretContainer(node)) {
11886              return Optional.none();
11887            }
11888            if (nonEmptyElementsMap[node.nodeName] || isTable$3(node)) {
11889              return Optional.none();
11890            }
11891          }
11892        }
11893        if (container.hasChildNodes()) {
11894          offset = Math.min(!directionLeft && offset > 0 ? offset - 1 : offset, container.childNodes.length - 1);
11895          container = container.childNodes[offset];
11896          offset = isText$1(container) && isAfterNode ? container.data.length : 0;
11897          if (!collapsed && container === body.lastChild && isTable$3(container)) {
11898            return Optional.none();
11899          }
11900          if (hasContentEditableFalseParent(body, container) || isCaretContainer(container)) {
11901            return Optional.none();
11902          }
11903          if (container.hasChildNodes() && isTable$3(container) === false) {
11904            node = container;
11905            var walker = new DomTreeWalker(container, body);
11906            do {
11907              if (isContentEditableFalse(node) || isCaretContainer(node)) {
11908                normalized = false;
11909                break;
11910              }
11911              if (isText$1(node) && node.nodeValue.length > 0) {
11912                offset = directionLeft ? 0 : node.nodeValue.length;
11913                container = node;
11914                normalized = true;
11915                break;
11916              }
11917              if (nonEmptyElementsMap[node.nodeName.toLowerCase()] && !isTableCell$3(node)) {
11918                offset = dom.nodeIndex(node);
11919                container = node.parentNode;
11920                if (!directionLeft) {
11921                  offset++;
11922                }
11923                normalized = true;
11924                break;
11925              }
11926            } while (node = directionLeft ? walker.next() : walker.prev());
11927          }
11928        }
11929      }
11930      if (collapsed) {
11931        if (isText$1(container) && offset === 0) {
11932          findTextNodeRelative(dom, isAfterNode, collapsed, true, container).each(function (pos) {
11933            container = pos.container();
11934            offset = pos.offset();
11935            normalized = true;
11936          });
11937        }
11938        if (isElement$1(container)) {
11939          node = container.childNodes[offset];
11940          if (!node) {
11941            node = container.childNodes[offset - 1];
11942          }
11943          if (node && isBr(node) && !isPrevNode(node, 'A') && !hasBrBeforeAfter(dom, node, false) && !hasBrBeforeAfter(dom, node, true)) {
11944            findTextNodeRelative(dom, isAfterNode, collapsed, true, node).each(function (pos) {
11945              container = pos.container();
11946              offset = pos.offset();
11947              normalized = true;
11948            });
11949          }
11950        }
11951      }
11952      if (directionLeft && !collapsed && isText$1(container) && offset === container.nodeValue.length) {
11953        findTextNodeRelative(dom, isAfterNode, collapsed, false, container).each(function (pos) {
11954          container = pos.container();
11955          offset = pos.offset();
11956          normalized = true;
11957        });
11958      }
11959      return normalized ? Optional.some(CaretPosition(container, offset)) : Optional.none();
11960    };
11961    var normalize = function (dom, rng) {
11962      var collapsed = rng.collapsed, normRng = rng.cloneRange();
11963      var startPos = CaretPosition.fromRangeStart(rng);
11964      normalizeEndPoint(dom, collapsed, true, normRng).each(function (pos) {
11965        if (!collapsed || !CaretPosition.isAbove(startPos, pos)) {
11966          normRng.setStart(pos.container(), pos.offset());
11967        }
11968      });
11969      if (!collapsed) {
11970        normalizeEndPoint(dom, collapsed, false, normRng).each(function (pos) {
11971          normRng.setEnd(pos.container(), pos.offset());
11972        });
11973      }
11974      if (collapsed) {
11975        normRng.collapse(true);
11976      }
11977      return isEq$1(rng, normRng) ? Optional.none() : Optional.some(normRng);
11978    };
11979
11980    var splitText = function (node, offset) {
11981      return node.splitText(offset);
11982    };
11983    var split$1 = function (rng) {
11984      var startContainer = rng.startContainer, startOffset = rng.startOffset, endContainer = rng.endContainer, endOffset = rng.endOffset;
11985      if (startContainer === endContainer && isText$1(startContainer)) {
11986        if (startOffset > 0 && startOffset < startContainer.nodeValue.length) {
11987          endContainer = splitText(startContainer, startOffset);
11988          startContainer = endContainer.previousSibling;
11989          if (endOffset > startOffset) {
11990            endOffset = endOffset - startOffset;
11991            startContainer = endContainer = splitText(endContainer, endOffset).previousSibling;
11992            endOffset = endContainer.nodeValue.length;
11993            startOffset = 0;
11994          } else {
11995            endOffset = 0;
11996          }
11997        }
11998      } else {
11999        if (isText$1(startContainer) && startOffset > 0 && startOffset < startContainer.nodeValue.length) {
12000          startContainer = splitText(startContainer, startOffset);
12001          startOffset = 0;
12002        }
12003        if (isText$1(endContainer) && endOffset > 0 && endOffset < endContainer.nodeValue.length) {
12004          endContainer = splitText(endContainer, endOffset).previousSibling;
12005          endOffset = endContainer.nodeValue.length;
12006        }
12007      }
12008      return {
12009        startContainer: startContainer,
12010        startOffset: startOffset,
12011        endContainer: endContainer,
12012        endOffset: endOffset
12013      };
12014    };
12015
12016    function RangeUtils(dom) {
12017      var walk = function (rng, callback) {
12018        return walk$1(dom, rng, callback);
12019      };
12020      var split = split$1;
12021      var normalize$1 = function (rng) {
12022        return normalize(dom, rng).fold(never, function (normalizedRng) {
12023          rng.setStart(normalizedRng.startContainer, normalizedRng.startOffset);
12024          rng.setEnd(normalizedRng.endContainer, normalizedRng.endOffset);
12025          return true;
12026        });
12027      };
12028      return {
12029        walk: walk,
12030        split: split,
12031        normalize: normalize$1
12032      };
12033    }
12034    (function (RangeUtils) {
12035      RangeUtils.compareRanges = isEq$1;
12036      RangeUtils.getCaretRangeFromPoint = fromPoint$1;
12037      RangeUtils.getSelectedNode = getSelectedNode;
12038      RangeUtils.getNode = getNode;
12039    }(RangeUtils || (RangeUtils = {})));
12040    var RangeUtils$1 = RangeUtils;
12041
12042    function Dimension (name, getOffset) {
12043      var set = function (element, h) {
12044        if (!isNumber(h) && !h.match(/^[0-9]+$/)) {
12045          throw new Error(name + '.set accepts only positive integer values. Value was ' + h);
12046        }
12047        var dom = element.dom;
12048        if (isSupported$1(dom)) {
12049          dom.style[name] = h + 'px';
12050        }
12051      };
12052      var get = function (element) {
12053        var r = getOffset(element);
12054        if (r <= 0 || r === null) {
12055          var css = get$4(element, name);
12056          return parseFloat(css) || 0;
12057        }
12058        return r;
12059      };
12060      var getOuter = get;
12061      var aggregate = function (element, properties) {
12062        return foldl(properties, function (acc, property) {
12063          var val = get$4(element, property);
12064          var value = val === undefined ? 0 : parseInt(val, 10);
12065          return isNaN(value) ? acc : acc + value;
12066        }, 0);
12067      };
12068      var max = function (element, value, properties) {
12069        var cumulativeInclusions = aggregate(element, properties);
12070        var absoluteMax = value > cumulativeInclusions ? value - cumulativeInclusions : 0;
12071        return absoluteMax;
12072      };
12073      return {
12074        set: set,
12075        get: get,
12076        getOuter: getOuter,
12077        aggregate: aggregate,
12078        max: max
12079      };
12080    }
12081
12082    var api$1 = Dimension('height', function (element) {
12083      var dom = element.dom;
12084      return inBody(element) ? dom.getBoundingClientRect().height : dom.offsetHeight;
12085    });
12086    var get$8 = function (element) {
12087      return api$1.get(element);
12088    };
12089
12090    var walkUp = function (navigation, doc) {
12091      var frame = navigation.view(doc);
12092      return frame.fold(constant([]), function (f) {
12093        var parent = navigation.owner(f);
12094        var rest = walkUp(navigation, parent);
12095        return [f].concat(rest);
12096      });
12097    };
12098    var pathTo = function (element, navigation) {
12099      var d = navigation.owner(element);
12100      return walkUp(navigation, d);
12101    };
12102
12103    var view = function (doc) {
12104      var _a;
12105      var element = doc.dom === document ? Optional.none() : Optional.from((_a = doc.dom.defaultView) === null || _a === void 0 ? void 0 : _a.frameElement);
12106      return element.map(SugarElement.fromDom);
12107    };
12108    var owner$1 = function (element) {
12109      return documentOrOwner(element);
12110    };
12111
12112    var Navigation = /*#__PURE__*/Object.freeze({
12113        __proto__: null,
12114        view: view,
12115        owner: owner$1
12116    });
12117
12118    var find$2 = function (element) {
12119      var doc = SugarElement.fromDom(document);
12120      var scroll = get$1(doc);
12121      var frames = pathTo(element, Navigation);
12122      var offset = viewport(element);
12123      var r = foldr(frames, function (b, a) {
12124        var loc = viewport(a);
12125        return {
12126          left: b.left + loc.left,
12127          top: b.top + loc.top
12128        };
12129      }, {
12130        left: 0,
12131        top: 0
12132      });
12133      return SugarPosition(r.left + offset.left + scroll.left, r.top + offset.top + scroll.top);
12134    };
12135
12136    var excludeFromDescend = function (element) {
12137      return name(element) === 'textarea';
12138    };
12139    var fireScrollIntoViewEvent = function (editor, data) {
12140      var scrollEvent = editor.fire('ScrollIntoView', data);
12141      return scrollEvent.isDefaultPrevented();
12142    };
12143    var fireAfterScrollIntoViewEvent = function (editor, data) {
12144      editor.fire('AfterScrollIntoView', data);
12145    };
12146    var descend = function (element, offset) {
12147      var children$1 = children(element);
12148      if (children$1.length === 0 || excludeFromDescend(element)) {
12149        return {
12150          element: element,
12151          offset: offset
12152        };
12153      } else if (offset < children$1.length && !excludeFromDescend(children$1[offset])) {
12154        return {
12155          element: children$1[offset],
12156          offset: 0
12157        };
12158      } else {
12159        var last = children$1[children$1.length - 1];
12160        if (excludeFromDescend(last)) {
12161          return {
12162            element: element,
12163            offset: offset
12164          };
12165        } else {
12166          if (name(last) === 'img') {
12167            return {
12168              element: last,
12169              offset: 1
12170            };
12171          } else if (isText(last)) {
12172            return {
12173              element: last,
12174              offset: get$7(last).length
12175            };
12176          } else {
12177            return {
12178              element: last,
12179              offset: children(last).length
12180            };
12181          }
12182        }
12183      }
12184    };
12185    var markerInfo = function (element, cleanupFun) {
12186      var pos = absolute(element);
12187      var height = get$8(element);
12188      return {
12189        element: element,
12190        bottom: pos.top + height,
12191        height: height,
12192        pos: pos,
12193        cleanup: cleanupFun
12194      };
12195    };
12196    var createMarker = function (element, offset) {
12197      var startPoint = descend(element, offset);
12198      var span = SugarElement.fromHtml('<span data-mce-bogus="all">' + ZWSP + '</span>');
12199      before(startPoint.element, span);
12200      return markerInfo(span, function () {
12201        return remove(span);
12202      });
12203    };
12204    var elementMarker = function (element) {
12205      return markerInfo(SugarElement.fromDom(element), noop);
12206    };
12207    var withMarker = function (editor, f, rng, alignToTop) {
12208      preserveWith(editor, function (_s, _e) {
12209        return applyWithMarker(editor, f, rng, alignToTop);
12210      }, rng);
12211    };
12212    var withScrollEvents = function (editor, doc, f, marker, alignToTop) {
12213      var data = {
12214        elm: marker.element.dom,
12215        alignToTop: alignToTop
12216      };
12217      if (fireScrollIntoViewEvent(editor, data)) {
12218        return;
12219      }
12220      var scrollTop = get$1(doc).top;
12221      f(doc, scrollTop, marker, alignToTop);
12222      fireAfterScrollIntoViewEvent(editor, data);
12223    };
12224    var applyWithMarker = function (editor, f, rng, alignToTop) {
12225      var body = SugarElement.fromDom(editor.getBody());
12226      var doc = SugarElement.fromDom(editor.getDoc());
12227      reflow(body);
12228      var marker = createMarker(SugarElement.fromDom(rng.startContainer), rng.startOffset);
12229      withScrollEvents(editor, doc, f, marker, alignToTop);
12230      marker.cleanup();
12231    };
12232    var withElement = function (editor, element, f, alignToTop) {
12233      var doc = SugarElement.fromDom(editor.getDoc());
12234      withScrollEvents(editor, doc, f, elementMarker(element), alignToTop);
12235    };
12236    var preserveWith = function (editor, f, rng) {
12237      var startElement = rng.startContainer;
12238      var startOffset = rng.startOffset;
12239      var endElement = rng.endContainer;
12240      var endOffset = rng.endOffset;
12241      f(SugarElement.fromDom(startElement), SugarElement.fromDom(endElement));
12242      var newRng = editor.dom.createRng();
12243      newRng.setStart(startElement, startOffset);
12244      newRng.setEnd(endElement, endOffset);
12245      editor.selection.setRng(rng);
12246    };
12247    var scrollToMarker = function (marker, viewHeight, alignToTop, doc) {
12248      var pos = marker.pos;
12249      if (alignToTop) {
12250        to(pos.left, pos.top, doc);
12251      } else {
12252        var y = pos.top - viewHeight + marker.height;
12253        to(pos.left, y, doc);
12254      }
12255    };
12256    var intoWindowIfNeeded = function (doc, scrollTop, viewHeight, marker, alignToTop) {
12257      var viewportBottom = viewHeight + scrollTop;
12258      var markerTop = marker.pos.top;
12259      var markerBottom = marker.bottom;
12260      var largerThanViewport = markerBottom - markerTop >= viewHeight;
12261      if (markerTop < scrollTop) {
12262        scrollToMarker(marker, viewHeight, alignToTop !== false, doc);
12263      } else if (markerTop > viewportBottom) {
12264        var align = largerThanViewport ? alignToTop !== false : alignToTop === true;
12265        scrollToMarker(marker, viewHeight, align, doc);
12266      } else if (markerBottom > viewportBottom && !largerThanViewport) {
12267        scrollToMarker(marker, viewHeight, alignToTop === true, doc);
12268      }
12269    };
12270    var intoWindow = function (doc, scrollTop, marker, alignToTop) {
12271      var viewHeight = doc.dom.defaultView.innerHeight;
12272      intoWindowIfNeeded(doc, scrollTop, viewHeight, marker, alignToTop);
12273    };
12274    var intoFrame = function (doc, scrollTop, marker, alignToTop) {
12275      var frameViewHeight = doc.dom.defaultView.innerHeight;
12276      intoWindowIfNeeded(doc, scrollTop, frameViewHeight, marker, alignToTo
12276p);
12277      var op = find$2(marker.element);
12278      var viewportBounds = getBounds(window);
12279      if (op.top < viewportBounds.y) {
12280        intoView(marker.element, alignToTop !== false);
12281      } else if (op.top > viewportBounds.bottom) {
12282        intoView(marker.element, alignToTop === true);
12283      }
12284    };
12285    var rangeIntoWindow = function (editor, rng, alignToTop) {
12286      return withMarker(editor, intoWindow, rng, alignToTop);
12287    };
12288    var elementIntoWindow = function (editor, element, alignToTop) {
12289      return withElement(editor, element, intoWindow, alignToTop);
12290    };
12291    var rangeIntoFrame = function (editor, rng, alignToTop) {
12292      return withMarker(editor, intoFrame, rng, alignToTop);
12293    };
12294    var elementIntoFrame = function (editor, element, alignToTop) {
12295      return withElement(editor, element, intoFrame, alignToTop);
12296    };
12297    var scrollElementIntoView = function (editor, element, alignToTop) {
12298      var scroller = editor.inline ? elementIntoWindow : elementIntoFrame;
12299      scroller(editor, element, alignToTop);
12300    };
12301    var scrollRangeIntoView = function (editor, rng, alignToTop) {
12302      var scroller = editor.inline ? rangeIntoWindow : rangeIntoFrame;
12303      scroller(editor, rng, alignToTop);
12304    };
12305
12306    var getDocument = function () {
12307      return SugarElement.fromDom(document);
12308    };
12309
12310    var focus = function (element) {
12311      return element.dom.focus();
12312    };
12313    var hasFocus = function (element) {
12314      var root = getRootNode(element).dom;
12315      return element.dom === root.activeElement;
12316    };
12317    var active = function (root) {
12318      if (root === void 0) {
12319        root = getDocument();
12320      }
12321      return Optional.from(root.dom.activeElement).map(SugarElement.fromDom);
12322    };
12323    var search = function (element) {
12324      return active(getRootNode(element)).filter(function (e) {
12325        return element.dom.contains(e.dom);
12326      });
12327    };
12328
12329    var create$4 = function (start, soffset, finish, foffset) {
12330      return {
12331        start: start,
12332        soffset: soffset,
12333        finish: finish,
12334        foffset: foffset
12335      };
12336    };
12337    var SimRange = { create: create$4 };
12338
12339    var adt = Adt.generate([
12340      { before: ['element'] },
12341      {
12342        on: [
12343          'element',
12344          'offset'
12345        ]
12346      },
12347      { after: ['element'] }
12348    ]);
12349    var cata = function (subject, onBefore, onOn, onAfter) {
12350      return subject.fold(onBefore, onOn, onAfter);
12351    };
12352    var getStart = function (situ) {
12353      return situ.fold(identity, identity, identity);
12354    };
12355    var before$3 = adt.before;
12356    var on = adt.on;
12357    var after$2 = adt.after;
12358    var Situ = {
12359      before: before$3,
12360      on: on,
12361      after: after$2,
12362      cata: cata,
12363      getStart: getStart
12364    };
12365
12366    var adt$1 = Adt.generate([
12367      { domRange: ['rng'] },
12368      {
12369        relative: [
12370          'startSitu',
12371          'finishSitu'
12372        ]
12373      },
12374      {
12375        exact: [
12376          'start',
12377          'soffset',
12378          'finish',
12379          'foffset'
12380        ]
12381      }
12382    ]);
12383    var exactFromRange = function (simRange) {
12384      return adt$1.exact(simRange.start, simRange.soffset, simRange.finish, simRange.foffset);
12385    };
12386    var getStart$1 = function (selection) {
12387      return selection.match({
12388        domRange: function (rng) {
12389          return SugarElement.fromDom(rng.startContainer);
12390        },
12391        relative: function (startSitu, _finishSitu) {
12392          return Situ.getStart(startSitu);
12393        },
12394        exact: function (start, _soffset, _finish, _foffset) {
12395          return start;
12396        }
12397      });
12398    };
12399    var domRange = adt$1.domRange;
12400    var relative = adt$1.relative;
12401    var exact = adt$1.exact;
12402    var getWin = function (selection) {
12403      var start = getStart$1(selection);
12404      return defaultView(start);
12405    };
12406    var range = SimRange.create;
12407    var SimSelection = {
12408      domRange: domRange,
12409      relative: relative,
12410      exact: exact,
12411      exactFromRange: exactFromRange,
12412      getWin: getWin,
12413      range: range
12414    };
12415
12416    var browser$3 = detect$3().browser;
12417    var clamp = function (offset, element) {
12418      var max = isText(element) ? get$7(element).length : children(element).length + 1;
12419      if (offset > max) {
12420        return max;
12421      } else if (offset < 0) {
12422        return 0;
12423      }
12424      return offset;
12425    };
12426    var normalizeRng = function (rng) {
12427      return SimSelection.range(rng.start, clamp(rng.soffset, rng.start), rng.finish, clamp(rng.foffset, rng.finish));
12428    };
12429    var isOrContains = function (root, elm) {
12430      return !isRestrictedNode(elm.dom) && (contains$2(root, elm) || eq$2(root, elm));
12431    };
12432    var isRngInRoot = function (root) {
12433      return function (rng) {
12434        return isOrContains(root, rng.start) && isOrContains(root, rng.finish);
12435      };
12436    };
12437    var shouldStore = function (editor) {
12438      return editor.inline === true || browser$3.isIE();
12439    };
12440    var nativeRangeToSelectionRange = function (r) {
12441      return SimSelection.range(SugarElement.fromDom(r.startContainer), r.startOffset, SugarElement.fromDom(r.endContainer), r.endOffset);
12442    };
12443    var readRange = function (win) {
12444      var selection = win.getSelection();
12445      var rng = !selection || selection.rangeCount === 0 ? Optional.none() : Optional.from(selection.getRangeAt(0));
12446      return rng.map(nativeRangeToSelectionRange);
12447    };
12448    var getBookmark$2 = function (root) {
12449      var win = defaultView(root);
12450      return readRange(win.dom).filter(isRngInRoot(root));
12451    };
12452    var validate = function (root, bookmark) {
12453      return Optional.from(bookmark).filter(isRngInRoot(root)).map(normalizeRng);
12454    };
12455    var bookmarkToNativeRng = function (bookmark) {
12456      var rng = document.createRange();
12457      try {
12458        rng.setStart(bookmark.start.dom, bookmark.soffset);
12459        rng.setEnd(bookmark.finish.dom, bookmark.foffset);
12460        return Optional.some(rng);
12461      } catch (_) {
12462        return Optional.none();
12463      }
12464    };
12465    var store = function (editor) {
12466      var newBookmark = shouldStore(editor) ? getBookmark$2(SugarElement.fromDom(editor.getBody())) : Optional.none();
12467      editor.bookmark = newBookmark.isSome() ? newBookmark : editor.bookmark;
12468    };
12469    var storeNative = function (editor, rng) {
12470      var root = SugarElement.fromDom(editor.getBody());
12471      var range = shouldStore(editor) ? Optional.from(rng) : Optional.none();
12472      var newBookmark = range.map(nativeRangeToSelectionRange).filter(isRngInRoot(root));
12473      editor.bookmark = newBookmark.isSome() ? newBookmark : editor.bookmark;
12474    };
12475    var getRng = function (editor) {
12476      var bookmark = editor.bookmark ? editor.bookmark : Optional.none();
12477      return bookmark.bind(function (x) {
12478        return validate(SugarElement.fromDom(editor.getBody()), x);
12479      }).bind(bookmarkToNativeRng);
12480    };
12481    var restore = function (editor) {
12482      getRng(editor).each(function (rng) {
12483        return editor.selection.setRng(rng);
12484      });
12485    };
12486
12487    var isEditorUIElement = function (elm) {
12488      var className = elm.className.toString();
12489      return className.indexOf('tox-') !== -1 || className.indexOf('mce-') !== -1;
12490    };
12491    var FocusManager = { isEditorUIElement: isEditorUIElement };
12492
12493    var isManualNodeChange = function (e) {
12494      return e.type === 'nodechange' && e.selectionChange;
12495    };
12496    var registerPageMouseUp = function (editor, throttledStore) {
12497      var mouseUpPage = function () {
12498        throttledStore.throttle();
12499      };
12500      DOMUtils$1.DOM.bind(document, 'mouseup', mouseUpPage);
12501      editor.on('remove', function () {
12502        DOMUtils$1.DOM.unbind(document, 'mouseup', mouseUpPage);
12503      });
12504    };
12505    var registerFocusOut = function (editor) {
12506      editor.on('focusout', function () {
12507        store(editor);
12508      });
12509    };
12510    var registerMouseUp = function (editor, throttledStore) {
12511      editor.on('mouseup touchend', function (_e) {
12512        throttledStore.throttle();
12513      });
12514    };
12515    var registerEditorEvents = function (editor, throttledStore) {
12516      var browser = detect$3().browser;
12517      if (browser.isIE()) {
12518        registerFocusOut(editor);
12519      } else {
12520        registerMouseUp(editor, throttledStore);
12521      }
12522      editor.on('keyup NodeChange', function (e) {
12523        if (!isManualNodeChange(e)) {
12524          store(editor);
12525        }
12526      });
12527    };
12528    var register = function (editor) {
12529      var throttledStore = first(function () {
12530        store(editor);
12531      }, 0);
12532      editor.on('init', function () {
12533        if (editor.inline) {
12534          registerPageMouseUp(editor, throttledStore);
12535        }
12536        registerEditorEvents(editor, throttledStore);
12537      });
12538      editor.on('remove', function () {
12539        throttledStore.cancel();
12540      });
12541    };
12542
12543    var documentFocusInHandler;
12544    var DOM$2 = DOMUtils$1.DOM;
12545    var isEditorUIElement$1 = function (elm) {
12546      return FocusManager.isEditorUIElement(elm);
12547    };
12548    var isEditorContentAreaElement = function (elm) {
12549      var classList = elm.classList;
12550      if (classList !== undefined) {
12551        return classList.contains('tox-edit-area') || classList.contains('tox-edit-area__iframe') || classList.contains('mce-content-body');
12552      } else {
12553        return false;
12554      }
12555    };
12556    var isUIElement = function (editor, elm) {
12557      var customSelector = getCustomUiSelector(editor);
12558      var parent = DOM$2.getParent(elm, function (elm) {
12559        return isEditorUIElement$1(elm) || (customSelector ? editor.dom.is(elm, customSelector) : false);
12560      });
12561      return parent !== null;
12562    };
12563    var getActiveElement = function (editor) {
12564      try {
12565        var root = getRootNode(SugarElement.fromDom(editor.getElement()));
12566        return active(root).fold(function () {
12567          return document.body;
12568        }, function (x) {
12569          return x.dom;
12570        });
12571      } catch (ex) {
12572        return document.body;
12573      }
12574    };
12575    var registerEvents = function (editorManager, e) {
12576      var editor = e.editor;
12577      register(editor);
12578      editor.on('focusin', function () {
12579        var self = this;
12580        var focusedEditor = editorManager.focusedEditor;
12581        if (focusedEditor !== self) {
12582          if (focusedEditor) {
12583            focusedEditor.fire('blur', { focusedEditor: self });
12584          }
12585          editorManager.setActive(self);
12586          editorManager.focusedEditor = self;
12587          self.fire('focus', { blurredEditor: focusedEditor });
12588          self.focus(true);
12589        }
12590      });
12591      editor.on('focusout', function () {
12592        var self = this;
12593        Delay.setEditorTimeout(self, function () {
12594          var focusedEditor = editorManager.focusedEditor;
12595          if (!isUIElement(self, getActiveElement(self)) && focusedEditor === self) {
12596            self.fire('blur', { focusedEditor: null });
12597            editorManager.focusedEditor = null;
12598          }
12599        });
12600      });
12601      if (!documentFocusInHandler) {
12602        documentFocusInHandler = function (e) {
12603          var activeEditor = editorManager.activeEditor;
12604          if (activeEditor) {
12605            getOriginalEventTarget(e).each(function (target) {
12606              if (target.ownerDocument === document) {
12607                if (target !== document.body && !isUIElement(activeEditor, target) && editorManager.focusedEditor === activeEditor) {
12608                  activeEditor.fire('blur', { focusedEditor: null });
12609                  editorManager.focusedEditor = null;
12610                }
12611              }
12612            });
12613          }
12614        };
12615        DOM$2.bind(document, 'focusin', documentFocusInHandler);
12616      }
12617    };
12618    var unregisterDocumentEvents = function (editorManager, e) {
12619      if (editorManager.focusedEditor === e.editor) {
12620        editorManager.focusedEditor = null;
12621      }
12622      if (!editorManager.activeEditor) {
12623        DOM$2.unbind(document, 'focusin', documentFocusInHandler);
12624        documentFocusInHandler = null;
12625      }
12626    };
12627    var setup$2 = function (editorManager) {
12628      editorManager.on('AddEditor', curry(registerEvents, editorManager));
12629      editorManager.on('RemoveEditor', curry(unregisterDocumentEvents, editorManager));
12630    };
12631
12632    var getContentEditableHost = function (editor, node) {
12633      return editor.dom.getParent(node, function (node) {
12634        return editor.dom.getContentEditable(node) === 'true';
12635      });
12636    };
12637    var getCollapsedNode = function (rng) {
12638      return rng.collapsed ? Optional.from(getNode(rng.startContainer, rng.startOffset)).map(SugarElement.fromDom) : Optional.none();
12639    };
12640    var getFocusInElement = function (root, rng) {
12641      return getCollapsedNode(rng).bind(function (node) {
12642        if (isTableSection(node)) {
12643          return Optional.some(node);
12644        } else if (contains$2(root, node) === false) {
12645          return Optional.some(root);
12646        } else {
12647          return Optional.none();
12648        }
12649      });
12650    };
12651    var normalizeSelection = function (editor, rng) {
12652      getFocusInElement(SugarElement.fromDom(editor.getBody()), rng).bind(function (elm) {
12653        return firstPositionIn(elm.dom);
12654      }).fold(function () {
12655        editor.selection.normalize();
12656        return;
12657      }, function (caretPos) {
12658        return editor.selection.setRng(caretPos.toRange());
12659      });
12660    };
12661    var focusBody = function (body) {
12662      if (body.setActive) {
12663        try {
12664          body.setActive();
12665        } catch (ex) {
12666          body.focus();
12667        }
12668      } else {
12669        body.focus();
12670      }
12671    };
12672    var hasElementFocus = function (elm) {
12673      return hasFocus(elm) || search(elm).isSome();
12674    };
12675    var hasIframeFocus = function (editor) {
12676      return editor.iframeElement && hasFocus(SugarElement.fromDom(editor.iframeElement));
12677    };
12678    var hasInlineFocus = function (editor) {
12679      var rawBody = editor.getBody();
12680      return rawBody && hasElementFocus(SugarElement.fromDom(rawBody));
12681    };
12682    var hasUiFocus = function (editor) {
12683      return active().filter(function (elem) {
12684        return !isEditorContentAreaElement(elem.dom) && isUIElement(editor, elem.dom);
12685      }).isSome();
12686    };
12687    var hasFocus$1 = function (editor) {
12688      return editor.inline ? hasInlineFocus(editor) : hasIframeFocus(editor);
12689    };
12690    var hasEditorOrUiFocus = function (editor) {
12691      return hasFocus$1(editor) || hasUiFocus(editor);
12692    };
12693    var focusEditor = function (editor) {
12694      var selection = editor.selection;
12695      var body = editor.getBody();
12696      var rng = selection.getRng();
12697      editor.quirks.refreshContentEditable();
12698      if (editor.bookmark !== undefined && hasFocus$1(editor) === false) {
12699        getRng(editor).each(function (bookmarkRng) {
12700          editor.selection.setRng(bookmarkRng);
12701          rng = bookmarkRng;
12702        });
12703      }
12704      var contentEditableHost = getContentEditableHost(editor, selection.getNode());
12705      if (editor.$.contains(body, contentEditableHost)) {
12706        focusBody(contentEditableHost);
12707        normalizeSelection(editor, rng);
12708        activateEditor(editor);
12709        return;
12710      }
12711      if (!editor.inline) {
12712        if (!Env.opera) {
12713          focusBody(body);
12714        }
12715        editor.getWin().focus();
12716      }
12717      if (Env.gecko || editor.inline) {
12718        focusBody(body);
12719        normalizeSelection(editor, rng);
12720      }
12721      activateEditor(editor);
12722    };
12723    var activateEditor = function (editor) {
12724      return editor.editorManager.setActive(editor);
12725    };
12726    var focus$1 = function (editor, skipFocus) {
12727      if (editor.removed) {
12728        return;
12729      }
12730      skipFocus ? activateEditor(editor) : focusEditor(editor);
12731    };
12732
12733    var getEndpointElement = function (root, rng, start, real, resolve) {
12734      var container = start ? rng.startContainer : rng.endContainer;
12735      var offset = start ? rng.startOffset : rng.endOffset;
12736      return Optional.from(container).map(SugarElement.fromDom).map(function (elm) {
12737        return !real || !rng.collapsed ? child(elm, resolve(elm, offset)).getOr(elm) : elm;
12738      }).bind(function (elm) {
12739        return isElement(elm) ? Optional.some(elm) : parent(elm).filter(isElement);
12740      }).map(function (elm) {
12741        return elm.dom;
12742      }).getOr(root);
12743    };
12744    var getStart$2 = function (root, rng, real) {
12745      return getEndpointElement(root, rng, true, real, function (elm, offset) {
12746        return Math.min(childNodesCount(elm), offset);
12747      });
12748    };
12749    var getEnd = function (root, rng, real) {
12750      return getEndpointElement(root, rng, false, real, function (elm, offset) {
12751        return offset > 0 ? offset - 1 : offset;
12752      });
12753    };
12754    var skipEmptyTextNodes = function (node, forwards) {
12755      var orig = node;
12756      while (node && isText$1(node) && node.length === 0) {
12757        node = forwards ? node.nextSibling : node.previousSibling;
12758      }
12759      return node || orig;
12760    };
12761    var getNode$1 = function (root, rng) {
12762      var elm, startContainer, endContainer;
12763      if (!rng) {
12764        return root;
12765      }
12766      startContainer = rng.startContainer;
12767      endContainer = rng.endContainer;
12768      var startOffset = rng.startOffset;
12769      var endOffset = rng.endOffset;
12770      elm = rng.commonAncestorContainer;
12771      if (!rng.collapsed) {
12772        if (startContainer === endContainer) {
12773          if (endOffset - startOffset < 2) {
12774            if (startContainer.hasChildNodes()) {
12775              elm = startContainer.childNodes[startOffset];
12776            }
12777          }
12778        }
12779        if (startContainer.nodeType === 3 && endContainer.nodeType === 3) {
12780          if (startContainer.length === startOffset) {
12781            startContainer = skipEmptyTextNodes(startContainer.nextSibling, true);
12782          } else {
12783            startContainer = startContainer.parentNode;
12784          }
12785          if (endOffset === 0) {
12786            endContainer = skipEmptyTextNodes(endContainer.previousSibling, false);
12787          } else {
12788            endContainer = endContainer.parentNode;
12789          }
12790          if (startContainer && startContainer === endContainer) {
12791            return startContainer;
12792          }
12793        }
12794      }
12795      if (elm && elm.nodeType === 3) {
12796        return elm.parentNode;
12797      }
12798      return elm;
12799    };
12800    var getSelectedBlocks = function (dom, rng, startElm, endElm) {
12801      var node;
12802      var selectedBlocks = [];
12803      var root = dom.getRoot();
12804      startElm = dom.getParent(startElm || getStart$2(root, rng, rng.collapsed), dom.isBlock);
12805      endElm = dom.getParent(endElm || getEnd(root, rng, rng.collapsed), dom.isBlock);
12806      if (startElm && startElm !== root) {
12807        selectedBlocks.push(startElm);
12808      }
12809      if (startElm && endElm && startElm !== endElm) {
12810        node = startElm;
12811        var walker = new DomTreeWalker(startElm, root);
12812        while ((node = walker.next()) && node !== endElm) {
12813          if (dom.isBlock(node)) {
12814            selectedBlocks.push(node);
12815          }
12816        }
12817      }
12818      if (endElm && startElm !== endElm && endElm !== root) {
12819        selectedBlocks.push(endElm);
12820      }
12821      return selectedBlocks;
12822    };
12823    var select$1 = function (dom, node, content) {
12824      return Optional.from(node).map(function (node) {
12825        var idx = dom.nodeIndex(node);
12826        var rng = dom.createRng();
12827        rng.setStart(node.parentNode, idx);
12828        rng.setEnd(node.parentNode, idx + 1);
12829        if (content) {
12830          moveEndPoint$1(dom, rng, node, true);
12831          moveEndPoint$1(dom, rng, node, false);
12832        }
12833        return rng;
12834      });
12835    };
12836
12837    var processRanges = function (editor, ranges) {
12838      return map(ranges, function (range) {
12839        var evt = editor.fire('GetSelectionRange', { range: range });
12840        return evt.range !== range ? evt.range : range;
12841      });
12842    };
12843
12844    var typeLookup = {
12845      '#text': 3,
12846      '#comment': 8,
12847      '#cdata': 4,
12848      '#pi': 7,
12849      '#doctype': 10,
12850      '#document-fragment': 11
12851    };
12852    var walk$2 = function (node, root, prev) {
12853      var startName = prev ? 'lastChild' : 'firstChild';
12854      var siblingName = prev ? 'prev' : 'next';
12855      if (node[startName]) {
12856        return node[startName];
12857      }
12858      if (node !== root) {
12859        var sibling = node[siblingName];
12860        if (sibling) {
12861          return sibling;
12862        }
12863        for (var parent_1 = node.parent; parent_1 && parent_1 !== root; parent_1 = parent_1.parent) {
12864          sibling = parent_1[siblingName];
12865          if (sibling) {
12866            return sibling;
12867          }
12868        }
12869      }
12870    };
12871    var isEmptyTextNode$1 = function (node) {
12872      if (!isWhitespaceText(node.value)) {
12873        return false;
12874      }
12875      var parentNode = node.parent;
12876      if (parentNode && (parentNode.name !== 'span' || parentNode.attr('style')) && /^[ ]+$/.test(node.value)) {
12877        return false;
12878      }
12879      return true;
12880    };
12881    var isNonEmptyElement = function (node) {
12882      var isNamedAnchor = node.name === 'a' && !node.attr('href') && node.attr('id');
12883      return node.attr('name') || node.attr('id') && !node.firstChild || node.attr('data-mce-bookmark') || isNamedAnchor;
12884    };
12885    var AstNode = function () {
12886      function AstNode(name, type) {
12887        this.name = name;
12888        this.type = type;
12889        if (type === 1) {
12890          this.attributes = [];
12891          this.attributes.map = {};
12892        }
12893      }
12894      AstNode.create = function (name, attrs) {
12895        var node = new AstNode(name, typeLookup[name] || 1);
12896        if (attrs) {
12897          each$1(attrs, function (value, attrName) {
12898            node.attr(attrName, value);
12899          });
12900        }
12901        return node;
12902      };
12903      AstNode.prototype.replace = function (node) {
12904        var self = this;
12905        if (node.parent) {
12906          node.remove();
12907        }
12908        self.insert(node, self);
12909        self.remove();
12910        return self;
12911      };
12912      AstNode.prototype.attr = function (name, value) {
12913        var self = this;
12914        var attrs;
12915        if (typeof name !== 'string') {
12916          if (name !== undefined && name !== null) {
12917            each$1(name, function (value, key) {
12918              self.attr(key, value);
12919            });
12920          }
12921          return self;
12922        }
12923        if (attrs = self.attributes) {
12924          if (value !== undefined) {
12925            if (value === null) {
12926              if (name in attrs.map) {
12927                delete attrs.map[name];
12928                var i = attrs.length;
12929                while (i--) {
12930                  if (attrs[i].name === name) {
12931                    attrs.splice(i, 1);
12932                    return self;
12933                  }
12934                }
12935              }
12936              return self;
12937            }
12938            if (name in attrs.map) {
12939              var i = attrs.length;
12940              while (i--) {
12941                if (attrs[i].name === name) {
12942                  attrs[i].value = value;
12943                  break;
12944                }
12945              }
12946            } else {
12947              attrs.push({
12948                name: name,
12949                value: value
12950              });
12951            }
12952            attrs.map[name] = value;
12953            return self;
12954          }
12955          return attrs.map[name];
12956        }
12957      };
12958      AstNode.prototype.clone = function () {
12959        var self = this;
12960        var clone = new AstNode(self.name, self.type);
12961        var selfAttrs;
12962        if (selfAttrs = self.attributes) {
12963          var cloneAttrs = [];
12964          cloneAttrs.map = {};
12965          for (var i = 0, l = selfAttrs.length; i < l; i++) {
12966            var selfAttr = selfAttrs[i];
12967            if (selfAttr.name !== 'id') {
12968              cloneAttrs[cloneAttrs.length] = {
12969                name: selfAttr.name,
12970                value: selfAttr.value
12971              };
12972              cloneAttrs.map[selfAttr.name] = selfAttr.value;
12973            }
12974          }
12975          clone.attributes = cloneAttrs;
12976        }
12977        clone.value = self.value;
12978        clone.shortEnded = self.shortEnded;
12979        return clone;
12980      };
12981      AstNode.prototype.wrap = function (wrapper) {
12982        var self = this;
12983        self.parent.insert(wrapper, self);
12984        wrapper.append(self);
12985        return self;
12986      };
12987      AstNode.prototype.unwrap = function () {
12988        var self = this;
12989        for (var node = self.firstChild; node;) {
12990          var next = node.next;
12991          self.insert(node, self, true);
12992          node = next;
12993        }
12994        self.remove();
12995      };
12996      AstNode.prototype.remove = function () {
12997        var self = this, parent = self.parent, next = self.next, prev = self.prev;
12998        if (parent) {
12999          if (parent.firstChild === self) {
13000            parent.firstChild = next;
13001            if (next) {
13002              next.prev = null;
13003            }
13004          } else {
13005            prev.next = next;
13006          }
13007          if (parent.lastChild === self) {
13008            parent.lastChild = prev;
13009            if (prev) {
13010              prev.next = null;
13011            }
13012          } else {
13013            next.prev = prev;
13014          }
13015          self.parent = self.next = self.prev = null;
13016        }
13017        return self;
13018      };
13019      AstNode.prototype.append = function (node) {
13020        var self = this;
13021        if (node.parent) {
13022          node.remove();
13023        }
13024        var last = self.lastChild;
13025        if (last) {
13026          last.next = node;
13027          node.prev = last;
13028          self.lastChild = node;
13029        } else {
13030          self.lastChild = self.firstChild = node;
13031        }
13032        node.parent = self;
13033        return node;
13034      };
13035      AstNode.prototype.insert = function (node, refNode, before) {
13036        if (node.parent) {
13037          node.remove();
13038        }
13039        var parent = refNode.parent || this;
13040        if (before) {
13041          if (refNode === parent.firstChild) {
13042            parent.firstChild = node;
13043          } else {
13044            refNode.prev.next = node;
13045          }
13046          node.prev = refNode.prev;
13047          node.next = refNode;
13048          refNode.prev = node;
13049        } else {
13050          if (refNode === parent.lastChild) {
13051            parent.lastChild = node;
13052          } else {
13053            refNode.next.prev = node;
13054          }
13055          node.next = refNode.next;
13056          node.prev = refNode;
13057          refNode.next = node;
13058        }
13059        node.parent = parent;
13060        return node;
13061      };
13062      AstNode.prototype.getAll = function (name) {
13063        var self = this;
13064        var collection = [];
13065        for (var node = self.firstChild; node; node = walk$2(node, self)) {
13066          if (node.name === name) {
13067            collection.push(node);
13068          }
13069        }
13070        return collection;
13071      };
13072      AstNode.prototype.empty = function () {
13073        var self = this;
13074        if (self.firstChild) {
13075          var nodes = [];
13076          for (var node = self.firstChild; node; node = walk$2(node, self)) {
13077            nodes.push(node);
13078          }
13079          var i = nodes.length;
13080          while (i--) {
13081            var node = nodes[i];
13082            node.parent = node.firstChild = node.lastChild = node.next = node.prev = null;
13083          }
13084        }
13085        self.firstChild = self.lastChild = null;
13086        return self;
13087      };
13088      AstNode.prototype.isEmpty = function (elements, whitespace, predicate) {
13089        if (whitespace === void 0) {
13090          whitespace = {};
13091        }
13092        var self = this;
13093        var node = self.firstChild;
13094        if (isNonEmptyElement(self)) {
13095          return false;
13096        }
13097        if (node) {
13098          do {
13099            if (node.type === 1) {
13100              if (node.attr('data-mce-bogus')) {
13101                continue;
13102              }
13103              if (elements[node.name]) {
13104                return false;
13105              }
13106              if (isNonEmptyElement(node)) {
13107                return false;
13108              }
13109            }
13110            if (node.type === 8) {
13111              return false;
13112            }
13113            if (node.type === 3 && !isEmptyTextNode$1(node)) {
13114              return false;
13115            }
13116            if (node.type === 3 && node.parent && whitespace[node.parent.name] && isWhitespaceText(node.value)) {
13117              return false;
13118            }
13119            if (predicate && predicate(node)) {
13120              return false;
13121            }
13122          } while (node = walk$2(node, self));
13123        }
13124        return true;
13125      };
13126      AstNode.prototype.walk = function (prev) {
13127        return walk$2(this, null, prev);
13128      };
13129      return AstNode;
13130    }();
13131
13132    var makeMap$3 = Tools.makeMap;
13133    var Writer = function (settings) {
13134      var html = [];
13135      settings = settings || {};
13136      var indent = settings.indent;
13137      var indentBefore = makeMap$3(settings.indent_before || '');
13138      var indentAfter = makeMap$3(settings.indent_after || '');
13139      var encode = Entities.getEncodeFunc(settings.entity_encoding || 'raw', settings.entities);
13140      var htmlOutput = settings.element_format === 'html';
13141      return {
13142        start: function (name, attrs, empty) {
13143          var i, l, attr, value;
13144          if (indent && indentBefore[name] && html.length > 0) {
13145            value = html[html.length - 1];
13146            if (value.length > 0 && value !== '\n') {
13147              html.push('\n');
13148            }
13149          }
13150          html.push('<', name);
13151          if (attrs) {
13152            for (i = 0, l = attrs.length; i < l; i++) {
13153              attr = attrs[i];
13154              html.push(' ', attr.name, '="', encode(attr.value, true), '"');
13155            }
13156          }
13157          if (!empty || htmlOutput) {
13158            html[html.length] = '>';
13159          } else {
13160            html[html.length] = ' />';
13161          }
13162          if (empty && indent && indentAfter[name] && html.length > 0) {
13163            value = html[html.length - 1];
13164            if (value.length > 0 && value !== '\n') {
13165              html.push('\n');
13166            }
13167          }
13168        },
13169        end: function (name) {
13170          var value;
13171          html.push('</', name, '>');
13172          if (indent && indentAfter[name] && html.length > 0) {
13173            value = html[html.length - 1];
13174            if (value.length > 0 && value !== '\n') {
13175              html.push('\n');
13176            }
13177          }
13178        },
13179        text: function (text, raw) {
13180          if (text.length > 0) {
13181            html[html.length] = raw ? text : encode(text);
13182          }
13183        },
13184        cdata: function (text) {
13185          html.push('<![CDATA[', text, ']]>');
13186        },
13187        comment: function (text) {
13188          html.push('<!--', text, '-->');
13189        },
13190        pi: function (name, text) {
13191          if (text) {
13192            html.push('<?', name, ' ', encode(text), '?>');
13193          } else {
13194            html.push('<?', name, '?>');
13195          }
13196          if (indent) {
13197            html.push('\n');
13198          }
13199        },
13200        doctype: function (text) {
13201          html.push('<!DOCTYPE', text, '>', indent ? '\n' : '');
13202        },
13203        reset: function () {
13204          html.length = 0;
13205        },
13206        getContent: function () {
13207          return html.join('').replace(/\n$/, '');
13208        }
13209      };
13210    };
13211
13212    var HtmlSerializer = function (settings, schema) {
13213      if (schema === void 0) {
13214        schema = Schema();
13215      }
13216      var writer = Writer(settings);
13217      settings = settings || {};
13218      settings.validate = 'validate' in settings ? settings.validate : true;
13219      var serialize = function (node) {
13220        var validate = settings.validate;
13221        var handlers = {
13222          3: function (node) {
13223            writer.text(node.value, node.raw);
13224          },
13225          8: function (node) {
13226            writer.comment(node.value);
13227          },
13228          7: function (node) {
13229            writer.pi(node.name, node.value);
13230          },
13231          10: function (node) {
13232            writer.doctype(node.value);
13233          },
13234          4: function (node) {
13235            writer.cdata(node.value);
13236          },
13237          11: function (node) {
13238            if (node = node.firstChild) {
13239              do {
13240                walk(node);
13241              } while (node = node.next);
13242            }
13243          }
13244        };
13245        writer.reset();
13246        var walk = function (node) {
13247          var handler = handlers[node.type];
13248          var name, isEmpty, attrs, attrName, attrValue, sortedAttrs, i, l, elementRule;
13249          if (!handler) {
13250            name = node.name;
13251            isEmpty = node.shortEnded;
13252            attrs = node.attributes;
13253            if (validate && attrs && attrs.length > 1) {
13254              sortedAttrs = [];
13255              sortedAttrs.map = {};
13256              elementRule = schema.getElementRule(node.name);
13257              if (elementRule) {
13258                for (i = 0, l = elementRule.attributesOrder.length; i < l; i++) {
13259                  attrName = elementRule.attributesOrder[i];
13260                  if (attrName in attrs.map) {
13261                    attrValue = attrs.map[attrName];
13262                    sortedAttrs.map[attrName] = attrValue;
13263                    sortedAttrs.push({
13264                      name: attrName,
13265                      value: attrValue
13266                    });
13267                  }
13268                }
13269                for (i = 0, l = attrs.length; i < l; i++) {
13270                  attrName = attrs[i].name;
13271                  if (!(attrName in sortedAttrs.map)) {
13272                    attrValue = attrs.map[attrName];
13273                    sortedAttrs.map[attrName] = attrValue;
13274                    sortedAttrs.push({
13275                      name: attrName,
13276                      value: attrValue
13277                    });
13278                  }
13279                }
13280                attrs = sortedAttrs;
13281              }
13282            }
13283            writer.start(node.name, attrs, isEmpty);
13284            if (!isEmpty) {
13285              if (node = node.firstChild) {
13286                do {
13287                  walk(node);
13288                } while (node = node.next);
13289              }
13290              writer.end(name);
13291            }
13292          } else {
13293            handler(node);
13294          }
13295        };
13296        if (node.type === 1 && !settings.inner) {
13297          walk(node);
13298        } else {
13299          handlers[11](node);
13300        }
13301        return writer.getContent();
13302      };
13303      return { serialize: serialize };
13304    };
13305
13306    var extractBase64DataUris = function (html) {
13307      var dataImageUri = /data:[^;]+;base64,([a-z0-9\+\/=]+)/gi;
13308      var chunks = [];
13309      var uris = {};
13310      var prefix = generate$1('img');
13311      var matches;
13312      var index = 0;
13313      var count = 0;
13314      while (matches = dataImageUri.exec(html)) {
13315        var uri = matches[0];
13316        var imageId = prefix + '_' + count++;
13317        uris[imageId] = uri;
13318        if (index < matches.index) {
13319          chunks.push(html.substr(index, matches.index - index));
13320        }
13321        chunks.push(imageId);
13322        index = matches.index + uri.length;
13323      }
13324      if (index === 0) {
13325        return {
13326          prefix: prefix,
13327          uris: uris,
13328          html: html
13329        };
13330      } else {
13331        if (index < html.length) {
13332          chunks.push(html.substr(index));
13333        }
13334        return {
13335          prefix: prefix,
13336          uris: uris,
13337          html: chunks.join('')
13338        };
13339      }
13340    };
13341    var restoreDataUris = function (html, result) {
13342      return html.replace(new RegExp(result.prefix + '_[0-9]+', 'g'), function (imageId) {
13343        return get(result.uris, imageId).getOr(imageId);
13344      });
13345    };
13346    var parseDataUri = function (uri) {
13347      var matches = /data:([^;]+);base64,([a-z0-9\+\/=]+)/i.exec(uri);
13348      if (matches) {
13349        return Optional.some({
13350          type: matches[1],
13351          data: decodeURIComponent(matches[2])
13352        });
13353      } else {
13354        return Optional.none();
13355      }
13356    };
13357
13358    var isValidPrefixAttrName = function (name) {
13359      return name.indexOf('data-') === 0 || name.indexOf('aria-') === 0;
13360    };
13361    var isInvalidUri = function (settings, uri) {
13362      if (settings.allow_html_data_urls) {
13363        return false;
13364      } else if (/^data:image\//i.test(uri)) {
13365        return settings.allow_svg_data_urls === false && /^data:image\/svg\+xml/i.test(uri);
13366      } else {
13367        return /^data:/i.test(uri);
13368      }
13369    };
13370    var findEndTagIndex = function (schema, html, startIndex) {
13371      var count = 1, index, matches;
13372      var shortEndedElements = schema.getShortEndedElements();
13373      var tokenRegExp = /<([!?\/])?([A-Za-z0-9\-_\:\.]+)((?:\s+[^"\'>]+(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>]*))*|\/|\s+)>/g;
13374      tokenRegExp.lastIndex = index = startIndex;
13375      while (matches = tokenRegExp.exec(html)) {
13376        index = tokenRegExp.lastIndex;
13377        if (matches[1] === '/') {
13378          count--;
13379        } else if (!matches[1]) {
13380          if (matches[2] in shortEndedElements) {
13381            continue;
13382          }
13383          count++;
13384        }
13385        if (count === 0) {
13386          break;
13387        }
13388      }
13389      return index;
13390    };
13391    var isConditionalComment = function (html, startIndex) {
13392      return /^\s*\[if [\w\W]+\]>.*<!\[endif\](--!?)?>/.test(html.substr(startIndex));
13393    };
13394    var findCommentEndIndex = function (html, isBogus, startIndex) {
13395      if (startIndex === void 0) {
13396        startIndex = 0;
13397      }
13398      var lcHtml = html.toLowerCase();
13399      if (lcHtml.indexOf('[if ', startIndex) !== -1 && isConditionalComment(lcHtml, startIndex)) {
13400        var endIfIndex = lcHtml.indexOf('[endif]', startIndex);
13401        return lcHtml.indexOf('>', endIfIndex);
13402      } else {
13403        if (isBogus) {
13404          var endIndex = lcHtml.indexOf('>', startIndex);
13405          return endIndex !== -1 ? endIndex : lcHtml.length;
13406        } else {
13407          var endCommentRegexp = /--!?>/;
13408          endCommentRegexp.lastIndex = startIndex;
13409          var match = endCommentRegexp.exec(html);
13410          return match ? match.index + match[0].length : lcHtml.length;
13411        }
13412      }
13413    };
13414    var checkBogusAttribute = function (regExp, attrString) {
13415      var matches = regExp.exec(attrString);
13416      if (matches) {
13417        var name_1 = matches[1];
13418        var value = matches[2];
13419        return typeof name_1 === 'string' && name_1.toLowerCase() === 'data-mce-bogus' ? value : null;
13420      } else {
13421        return null;
13422      }
13423    };
13424    function SaxParser(settings, schema) {
13425      if (schema === void 0) {
13426        schema = Schema();
13427      }
13428      var noop = function () {
13429      };
13430      settings = settings || {};
13431      if (settings.fix_self_closing !== false) {
13432        settings.fix_self_closing = true;
13433      }
13434      var comment = settings.comment ? settings.comment : noop;
13435      var cdata = settings.cdata ? settings.cdata : noop;
13436      var text = settings.text ? settings.text : noop;
13437      var start = settings.start ? settings.start : noop;
13438      var end = settings.end ? settings.end : noop;
13439      var pi = settings.pi ? settings.pi : noop;
13440      var doctype = settings.doctype ? settings.doctype : noop;
13441      var parseInternal = function (base64Extract, format) {
13442        if (format === void 0) {
13443          format = 'html';
13444        }
13445        var html = base64Extract.html;
13446        var matches, index = 0, value, endRegExp;
13447        var stack = [];
13448        var attrList, i, textData, name;
13449        var isInternalElement, isShortEnded;
13450        var elementRule, isValidElement, attr, attribsValue, validAttributesMap, validAttributePatterns;
13451        var attributesRequired, attributesDefault, attributesForced;
13452        var anyAttributesRequired, attrValue, idCount = 0;
13453        var decode = Entities.decode;
13454        var filteredUrlAttrs = Tools.makeMap('src,href,data,background,formaction,poster,xlink:href');
13455        var scriptUriRegExp = /((java|vb)script|mhtml):/i;
13456        var parsingMode = format === 'html' ? 0 : 1;
13457        var processEndTag = function (name) {
13458          var pos, i;
13459          pos = stack.length;
13460          while (pos--) {
13461            if (stack[pos].name === name) {
13462              break;
13463            }
13464          }
13465          if (pos >= 0) {
13466            for (i = stack.length - 1; i >= pos; i--) {
13467              name = stack[i];
13468              if (name.valid) {
13469                end(name.name);
13470              }
13471            }
13472            stack.length = pos;
13473          }
13474        };
13475        var processText = function (value, raw) {
13476          return text(restoreDataUris(value, base64Extract), raw);
13477        };
13478        var processComment = function (value) {
13479          if (value === '') {
13480            return;
13481          }
13482          if (value.charAt(0) === '>') {
13483            value = ' ' + value;
13484          }
13485          if (!settings.allow_conditional_comments && value.substr(0, 3).toLowerCase() === '[if') {
13486            value = ' ' + value;
13487          }
13488          comment(restoreDataUris(value, base64Extract));
13489        };
13490        var processAttr = function (value) {
13491          return get(base64Extract.uris, value).getOr(value);
13492        };
13493        var processMalformedComment = function (value, startIndex) {
13494          var startTag = value || '';
13495          var isBogus = !startsWith(startTag, '--');
13496          var endIndex = findCommentEndIndex(html, isBogus, startIndex);
13497          value = html.substr(startIndex, endIndex - startIndex);
13498          processComment(isBogus ? startTag + value : value);
13499          return endIndex + 1;
13500        };
13501        var parseAttribute = function (match, name, value, val2, val3) {
13502          var attrRule, i;
13503          var trimRegExp = /[\s\u0000-\u001F]+/g;
13504          name = name.toLowerCase();
13505          value = processAttr(name in fillAttrsMap ? name : decode(value || val2 || val3 || ''));
13506          if (validate && !isInternalElement && isValidPrefixAttrName(name) === false) {
13507            attrRule = validAttributesMap[name];
13508            if (!attrRule && validAttributePatterns) {
13509              i = validAttributePatterns.length;
13510              while (i--) {
13511                attrRule = validAttributePatterns[i];
13512                if (attrRule.pattern.test(name)) {
13513                  break;
13514                }
13515              }
13516              if (i === -1) {
13517                attrRule = null;
13518              }
13519            }
13520            if (!attrRule) {
13521              return;
13522            }
13523            if (attrRule.validValues && !(value in attrRule.validValues)) {
13524              return;
13525            }
13526          }
13527          if (filteredUrlAttrs[name] && !settings.allow_script_urls) {
13528            var uri = value.replace(trimRegExp, '');
13529            try {
13530              uri = decodeURIComponent(uri);
13531            } catch (ex) {
13532              uri = unescape(uri);
13533            }
13534            if (scriptUriRegExp.test(uri)) {
13535              return;
13536            }
13537            if (isInvalidUri(settings, uri)) {
13538              return;
13539            }
13540          }
13541          if (isInternalElement && (name in filteredUrlAttrs || name.indexOf('on') === 0)) {
13542            return;
13543          }
13544          attrList.map[name] = value;
13545          attrList.push({
13546            name: name,
13547            value: value
13548          });
13549        };
13550        var tokenRegExp = new RegExp('<(?:' + '(?:!--([\\w\\W]*?)--!?>)|' + '(?:!\\[CDATA\\[([\\w\\W]*?)\\]\\]>)|' + '(?:![Dd][Oo][Cc][Tt][Yy][Pp][Ee]([\\w\\W]*?)>)|' + '(?:!(--)?)|' + '(?:\\?([^\\s\\/<>]+) ?([\\w\\W]*?)[?/]>)|' + '(?:\\/([A-Za-z][A-Za-z0-9\\-_\\:\\.]*)>)|' + '(?:([A-Za-z][A-Za-z0-9\\-_\\:\\.]*)((?:\\s+[^"\'>]+(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>]*))*|\\/|\\s+)>)' + ')', 'g');
13551        var attrRegExp = /([\w:\-]+)(?:\s*=\s*(?:(?:\"((?:[^\"])*)\")|(?:\'((?:[^\'])*)\')|([^>\s]+)))?/g;
13552        var shortEndedElements = schema.getShortEndedElements();
13553        var selfClosing = settings.self_closing_elements || schema.getSelfClosingElements();
13554        var fillAttrsMap = schema.getBoolAttrs();
13555        var validate = settings.validate;
13556        var removeInternalElements = settings.remove_internals;
13557        var fixSelfClosing = settings.fix_self_closing;
13558        var specialElements = schema.getSpecialElements();
13559        var processHtml = html + '>';
13560        while (matches = tokenRegExp.exec(processHtml)) {
13561          var matchText = matches[0];
13562          if (index < matches.index) {
13563            processText(decode(html.substr(index, matches.index - index)));
13564          }
13565          if (value = matches[7]) {
13566            value = value.toLowerCase();
13567            if (value.charAt(0) === ':') {
13568              value = value.substr(1);
13569            }
13570            processEndTag(value);
13571          } else if (value = matches[8]) {
13572            if (matches.index + matchText.length > html.length) {
13573              processText(decode(html.substr(matches.index)));
13574              index = matches.index + matchText.length;
13575              continue;
13576            }
13577            value = value.toLowerCase();
13578            if (value.charAt(0) === ':') {
13579              value = value.substr(1);
13580            }
13581            isShortEnded = value in shortEndedElements;
13582            if (fixSelfClosing && selfClosing[value] && stack.length > 0 && stack[stack.length - 1].name === value) {
13583              processEndTag(value);
13584            }
13585            var bogusValue = checkBogusAttribute(attrRegExp, matches[9]);
13586            if (bogusValue !== null) {
13587              if (bogusValue === 'all') {
13588                index = findEndTagIndex(schema, html, tokenRegExp.lastIndex);
13589                tokenRegExp.lastIndex = index;
13590                continue;
13591              }
13592              isValidElement = false;
13593            }
13594            if (!validate || (elementRule = schema.getElementRule(value))) {
13595              isValidElement = true;
13596              if (validate) {
13597                validAttributesMap = elementRule.attributes;
13598                validAttributePatterns = elementRule.attributePatterns;
13599              }
13600              if (attribsValue = matches[9]) {
13601                isInternalElement = attribsValue.indexOf('data-mce-type') !== -1;
13602                if (isInternalElement && removeInternalElements) {
13603                  isValidElement = false;
13604                }
13605                attrList = [];
13606                attrList.map = {};
13607                attribsValue.replace(attrRegExp, parseAttribute);
13608              } else {
13609                attrList = [];
13610                attrList.map = {};
13611              }
13612              if (validate && !isInternalElement) {
13613                attributesRequired = elementRule.attributesRequired;
13614                attributesDefault = elementRule.attributesDefault;
13615                attributesForced = elementRule.attributesForced;
13616                anyAttributesRequired = elementRule.removeEmptyAttrs;
13617                if (anyAttributesRequired && !attrList.length) {
13618                  isValidElement = false;
13619                }
13620                if (attributesForced) {
13621                  i = attributesForced.length;
13622                  while (i--) {
13623                    attr = attributesForced[i];
13624                    name = attr.name;
13625                    attrValue = attr.value;
13626                    if (attrValue === '{$uid}') {
13627                      attrValue = 'mce_' + idCount++;
13628                    }
13629                    attrList.map[name] = attrValue;
13630                    attrList.push({
13631                      name: name,
13632                      value: attrValue
13633                    });
13634                  }
13635                }
13636                if (attributesDefault) {
13637                  i = attributesDefault.length;
13638                  while (i--) {
13639                    attr = attributesDefault[i];
13640                    name = attr.name;
13641                    if (!(name in attrList.map)) {
13642                      attrValue = attr.value;
13643                      if (attrValue === '{$uid}') {
13644                        attrValue = 'mce_' + idCount++;
13645                      }
13646                      attrList.map[name] = attrValue;
13647                      attrList.push({
13648                        name: name,
13649                        value: attrValue
13650                      });
13651                    }
13652                  }
13653                }
13654                if (attributesRequired) {
13655                  i = attributesRequired.length;
13656                  while (i--) {
13657                    if (attributesRequired[i] in attrList.map) {
13658                      break;
13659                    }
13660                  }
13661                  if (i === -1) {
13662                    isValidElement = false;
13663                  }
13664                }
13665                if (attr = attrList.map['data-mce-bogus']) {
13666                  if (attr === 'all') {
13667                    index = findEndTagIndex(schema, html, tokenRegExp.lastIndex);
13668                    tokenRegExp.lastIndex = index;
13669                    continue;
13670                  }
13671                  isValidElement = false;
13672                }
13673              }
13674              if (isValidElement) {
13675                start(value, attrList, isShortEnded);
13676              }
13677            } else {
13678              isValidElement = false;
13679            }
13680            if (endRegExp = specialElements[value]) {
13681              endRegExp.lastIndex = index = matches.index + matchText.length;
13682              if (matches = endRegExp.exec(html)) {
13683                if (isValidElement) {
13684                  textData = html.substr(index, matches.index - index);
13685                }
13686                index = matches.index + matches[0].length;
13687              } else {
13688                textData = html.substr(index);
13689                index = html.length;
13690              }
13691              if (isValidElement) {
13692                if (textData.length > 0) {
13693                  processText(textData, true);
13694                }
13695                end(value);
13696              }
13697              tokenRegExp.lastIndex = index;
13698              continue;
13699            }
13700            if (!isShortEnded) {
13701              if (!attribsValue || attribsValue.indexOf('/') !== attribsValue.length - 1) {
13702                stack.push({
13703                  name: value,
13704                  valid: isValidElement
13705                });
13706              } else if (isValidElement) {
13707                end(value);
13708              }
13709            }
13710          } else if (value = matches[1]) {
13711            processComment(value);
13712          } else if (value = matches[2]) {
13713            var isValidCdataSection = parsingMode === 1 || settings.preserve_cdata || stack.length > 0 && schema.isValidChild(stack[stack.length - 1].name, '#cdata');
13714            if (isValidCdataSection) {
13715              cdata(value);
13716            } else {
13717              index = processMalformedComment('', matches.index + 2);
13718              tokenRegExp.lastIndex = index;
13719              continue;
13720            }
13721          } else if (value = matches[3]) {
13722            doctype(value);
13723          } else if ((value = matches[4]) || matchText === '<!') {
13724            index = processMalformedComment(value, matches.index + matchText.length);
13725            tokenRegExp.lastIndex = index;
13726            continue;
13727          } else if (value = matches[5]) {
13728            if (parsingMode === 1) {
13729              pi(value, matches[6]);
13730            } else {
13731              index = processMalformedComment('?', matches.index + 2);
13732              tokenRegExp.lastIndex = index;
13733              continue;
13734            }
13735          }
13736          index = matches.index + matchText.length;
13737        }
13738        if (index < html.length) {
13739          processText(decode(html.substr(index)));
13740        }
13741        for (i = stack.length - 1; i >= 0; i--) {
13742          value = stack[i];
13743          if (value.valid) {
13744            end(value.name);
13745          }
13746        }
13747      };
13748      var parse = function (html, format) {
13749        if (format === void 0) {
13750          format = 'html';
13751        }
13752        parseInternal(extractBase64DataUris(html), format);
13753      };
13754      return { parse: parse };
13755    }
13756    (function (SaxParser) {
13757      SaxParser.findEndTag = findEndTagIndex;
13758    }(SaxParser || (SaxParser = {})));
13759    var SaxParser$1 = SaxParser;
13760
13761    var trimHtml = function (tempAttrs, html) {
13762      var trimContentRegExp = new RegExp(['\\s?(' + tempAttrs.join('|') + ')="[^"]+"'].join('|'), 'gi');
13763      return html.replace(trimContentRegExp, '');
13764    };
13765    var trimInternal = function (serializer, html) {
13766      var content = html;
13767      var bogusAllRegExp = /<(\w+) [^>]*data-mce-bogus="all"[^>]*>/g;
13768      var endTagIndex, index, matchLength, matches;
13769      var schema = serializer.schema;
13770      content = trimHtml(serializer.getTempAttrs(), content);
13771      var shortEndedElements = schema.getShortEndedElements();
13772      while (matches = bogusAllRegExp.exec(content)) {
13773        index = bogusAllRegExp.lastIndex;
13774        matchLength = matches[0].length;
13775        if (shortEndedElements[matches[1]]) {
13776          endTagIndex = index;
13777        } else {
13778          endTagIndex = SaxParser$1.findEndTag(schema, content, index);
13779        }
13780        content = content.substring(0, index - matchLength) + content.substring(endTagIndex);
13781        bogusAllRegExp.lastIndex = index - matchLength;
13782      }
13783      return trim$2(content);
13784    };
13785    var trimExternal = trimInternal;
13786
13787    var trimEmptyContents = function (editor, html) {
13788      var blockName = getForcedRootBlock(editor);
13789      var emptyRegExp = new RegExp('^(<' + blockName + '[^>]*>(&nbsp;|&#160;|\\s|\xA0|<br \\/>|)<\\/' + blockName + '>[\r\n]*|<br \\/>[\r\n]*)$');
13790      return html.replace(emptyRegExp, '');
13791    };
13792    var getContentFromBody = function (editor, args, format, body) {
13793      var content;
13794      args.format = format;
13795      args.get = true;
13796      args.getInner = true;
13797      if (!args.no_events) {
13798        editor.fire('BeforeGetContent', args);
13799      }
13800      if (args.format === 'raw') {
13801        content = Tools.trim(trimExternal(editor.serializer, body.innerHTML));
13802      } else if (args.format === 'text') {
13803        content = trim$2(body.innerText || body.textContent);
13804      } else if (args.format === 'tree') {
13805        return editor.serializer.serialize(body, args);
13806      } else {
13807        content = trimEmptyContents(editor, editor.serializer.serialize(body, args));
13808      }
13809      if (args.format !== 'text' && !isWsPreserveElement(SugarElement.fromDom(body))) {
13810        args.content = Tools.trim(content);
13811      } else {
13812        args.content = content;
13813      }
13814      if (!args.no_events) {
13815        editor.fire('GetContent', args);
13816      }
13817      return args.content;
13818    };
13819    var getContentInternal = function (editor, args, format) {
13820      return Optional.from(editor.getBody()).fold(constant(args.format === 'tree' ? new AstNode('body', 11) : ''), function (body) {
13821        return getContentFromBody(editor, args, format, body);
13822      });
13823    };
13824
13825    var each$7 = Tools.each;
13826    var ElementUtils = function (dom) {
13827      this.compare = function (node1, node2) {
13828        if (node1.nodeName !== node2.nodeName) {
13829          return false;
13830        }
13831        var getAttribs = function (node) {
13832          var attribs = {};
13833          each$7(dom.getAttribs(node), function (attr) {
13834            var name = attr.nodeName.toLowerCase();
13835            if (name.indexOf('_') !== 0 && name !== 'style' && name.indexOf('data-') !== 0) {
13836              attribs[name] = dom.getAttrib(node, name);
13837            }
13838          });
13839          return attribs;
13840        };
13841        var compareObjects = function (obj1, obj2) {
13842          var value, name;
13843          for (name in obj1) {
13844            if (obj1.hasOwnProperty(name)) {
13845              value = obj2[name];
13846              if (typeof value === 'undefined') {
13847                return false;
13848              }
13849              if (obj1[name] !== value) {
13850                return false;
13851              }
13852              delete obj2[name];
13853            }
13854          }
13855          for (name in obj2) {
13856            if (obj2.hasOwnProperty(name)) {
13857              return false;
13858            }
13859          }
13860          return true;
13861        };
13862        if (!compareObjects(getAttribs(node1), getAttribs(node2))) {
13863          return false;
13864        }
13865        if (!compareObjects(dom.parseStyle(dom.getAttrib(node1, 'style')), dom.parseStyle(dom.getAttrib(node2, 'style')))) {
13866          return false;
13867        }
13868        return !isBookmarkNode$1(node1) && !isBookmarkNode$1(node2);
13869      };
13870    };
13871
13872    var isChar = function (forward, predicate, pos) {
13873      return Optional.from(pos.container()).filter(isText$1).exists(function (text) {
13874        var delta = forward ? 0 : -1;
13875        return predicate(text.data.charAt(pos.offset() + delta));
13876      });
13877    };
13878    var isBeforeSpace = curry(isChar, true, isWhiteSpace$1);
13879    var isAfterSpace = curry(isChar, false, isWhiteSpace$1);
13880    var isEmptyText = function (pos) {
13881      var container = pos.container();
13882      return isText$1(container) && (container.data.length === 0 || isZwsp$1(container.data) && BookmarkManager$1.isBookmarkNode(container.parentNode));
13883    };
13884    var matchesElementPosition = function (before, predicate) {
13885      return function (pos) {
13886        return Optional.from(getChildNodeAtRelativeOffset(before ? 0 : -1, pos)).filter(predicate).isSome();
13887      };
13888    };
13889    var isImageBlock = function (node) {
13890      return isImg(node) && get$4(SugarElement.fromDom(node), 'display') === 'block';
13891    };
13892    var isCefNode = function (node) {
13893      return isContentEditableFalse(node) && !isBogusAll(node);
13894    };
13895    var isBeforeImageBlock = matchesElementPosition(true, isImageBlock);
13896    var isAfterImageBlock = matchesElementPosition(false, isImageBlock);
13897    var isBeforeMedia = matchesElementPosition(true, isMedia);
13898    var isAfterMedia = matchesElementPosition(false, isMedia);
13899    var isBeforeTable = matchesElementPosition(true, isTable);
13900    var isAfterTable = matchesElementPosition(false, isTable);
13901    var isBeforeContentEditableFalse = matchesElementPosition(true, isCefNode);
13902    var isAfterContentEditableFalse = matchesElementPosition(false, isCefNode);
13903
13904    var getLastChildren$1 = function (elm) {
13905      var children = [];
13906      var rawNode = elm.dom;
13907      while (rawNode) {
13908        children.push(SugarElement.fromDom(rawNode));
13909        rawNode = rawNode.lastChild;
13910      }
13911      return children;
13912    };
13913    var removeTrailingBr = function (elm) {
13914      var allBrs = descendants$1(elm, 'br');
13915      var brs = filter(getLastChildren$1(elm).slice(-1), isBr$1);
13916      if (allBrs.length === brs.length) {
13917        each(brs, remove);
13918      }
13919    };
13920    var fillWithPaddingBr = function (elm) {
13921      empty(elm);
13922      append(elm, SugarElement.fromHtml('<br data-mce-bogus="1">'));
13923    };
13924    var trimBlockTrailingBr = function (elm) {
13925      lastChild(elm).each(function (lastChild) {
13926        prevSibling(lastChild).each(function (lastChildPrevSibling) {
13927          if (isBlock(elm) && isBr$1(lastChild) && isBlock(lastChildPrevSibling)) {
13928            remove(lastChild);
13929          }
13930        });
13931      });
13932    };
13933
13934    var dropLast = function (xs) {
13935      return xs.slice(0, -1);
13936    };
13937    var parentsUntil$1 = function (start, root, predicate) {
13938      if (contains$2(root, start)) {
13939        return dropLast(parents(start, function (elm) {
13940          return predicate(elm) || eq$2(elm, root);
13941        }));
13942      } else {
13943        return [];
13944      }
13945    };
13946    var parents$1 = function (start, root) {
13947      return parentsUntil$1(start, root, never);
13948    };
13949    var parentsAndSelf = function (start, root) {
13950      return [start].concat(parents$1(start, root));
13951    };
13952
13953    var navigateIgnoreEmptyTextNodes = function (forward, root, from) {
13954      return navigateIgnore(forward, root, from, isEmptyText);
13955    };
13956    var getClosestBlock = function (root, pos) {
13957      return find(parentsAndSelf(SugarElement.fromDom(pos.container()), root), isBlock);
13958    };
13959    var isAtBeforeAfterBlockBoundary = function (forward, root, pos) {
13960      return navigateIgnoreEmptyTextNodes(forward, root.dom, pos).forall(function (newPos) {
13961        return getClosestBlock(root, pos).fold(function () {
13962          return isInSameBlock(newPos, pos, root.dom) === false;
13963        }, function (fromBlock) {
13964          return isInSameBlock(newPos, pos, root.dom) === false && contains$2(fromBlock, SugarElement.fromDom(newPos.container()));
13965        });
13966      });
13967    };
13968    var isAtBlockBoundary = function (forward, root, pos) {
13969      return getClosestBlock(root, pos).fold(function () {
13970        return navigateIgnoreEmptyTextNodes(forward, root.dom, pos).forall(function (newPos) {
13971          return isInSameBlock(newPos, pos, root.dom) === false;
13972        });
13973      }, function (parent) {
13974        return navigateIgnoreEmptyTextNodes(forward, parent.dom, pos).isNone();
13975      });
13976    };
13977    var isAtStartOfBlock = curry(isAtBlockBoundary, false);
13978    var isAtEndOfBlock = curry(isAtBlockBoundary, true);
13979    var isBeforeBlock = curry(isAtBeforeAfterBlockBoundary, false);
13980    var isAfterBlock = curry(isAtBeforeAfterBlockBoundary, true);
13981
13982    var isBr$5 = function (pos) {
13983      return getElementFromPosition(pos).exists(isBr$1);
13984    };
13985    var findBr = function (forward, root, pos) {
13986      var parentBlocks = filter(parentsAndSelf(SugarElement.fromDom(pos.container()), root), isBlock);
13987      var scope = head(parentBlocks).getOr(root);
13988      return fromPosition(forward, scope.dom, pos).filter(isBr$5);
13989    };
13990    var isBeforeBr = function (root, pos) {
13991      return getElementFromPosition(pos).exists(isBr$1) || findBr(true, root, pos).isSome();
13992    };
13993    var isAfterBr = function (root, pos) {
13994      return getElementFromPrevPosition(pos).exists(isBr$1) || findBr(false, root, pos).isSome();
13995    };
13996    var findPreviousBr = curry(findBr, false);
13997    var findNextBr = curry(findBr, true);
13998
13999    var isInMiddleOfText = function (pos) {
14000      return CaretPosition.isTextPosition(pos) && !pos.isAtStart() && !pos.isAt
14000End();
14001    };
14002    var getClosestBlock$1 = function (root, pos) {
14003      var parentBlocks = filter(parentsAndSelf(SugarElement.fromDom(pos.container()), root), isBlock);
14004      return head(parentBlocks).getOr(root);
14005    };
14006    var hasSpaceBefore = function (root, pos) {
14007      if (isInMiddleOfText(pos)) {
14008        return isAfterSpace(pos);
14009      } else {
14010        return isAfterSpace(pos) || prevPosition(getClosestBlock$1(root, pos).dom, pos).exists(isAfterSpace);
14011      }
14012    };
14013    var hasSpaceAfter = function (root, pos) {
14014      if (isInMiddleOfText(pos)) {
14015        return isBeforeSpace(pos);
14016      } else {
14017        return isBeforeSpace(pos) || nextPosition(getClosestBlock$1(root, pos).dom, pos).exists(isBeforeSpace);
14018      }
14019    };
14020    var isPreValue = function (value) {
14021      return contains([
14022        'pre',
14023        'pre-wrap'
14024      ], value);
14025    };
14026    var isInPre = function (pos) {
14027      return getElementFromPosition(pos).bind(function (elm) {
14028        return closest(elm, isElement);
14029      }).exists(function (elm) {
14030        return isPreValue(get$4(elm, 'white-space'));
14031      });
14032    };
14033    var isAtBeginningOfBody = function (root, pos) {
14034      return prevPosition(root.dom, pos).isNone();
14035    };
14036    var isAtEndOfBody = function (root, pos) {
14037      return nextPosition(root.dom, pos).isNone();
14038    };
14039    var isAtLineBoundary = function (root, pos) {
14040      return isAtBeginningOfBody(root, pos) || isAtEndOfBody(root, pos) || isAtStartOfBlock(root, pos) || isAtEndOfBlock(root, pos) || isAfterBr(root, pos) || isBeforeBr(root, pos);
14041    };
14042    var needsToHaveNbsp = function (root, pos) {
14043      if (isInPre(pos)) {
14044        return false;
14045      } else {
14046        return isAtLineBoundary(root, pos) || hasSpaceBefore(root, pos) || hasSpaceAfter(root, pos);
14047      }
14048    };
14049    var needsToBeNbspLeft = function (root, pos) {
14050      if (isInPre(pos)) {
14051        return false;
14052      } else {
14053        return isAtStartOfBlock(root, pos) || isBeforeBlock(root, pos) || isAfterBr(root, pos) || hasSpaceBefore(root, pos);
14054      }
14055    };
14056    var leanRight = function (pos) {
14057      var container = pos.container();
14058      var offset = pos.offset();
14059      if (isText$1(container) && offset < container.data.length) {
14060        return CaretPosition(container, offset + 1);
14061      } else {
14062        return pos;
14063      }
14064    };
14065    var needsToBeNbspRight = function (root, pos) {
14066      if (isInPre(pos)) {
14067        return false;
14068      } else {
14069        return isAtEndOfBlock(root, pos) || isAfterBlock(root, pos) || isBeforeBr(root, pos) || hasSpaceAfter(root, pos);
14070      }
14071    };
14072    var needsToBeNbsp = function (root, pos) {
14073      return needsToBeNbspLeft(root, pos) || needsToBeNbspRight(root, leanRight(pos));
14074    };
14075    var isNbspAt = function (text, offset) {
14076      return isNbsp(text.charAt(offset));
14077    };
14078    var hasNbsp = function (pos) {
14079      var container = pos.container();
14080      return isText$1(container) && contains$1(container.data, nbsp);
14081    };
14082    var normalizeNbspMiddle = function (text) {
14083      var chars = text.split('');
14084      return map(chars, function (chr, i) {
14085        if (isNbsp(chr) && i > 0 && i < chars.length - 1 && isContent$1(chars[i - 1]) && isContent$1(chars[i + 1])) {
14086          return ' ';
14087        } else {
14088          return chr;
14089        }
14090      }).join('');
14091    };
14092    var normalizeNbspAtStart = function (root, node) {
14093      var text = node.data;
14094      var firstPos = CaretPosition(node, 0);
14095      if (isNbspAt(text, 0) && !needsToBeNbsp(root, firstPos)) {
14096        node.data = ' ' + text.slice(1);
14097        return true;
14098      } else {
14099        return false;
14100      }
14101    };
14102    var normalizeNbspInMiddleOfTextNode = function (node) {
14103      var text = node.data;
14104      var newText = normalizeNbspMiddle(text);
14105      if (newText !== text) {
14106        node.data = newText;
14107        return true;
14108      } else {
14109        return false;
14110      }
14111    };
14112    var normalizeNbspAtEnd = function (root, node) {
14113      var text = node.data;
14114      var lastPos = CaretPosition(node, text.length - 1);
14115      if (isNbspAt(text, text.length - 1) && !needsToBeNbsp(root, lastPos)) {
14116        node.data = text.slice(0, -1) + ' ';
14117        return true;
14118      } else {
14119        return false;
14120      }
14121    };
14122    var normalizeNbsps = function (root, pos) {
14123      return Optional.some(pos).filter(hasNbsp).bind(function (pos) {
14124        var container = pos.container();
14125        var normalized = normalizeNbspAtStart(root, container) || normalizeNbspInMiddleOfTextNode(container) || normalizeNbspAtEnd(root, container);
14126        return normalized ? Optional.some(pos) : Optional.none();
14127      });
14128    };
14129    var normalizeNbspsInEditor = function (editor) {
14130      var root = SugarElement.fromDom(editor.getBody());
14131      if (editor.selection.isCollapsed()) {
14132        normalizeNbsps(root, CaretPosition.fromRangeStart(editor.selection.getRng())).each(function (pos) {
14133          editor.selection.setRng(pos.toRange());
14134        });
14135      }
14136    };
14137
14138    var normalizeContent = function (content, isStartOfContent, isEndOfContent) {
14139      var result = foldl(content, function (acc, c) {
14140        if (isWhiteSpace$1(c) || isNbsp(c)) {
14141          if (acc.previousCharIsSpace || acc.str === '' && isStartOfContent || acc.str.length === content.length - 1 && isEndOfContent) {
14142            return {
14143              previousCharIsSpace: false,
14144              str: acc.str + nbsp
14145            };
14146          } else {
14147            return {
14148              previousCharIsSpace: true,
14149              str: acc.str + ' '
14150            };
14151          }
14152        } else {
14153          return {
14154            previousCharIsSpace: false,
14155            str: acc.str + c
14156          };
14157        }
14158      }, {
14159        previousCharIsSpace: false,
14160        str: ''
14161      });
14162      return result.str;
14163    };
14164    var normalize$1 = function (node, offset, count) {
14165      if (count === 0) {
14166        return;
14167      }
14168      var elm = SugarElement.fromDom(node);
14169      var root = ancestor(elm, isBlock).getOr(elm);
14170      var whitespace = node.data.slice(offset, offset + count);
14171      var isEndOfContent = offset + count >= node.data.length && needsToBeNbspRight(root, CaretPosition$1(node, node.data.length));
14172      var isStartOfContent = offset === 0 && needsToBeNbspLeft(root, CaretPosition$1(node, 0));
14173      node.replaceData(offset, count, normalizeContent(whitespace, isStartOfContent, isEndOfContent));
14174    };
14175    var normalizeWhitespaceAfter = function (node, offset) {
14176      var content = node.data.slice(offset);
14177      var whitespaceCount = content.length - lTrim(content).length;
14178      return normalize$1(node, offset, whitespaceCount);
14179    };
14180    var normalizeWhitespaceBefore = function (node, offset) {
14181      var content = node.data.slice(0, offset);
14182      var whitespaceCount = content.length - rTrim(content).length;
14183      return normalize$1(node, offset - whitespaceCount, whitespaceCount);
14184    };
14185    var mergeTextNodes = function (prevNode, nextNode, normalizeWhitespace, mergeToPrev) {
14186      if (mergeToPrev === void 0) {
14187        mergeToPrev = true;
14188      }
14189      var whitespaceOffset = rTrim(prevNode.data).length;
14190      var newNode = mergeToPrev ? prevNode : nextNode;
14191      var removeNode = mergeToPrev ? nextNode : prevNode;
14192      if (mergeToPrev) {
14193        newNode.appendData(removeNode.data);
14194      } else {
14195        newNode.insertData(0, removeNode.data);
14196      }
14197      remove(SugarElement.fromDom(removeNode));
14198      if (normalizeWhitespace) {
14199        normalizeWhitespaceAfter(newNode, whitespaceOffset);
14200      }
14201      return newNode;
14202    };
14203
14204    var needsReposition = function (pos, elm) {
14205      var container = pos.container();
14206      var offset = pos.offset();
14207      return CaretPosition$1.isTextPosition(pos) === false && container === elm.parentNode && offset > CaretPosition$1.before(elm).offset();
14208    };
14209    var reposition = function (elm, pos) {
14210      return needsReposition(pos, elm) ? CaretPosition$1(pos.container(), pos.offset() - 1) : pos;
14211    };
14212    var beforeOrStartOf = function (node) {
14213      return isText$1(node) ? CaretPosition$1(node, 0) : CaretPosition$1.before(node);
14214    };
14215    var afterOrEndOf = function (node) {
14216      return isText$1(node) ? CaretPosition$1(node, node.data.length) : CaretPosition$1.after(node);
14217    };
14218    var getPreviousSiblingCaretPosition = function (elm) {
14219      if (isCaretCandidate(elm.previousSibling)) {
14220        return Optional.some(afterOrEndOf(elm.previousSibling));
14221      } else {
14222        return elm.previousSibling ? lastPositionIn(elm.previousSibling) : Optional.none();
14223      }
14224    };
14225    var getNextSiblingCaretPosition = function (elm) {
14226      if (isCaretCandidate(elm.nextSibling)) {
14227        return Optional.some(beforeOrStartOf(elm.nextSibling));
14228      } else {
14229        return elm.nextSibling ? firstPositionIn(elm.nextSibling) : Optional.none();
14230      }
14231    };
14232    var findCaretPositionBackwardsFromElm = function (rootElement, elm) {
14233      var startPosition = CaretPosition$1.before(elm.previousSibling ? elm.previousSibling : elm.parentNode);
14234      return prevPosition(rootElement, startPosition).fold(function () {
14235        return nextPosition(rootElement, CaretPosition$1.after(elm));
14236      }, Optional.some);
14237    };
14238    var findCaretPositionForwardsFromElm = function (rootElement, elm) {
14239      return nextPosition(rootElement, CaretPosition$1.after(elm)).fold(function () {
14240        return prevPosition(rootElement, CaretPosition$1.before(elm));
14241      }, Optional.some);
14242    };
14243    var findCaretPositionBackwards = function (rootElement, elm) {
14244      return getPreviousSiblingCaretPosition(elm).orThunk(function () {
14245        return getNextSiblingCaretPosition(elm);
14246      }).orThunk(function () {
14247        return findCaretPositionBackwardsFromElm(rootElement, elm);
14248      });
14249    };
14250    var findCaretPositionForward = function (rootElement, elm) {
14251      return getNextSiblingCaretPosition(elm).orThunk(function () {
14252        return getPreviousSiblingCaretPosition(elm);
14253      }).orThunk(function () {
14254        return findCaretPositionForwardsFromElm(rootElement, elm);
14255      });
14256    };
14257    var findCaretPosition$1 = function (forward, rootElement, elm) {
14258      return forward ? findCaretPositionForward(rootElement, elm) : findCaretPositionBackwards(rootElement, elm);
14259    };
14260    var findCaretPosOutsideElmAfterDelete = function (forward, rootElement, elm) {
14261      return findCaretPosition$1(forward, rootElement, elm).map(curry(reposition, elm));
14262    };
14263    var setSelection = function (editor, forward, pos) {
14264      pos.fold(function () {
14265        editor.focus();
14266      }, function (pos) {
14267        editor.selection.setRng(pos.toRange(), forward);
14268      });
14269    };
14270    var eqRawNode = function (rawNode) {
14271      return function (elm) {
14272        return elm.dom === rawNode;
14273      };
14274    };
14275    var isBlock$2 = function (editor, elm) {
14276      return elm && has(editor.schema.getBlockElements(), name(elm));
14277    };
14278    var paddEmptyBlock = function (elm) {
14279      if (isEmpty(elm)) {
14280        var br = SugarElement.fromHtml('<br data-mce-bogus="1">');
14281        empty(elm);
14282        append(elm, br);
14283        return Optional.some(CaretPosition$1.before(br.dom));
14284      } else {
14285        return Optional.none();
14286      }
14287    };
14288    var deleteNormalized = function (elm, afterDeletePosOpt, normalizeWhitespace) {
14289      var prevTextOpt = prevSibling(elm).filter(isText);
14290      var nextTextOpt = nextSibling(elm).filter(isText);
14291      remove(elm);
14292      return lift3(prevTextOpt, nextTextOpt, afterDeletePosOpt, function (prev, next, pos) {
14293        var prevNode = prev.dom, nextNode = next.dom;
14294        var offset = prevNode.data.length;
14295        mergeTextNodes(prevNode, nextNode, normalizeWhitespace);
14296        return pos.container() === nextNode ? CaretPosition$1(prevNode, offset) : pos;
14297      }).orThunk(function () {
14298        if (normalizeWhitespace) {
14299          prevTextOpt.each(function (elm) {
14300            return normalizeWhitespaceBefore(elm.dom, elm.dom.length);
14301          });
14302          nextTextOpt.each(function (elm) {
14303            return normalizeWhitespaceAfter(elm.dom, 0);
14304          });
14305        }
14306        return afterDeletePosOpt;
14307      });
14308    };
14309    var isInlineElement = function (editor, element) {
14310      return has(editor.schema.getTextInlineElements(), name(element));
14311    };
14312    var deleteElement = function (editor, forward, elm, moveCaret) {
14313      if (moveCaret === void 0) {
14314        moveCaret = true;
14315      }
14316      var afterDeletePos = findCaretPosOutsideElmAfterDelete(forward, editor.getBody(), elm.dom);
14317      var parentBlock = ancestor(elm, curry(isBlock$2, editor), eqRawNode(editor.getBody()));
14318      var normalizedAfterDeletePos = deleteNormalized(elm, afterDeletePos, isInlineElement(editor, elm));
14319      if (editor.dom.isEmpty(editor.getBody())) {
14320        editor.setContent('');
14321        editor.selection.setCursorLocation();
14322      } else {
14323        parentBlock.bind(paddEmptyBlock).fold(function () {
14324          if (moveCaret) {
14325            setSelection(editor, forward, normalizedAfterDeletePos);
14326          }
14327        }, function (paddPos) {
14328          if (moveCaret) {
14329            setSelection(editor, forward, Optional.some(paddPos));
14330          }
14331        });
14332      }
14333    };
14334
14335    var tableCellRng = function (start, end) {
14336      return {
14337        start: start,
14338        end: end
14339      };
14340    };
14341    var tableSelection = function (rng, table, cells) {
14342      return {
14343        rng: rng,
14344        table: table,
14345        cells: cells
14346      };
14347    };
14348    var deleteAction = Adt.generate([
14349      { removeTable: ['element'] },
14350      { emptyCells: ['cells'] },
14351      {
14352        deleteCellSelection: [
14353          'rng',
14354          'cell'
14355        ]
14356      }
14357    ]);
14358    var isRootFromElement = function (root) {
14359      return function (cur) {
14360        return eq$2(root, cur);
14361      };
14362    };
14363    var getClosestCell = function (container, isRoot) {
14364      return closest$1(SugarElement.fromDom(container), 'td,th', isRoot);
14365    };
14366    var getClosestTable = function (cell, isRoot) {
14367      return ancestor$1(cell, 'table', isRoot);
14368    };
14369    var isExpandedCellRng = function (cellRng) {
14370      return !eq$2(cellRng.start, cellRng.end);
14371    };
14372    var getTableFromCellRng = function (cellRng, isRoot) {
14373      return getClosestTable(cellRng.start, isRoot).bind(function (startParentTable) {
14374        return getClosestTable(cellRng.end, isRoot).bind(function (endParentTable) {
14375          return someIf(eq$2(startParentTable, endParentTable), startParentTable);
14376        });
14377      });
14378    };
14379    var isSingleCellTable = function (cellRng, isRoot) {
14380      return !isExpandedCellRng(cellRng) && getTableFromCellRng(cellRng, isRoot).exists(function (table) {
14381        var rows = table.dom.rows;
14382        return rows.length === 1 && rows[0].cells.length === 1;
14383      });
14384    };
14385    var getTableCells = function (table) {
14386      return descendants$1(table, 'td,th');
14387    };
14388    var getCellRng = function (rng, isRoot) {
14389      var startCell = getClosestCell(rng.startContainer, isRoot);
14390      var endCell = getClosestCell(rng.endContainer, isRoot);
14391      return lift2(startCell, endCell, tableCellRng);
14392    };
14393    var getCellRangeFromStartTable = function (cellRng, isRoot) {
14394      return getClosestTable(cellRng.start, isRoot).bind(function (table) {
14395        return last(getTableCells(table)).map(function (endCell) {
14396          return tableCellRng(cellRng.start, endCell);
14397        });
14398      });
14399    };
14400    var partialSelection = function (isRoot, rng) {
14401      var startCell = getClosestCell(rng.startContainer, isRoot);
14402      var endCell = getClosestCell(rng.endContainer, isRoot);
14403      return rng.collapsed ? Optional.none() : lift2(startCell, endCell, tableCellRng).fold(function () {
14404        return startCell.fold(function () {
14405          return endCell.bind(function (endCell) {
14406            return getClosestTable(endCell, isRoot).bind(function (table) {
14407              return head(getTableCells(table)).map(function (startCell) {
14408                return tableCellRng(startCell, endCell);
14409              });
14410            });
14411          });
14412        }, function (startCell) {
14413          return getClosestTable(startCell, isRoot).bind(function (table) {
14414            return last(getTableCells(table)).map(function (endCell) {
14415              return tableCellRng(startCell, endCell);
14416            });
14417          });
14418        });
14419      }, function (cellRng) {
14420        return isWithinSameTable(isRoot, cellRng) ? Optional.none() : getCellRangeFromStartTable(cellRng, isRoot);
14421      });
14422    };
14423    var isWithinSameTable = function (isRoot, cellRng) {
14424      return getTableFromCellRng(cellRng, isRoot).isSome();
14425    };
14426    var getTableSelectionFromCellRng = function (cellRng, isRoot) {
14427      return getTableFromCellRng(cellRng, isRoot).map(function (table) {
14428        return tableSelection(cellRng, table, getTableCells(table));
14429      });
14430    };
14431    var getTableSelection = function (optCellRng, rng, isRoot) {
14432      return optCellRng.filter(function (cellRng) {
14433        return isExpandedCellRng(cellRng) && isWithinSameTable(isRoot, cellRng);
14434      }).orThunk(function () {
14435        return partialSelection(isRoot, rng);
14436      }).bind(function (cRng) {
14437        return getTableSelectionFromCellRng(cRng, isRoot);
14438      });
14439    };
14440    var getCellIndex = function (cells, cell) {
14441      return findIndex(cells, function (x) {
14442        return eq$2(x, cell);
14443      });
14444    };
14445    var getSelectedCells = function (tableSelection) {
14446      return lift2(getCellIndex(tableSelection.cells, tableSelection.rng.start), getCellIndex(tableSelection.cells, tableSelection.rng.end
14446), function (startIndex, endIndex) {
14447        return tableSelection.cells.slice(startIndex, endIndex + 1);
14448      });
14449    };
14450    var isSingleCellTableContentSelected = function (optCellRng, rng, isRoot) {
14451      return optCellRng.filter(function (cellRng) {
14452        return isSingleCellTable(cellRng, isRoot) && hasAllContentsSelected(cellRng.start, rng);
14453      }).map(function (cellRng) {
14454        return cellRng.start;
14455      });
14456    };
14457    var getAction = function (tableSelection) {
14458      return getSelectedCells(tableSelection).map(function (selected) {
14459        var cells = tableSelection.cells;
14460        return selected.length === cells.length ? deleteAction.removeTable(tableSelection.table) : deleteAction.emptyCells(selected);
14461      });
14462    };
14463    var getActionFromRange = function (root, rng) {
14464      var isRoot = isRootFromElement(root);
14465      var optCellRng = getCellRng(rng, isRoot);
14466      return isSingleCellTableContentSelected(optCellRng, rng, isRoot).map(function (cell) {
14467        return deleteAction.deleteCellSelection(rng, cell);
14468      }).orThunk(function () {
14469        return getTableSelection(optCellRng, rng, isRoot).bind(getAction);
14470      });
14471    };
14472
14473    var freefallRtl = function (root) {
14474      var child = isComment(root) ? prevSibling(root) : lastChild(root);
14475      return child.bind(freefallRtl).orThunk(function () {
14476        return Optional.some(root);
14477      });
14478    };
14479    var emptyCells = function (editor, cells) {
14480      each(cells, fillWithPaddingBr);
14481      editor.selection.setCursorLocation(cells[0].dom, 0);
14482      return true;
14483    };
14484    var deleteCellContents = function (editor, rng, cell) {
14485      rng.deleteContents();
14486      var lastNode = freefallRtl(cell).getOr(cell);
14487      var lastBlock = SugarElement.fromDom(editor.dom.getParent(lastNode.dom, editor.dom.isBlock));
14488      if (isEmpty(lastBlock)) {
14489        fillWithPaddingBr(lastBlock);
14490        editor.selection.setCursorLocation(lastBlock.dom, 0);
14491      }
14492      if (!eq$2(cell, lastBlock)) {
14493        var additionalCleanupNodes = parent(lastBlock).is(cell) ? [] : siblings(lastBlock);
14494        each(additionalCleanupNodes.concat(children(cell)), function (node) {
14495          if (!eq$2(node, lastBlock) && !contains$2(node, lastBlock)) {
14496            remove(node);
14497          }
14498        });
14499      }
14500      return true;
14501    };
14502    var deleteTableElement = function (editor, table) {
14503      deleteElement(editor, false, table);
14504      return true;
14505    };
14506    var deleteCellRange = function (editor, rootElm, rng) {
14507      return getActionFromRange(rootElm, rng).map(function (action) {
14508        return action.fold(curry(deleteTableElement, editor), curry(emptyCells, editor), curry(deleteCellContents, editor));
14509      });
14510    };
14511    var deleteCaptionRange = function (editor, caption) {
14512      return emptyElement(editor, caption);
14513    };
14514    var deleteTableRange = function (editor, rootElm, rng, startElm) {
14515      return getParentCaption(rootElm, startElm).fold(function () {
14516        return deleteCellRange(editor, rootElm, rng);
14517      }, function (caption) {
14518        return deleteCaptionRange(editor, caption);
14519      }).getOr(false);
14520    };
14521    var deleteRange = function (editor, startElm) {
14522      var rootNode = SugarElement.fromDom(editor.getBody());
14523      var rng = editor.selection.getRng();
14524      var selectedCells = getCellsFromEditor(editor);
14525      return selectedCells.length !== 0 ? emptyCells(editor, selectedCells) : deleteTableRange(editor, rootNode, rng, startElm);
14526    };
14527    var getParentCell = function (rootElm, elm) {
14528      return find(parentsAndSelf(elm, rootElm), isTableCell$1);
14529    };
14530    var getParentCaption = function (rootElm, elm) {
14531      return find(parentsAndSelf(elm, rootElm), function (elm) {
14532        return name(elm) === 'caption';
14533      });
14534    };
14535    var deleteBetweenCells = function (editor, rootElm, forward, fromCell, from) {
14536      return navigate(forward, editor.getBody(), from).bind(function (to) {
14537        return getParentCell(rootElm, SugarElement.fromDom(to.getNode())).map(function (toCell) {
14538          return eq$2(toCell, fromCell) === false;
14539        });
14540      });
14541    };
14542    var emptyElement = function (editor, elm) {
14543      fillWithPaddingBr(elm);
14544      editor.selection.setCursorLocation(elm.dom, 0);
14545      return Optional.some(true);
14546    };
14547    var isDeleteOfLastCharPos = function (fromCaption, forward, from, to) {
14548      return firstPositionIn(fromCaption.dom).bind(function (first) {
14549        return lastPositionIn(fromCaption.dom).map(function (last) {
14550          return forward ? from.isEqual(first) && to.isEqual(last) : from.isEqual(last) && to.isEqual(first);
14551        });
14552      }).getOr(true);
14553    };
14554    var emptyCaretCaption = function (editor, elm) {
14555      return emptyElement(editor, elm);
14556    };
14557    var validateCaretCaption = function (rootElm, fromCaption, to) {
14558      return getParentCaption(rootElm, SugarElement.fromDom(to.getNode())).map(function (toCaption) {
14559        return eq$2(toCaption, fromCaption) === false;
14560      });
14561    };
14562    var deleteCaretInsideCaption = function (editor, rootElm, forward, fromCaption, from) {
14563      return navigate(forward, editor.getBody(), from).bind(function (to) {
14564        return isDeleteOfLastCharPos(fromCaption, forward, from, to) ? emptyCaretCaption(editor, fromCaption) : validateCaretCaption(rootElm, fromCaption, to);
14565      }).or(Optional.some(true));
14566    };
14567    var deleteCaretCells = function (editor, forward, rootElm, startElm) {
14568      var from = CaretPosition$1.fromRangeStart(editor.selection.getRng());
14569      return getParentCell(rootElm, startElm).bind(function (fromCell) {
14570        return isEmpty(fromCell) ? emptyElement(editor, fromCell) : deleteBetweenCells(editor, rootElm, forward, fromCell, from);
14571      }).getOr(false);
14572    };
14573    var deleteCaretCaption = function (editor, forward, rootElm, fromCaption) {
14574      var from = CaretPosition$1.fromRangeStart(editor.selection.getRng());
14575      return isEmpty(fromCaption) ? emptyElement(editor, fromCaption) : deleteCaretInsideCaption(editor, rootElm, forward, fromCaption, from);
14576    };
14577    var isNearTable = function (forward, pos) {
14578      return forward ? isBeforeTable(pos) : isAfterTable(pos);
14579    };
14580    var isBeforeOrAfterTable = function (editor, forward) {
14581      var fromPos = CaretPosition$1.fromRangeStart(editor.selection.getRng());
14582      return isNearTable(forward, fromPos) || fromPosition(forward, editor.getBody(), fromPos).exists(function (pos) {
14583        return isNearTable(forward, pos);
14584      });
14585    };
14586    var deleteCaret = function (editor, forward, startElm) {
14587      var rootElm = SugarElement.fromDom(editor.getBody());
14588      return getParentCaption(rootElm, startElm).fold(function () {
14589        return deleteCaretCells(editor, forward, rootElm, startElm) || isBeforeOrAfterTable(editor, forward);
14590      }, function (fromCaption) {
14591        return deleteCaretCaption(editor, forward, rootElm, fromCaption).getOr(false);
14592      });
14593    };
14594    var backspaceDelete = function (editor, forward) {
14595      var startElm = SugarElement.fromDom(editor.selection.getStart(true));
14596      var cells = getCellsFromEditor(editor);
14597      return editor.selection.isCollapsed() && cells.length === 0 ? deleteCaret(editor, forward, startElm) : deleteRange(editor, startElm);
14598    };
14599
14600    var createRange$1 = function (sc, so, ec, eo) {
14601      var rng = document.createRange();
14602      rng.setStart(sc, so);
14603      rng.setEnd(ec, eo);
14604      return rng;
14605    };
14606    var normalizeBlockSelectionRange = function (rng) {
14607      var startPos = CaretPosition$1.fromRangeStart(rng);
14608      var endPos = CaretPosition$1.fromRangeEnd(rng);
14609      var rootNode = rng.commonAncestorContainer;
14610      return fromPosition(false, rootNode, endPos).map(function (newEndPos) {
14611        if (!isInSameBlock(startPos, endPos, rootNode) && isInSameBlock(startPos, newEndPos, rootNode)) {
14612          return createRange$1(startPos.container(), startPos.offset(), newEndPos.container(), newEndPos.offset());
14613        } else {
14614          return rng;
14615        }
14616      }).getOr(rng);
14617    };
14618    var normalize$2 = function (rng) {
14619      return rng.collapsed ? rng : normalizeBlockSelectionRange(rng);
14620    };
14621
14622    var hasOnlyOneChild = function (node) {
14623      return node.firstChild && node.firstChild === node.lastChild;
14624    };
14625    var isPaddingNode = function (node) {
14626      return node.name === 'br' || node.value === nbsp;
14627    };
14628    var isPaddedEmptyBlock = function (schema, node) {
14629      var blockElements = schema.getBlockElements();
14630      return blockElements[node.name] && hasOnlyOneChild(node) && isPaddingNode(node.firstChild);
14631    };
14632    var isEmptyFragmentElement = function (schema, node) {
14633      var nonEmptyElements = schema.getNonEmptyElements();
14634      return node && (node.isEmpty(nonEmptyElements) || isPaddedEmptyBlock(schema, node));
14635    };
14636    var isListFragment = function (schema, fragment) {
14637      var firstChild = fragment.firstChild;
14638      var lastChild = fragment.lastChild;
14639      if (firstChild && firstChild.name === 'meta') {
14640        firstChild = firstChild.next;
14641      }
14642      if (lastChild && lastChild.attr('id') === 'mce_marker') {
14643        lastChild = lastChild.prev;
14644      }
14645      if (isEmptyFragmentElement(schema, lastChild)) {
14646        lastChild = lastChild.prev;
14647      }
14648      if (!firstChild || firstChild !== lastChild) {
14649        return false;
14650      }
14651      return firstChild.name === 'ul' || firstChild.name === 'ol';
14652    };
14653    var cleanupDomFragment = function (domFragment) {
14654      var firstChild = domFragment.firstChild;
14655      var lastChild = domFragment.lastChild;
14656      if (firstChild && firstChild.nodeName === 'META') {
14657        firstChild.parentNode.removeChild(firstChild);
14658      }
14659      if (lastChild && lastChild.id === 'mce_marker') {
14660        lastChild.parentNode.removeChild(lastChild);
14661      }
14662      return domFragment;
14663    };
14664    var toDomFragment = function (dom, serializer, fragment) {
14665      var html = serializer.serialize(fragment);
14666      var domFragment = dom.createFragment(html);
14667      return cleanupDomFragment(domFragment);
14668    };
14669    var listItems$1 = function (elm) {
14670      return Tools.grep(elm.childNodes, function (child) {
14671        return child.nodeName === 'LI';
14672      });
14673    };
14674    var isPadding = function (node) {
14675      return node.data === nbsp || isBr(node);
14676    };
14677    var isListItemPadded = function (node) {
14678      return node && node.firstChild && node.firstChild === node.lastChild && isPadding(node.firstChild);
14679    };
14680    var isEmptyOrPadded = function (elm) {
14681      return !elm.firstChild || isListItemPadded(elm);
14682    };
14683    var trimListItems = function (elms) {
14684      return elms.length > 0 && isEmptyOrPadded(elms[elms.length - 1]) ? elms.slice(0, -1) : elms;
14685    };
14686    var getParentLi = function (dom, node) {
14687      var parentBlock = dom.getParent(node, dom.isBlock);
14688      return parentBlock && parentBlock.nodeName === 'LI' ? parentBlock : null;
14689    };
14690    var isParentBlockLi = function (dom, node) {
14691      return !!getParentLi(dom, node);
14692    };
14693    var getSplit = function (parentNode, rng) {
14694      var beforeRng = rng.cloneRange();
14695      var afterRng = rng.cloneRange();
14696      beforeRng.setStartBefore(parentNode);
14697      afterRng.setEndAfter(parentNode);
14698      return [
14699        beforeRng.cloneContents(),
14700        afterRng.cloneContents()
14701      ];
14702    };
14703    var findFirstIn = function (node, rootNode) {
14704      var caretPos = CaretPosition$1.before(node);
14705      var caretWalker = CaretWalker(rootNode);
14706      var newCaretPos = caretWalker.next(caretPos);
14707      return newCaretPos ? newCaretPos.toRange() : null;
14708    };
14709    var findLastOf = function (node, rootNode) {
14710      var caretPos = CaretPosition$1.after(node);
14711      var caretWalker = CaretWalker(rootNode);
14712      var newCaretPos = caretWalker.prev(caretPos);
14713      return newCaretPos ? newCaretPos.toRange() : null;
14714    };
14715    var insertMiddle = function (target, elms, rootNode, rng) {
14716      var parts = getSplit(target, rng);
14717      var parentElm = target.parentNode;
14718      parentElm.insertBefore(parts[0], target);
14719      Tools.each(elms, function (li) {
14720        parentElm.insertBefore(li, target);
14721      });
14722      parentElm.insertBefore(parts[1], target);
14723      parentElm.removeChild(target);
14724      return findLastOf(elms[elms.length - 1], rootNode);
14725    };
14726    var insertBefore = function (target, elms, rootNode) {
14727      var parentElm = target.parentNode;
14728      Tools.each(elms, function (elm) {
14729        parentElm.insertBefore(elm, target);
14730      });
14731      return findFirstIn(target, rootNode);
14732    };
14733    var insertAfter = function (target, elms, rootNode, dom) {
14734      dom.insertAfter(elms.reverse(), target);
14735      return findLastOf(elms[0], rootNode);
14736    };
14737    var insertAtCaret = function (serializer, dom, rng, fragment) {
14738      var domFragment = toDomFragment(dom, serializer, fragment);
14739      var liTarget = getParentLi(dom, rng.startContainer);
14740      var liElms = trimListItems(listItems$1(domFragment.firstChild));
14741      var BEGINNING = 1, END = 2;
14742      var rootNode = dom.getRoot();
14743      var isAt = function (location) {
14744        var caretPos = CaretPosition$1.fromRangeStart(rng);
14745        var caretWalker = CaretWalker(dom.getRoot());
14746        var newPos = location === BEGINNING ? caretWalker.prev(caretPos) : caretWalker.next(caretPos);
14747        return newPos ? getParentLi(dom, newPos.getNode()) !== liTarget : true;
14748      };
14749      if (isAt(BEGINNING)) {
14750        return insertBefore(liTarget, liElms, rootNode);
14751      } else if (isAt(END)) {
14752        return insertAfter(liTarget, liElms, rootNode, dom);
14753      }
14754      return insertMiddle(liTarget, liElms, rootNode, rng);
14755    };
14756
14757    var trimOrPadLeftRight = function (dom, rng, html) {
14758      var root = SugarElement.fromDom(dom.getRoot());
14759      if (needsToBeNbspLeft(root, CaretPosition$1.fromRangeStart(rng))) {
14760        html = html.replace(/^ /, '&nbsp;');
14761      } else {
14762        html = html.replace(/^&nbsp;/, ' ');
14763      }
14764      if (needsToBeNbspRight(root, CaretPosition$1.fromRangeEnd(rng))) {
14765        html = html.replace(/(&nbsp;| )(<br( \/)>)?$/, '&nbsp;');
14766      } else {
14767        html = html.replace(/&nbsp;(<br( \/)?>)?$/, ' ');
14768      }
14769      return html;
14770    };
14771
14772    var isTableCell$4 = isTableCell;
14773    var isTableCellContentSelected = function (dom, rng, cell) {
14774      if (cell !== null) {
14775        var endCell = dom.getParent(rng.endContainer, isTableCell$4);
14776        return cell === endCell && hasAllContentsSelected(SugarElement.fromDom(cell), rng);
14777      } else {
14778        return false;
14779      }
14780    };
14781    var validInsertion = function (editor, value, parentNode) {
14782      if (parentNode.getAttribute('data-mce-bogus') === 'all') {
14783        parentNode.parentNode.insertBefore(editor.dom.createFragment(value), parentNode);
14784      } else {
14785        var node = parentNode.firstChild;
14786        var node2 = parentNode.lastChild;
14787        if (!node || node === node2 && node.nodeName === 'BR') {
14788          editor.dom.setHTML(parentNode, value);
14789        } else {
14790          editor.selection.setContent(value);
14791        }
14792      }
14793    };
14794    var trimBrsFromTableCell = function (dom, elm) {
14795      Optional.from(dom.getParent(elm, 'td,th')).map(SugarElement.fromDom).each(trimBlockTrailingBr);
14796    };
14797    var reduceInlineTextElements = function (editor, merge) {
14798      var textInlineElements = editor.schema.getTextInlineElements();
14799      var dom = editor.dom;
14800      if (merge) {
14801        var root_1 = editor.getBody(), elementUtils_1 = new ElementUtils(dom);
14802        Tools.each(dom.select('*[data-mce-fragment]'), function (node) {
14803          for (var testNode = node.parentNode; testNode && testNode !== root_1; testNode = testNode.parentNode) {
14804            if (textInlineElements[node.nodeName.toLowerCase()] && elementUtils_1.compare(testNode, node)) {
14805              dom.remove(node, true);
14806            }
14807          }
14808        });
14809      }
14810    };
14811    var markFragmentElements = function (fragment) {
14812      var node = fragment;
14813      while (node = node.walk()) {
14814        if (node.type === 1) {
14815          node.attr('data-mce-fragment', '1');
14816        }
14817      }
14818    };
14819    var unmarkFragmentElements = function (elm) {
14820      Tools.each(elm.getElementsByTagName('*'), function (elm) {
14821        elm.removeAttribute('data-mce-fragment');
14822      });
14823    };
14824    var isPartOfFragment = function (node) {
14825      return !!node.getAttribute('data-mce-fragment');
14826    };
14827    var canHaveChildren = function (editor, node) {
14828      return node && !editor.schema.getShortEndedElements()[node.nodeName];
14829    };
14830    var moveSelectionToMarker = function (editor, marker) {
14831      var nextRng;
14832      var dom = editor.dom, selection = editor.selection;
14833      var node2;
14834      var getContentEditableFalseParent = function (node) {
14835        var root = editor.getBody();
14836        for (; node && node !== root; node = node.parentNode) {
14837          if (dom.getContentEditable(node) === 'false') {
14838            return node;
14839          }
14840        }
14841        return null;
14842      };
14843      if (!marker) {
14844        return;
14845      }
14846      selection.scrollIntoView(marker);
14847      var parentEditableFalseElm = getContentEditableFalseParent(marker);
14848      if (parentEditableFalseElm) {
14849        dom.remove(marker);
14850        selection.select(parentEditableFalseElm);
14851        return;
14852      }
14853      var rng = dom.createRng();
14854      var node = marker.previousSibling;
14855      if (node && node.nodeType === 3) {
14856        rng.setStart(node, node.nodeValue.length);
14857        if (!Env.ie) {
14858          node2 = marker.nextSibling;
14859          if (node2 && node2.nodeType === 3) {
14860            node.appendData(node2.data);
14861            node2.parentNode.removeChild(node2);
14862          }
14863        }
14864      } else {
14865        rng.setStartBefore(marker);
14866        rng.setEndBefore(marker);
14867      }
14868      var findNextCaretRng = function (rng) {
14869        var caretPos = CaretPosition$1.fromRangeStart(rng);
14870        var caretWalker = CaretWalker(editor.getBody());
14871        caretPos = caretWalker.next(caretPos);
14872        if (caretPos) {
14873          return caretPos.toRange();
14874        }
14875      };
14876      var parentBlock = dom.getParent(marker, dom.isBlock);
14877      dom.remove(marker);
14878      if (parentBlock && dom.isEmpty(parentBlock)) {
14879        editor.$(parentBlock).empty();
14880        rng.setStart(parentBlock, 0);
14881        rng.setEnd(parentBlock, 0);
14882        if (!isTableCell$4(parentBlock) && !isPartOfFragment(parentBlock) && (nextRng = findNextCaretRng(rng))) {
14883          rng = nextRng;
14884          dom.remove(parentBlock);
14885        } else {
14886          dom.add(parentBlock, dom.create('br', { 'data-mce-bogus': '1' }));
14887        }
14888      }
14889      selection.setRng(rng);
14890    };
14891    var deleteSelectedContent = function (editor) {
14892      var dom = editor.dom;
14893      var rng = normalize$2(editor.selection.getRng());
14894      editor.selection.setRng(rng);
14895      var startCell = dom.getParent(rng.startContainer, isTableCell$4);
14896      if (isTableCellContentSelected(dom, rng, startCell)) {
14897        deleteCellContents(editor, rng, SugarElement.fromDom(startCell));
14898      } else {
14899        editor.getDoc().execCommand('Delete', false, null);
14900      }
14901    };
14902    var insertHtmlAtCaret = function (editor, value, details) {
14903      var parentNode, rootNode, args;
14904      var marker, rng, node;
14905      var selection = editor.selection, dom = editor.dom;
14906      if (/^ | $/.test(value)) {
14907        value = trimOrPadLeftRight(dom, selection.getRng(), value);
14908      }
14909      var parser = editor.parser;
14910      var merge = details.merge;
14911      var serializer = HtmlSerializer({ validate: shouldValidate(editor) }, editor.schema);
14912      var bookmarkHtml = '<span id="mce_marker" data-mce-type="bookmark">
14912&#xFEFF;</span>';
14913      args = {
14914        content: value,
14915        format: 'html',
14916        selection: true,
14917        paste: details.paste
14918      };
14919      args = editor.fire('BeforeSetContent', args);
14920      if (args.isDefaultPrevented()) {
14921        editor.fire('SetContent', {
14922          content: args.content,
14923          format: 'html',
14924          selection: true,
14925          paste: details.paste
14926        });
14927        return;
14928      }
14929      value = args.content;
14930      if (value.indexOf('{$caret}') === -1) {
14931        value += '{$caret}';
14932      }
14933      value = value.replace(/\{\$caret\}/, bookmarkHtml);
14934      rng = selection.getRng();
14935      var caretElement = rng.startContainer || (rng.parentElement ? rng.parentElement() : null);
14936      var body = editor.getBody();
14937      if (caretElement === body && selection.isCollapsed()) {
14938        if (dom.isBlock(body.firstChild) && canHaveChildren(editor, body.firstChild) && dom.isEmpty(body.firstChild)) {
14939          rng = dom.createRng();
14940          rng.setStart(body.firstChild, 0);
14941          rng.setEnd(body.firstChild, 0);
14942          selection.setRng(rng);
14943        }
14944      }
14945      if (!selection.isCollapsed()) {
14946        deleteSelectedContent(editor);
14947      }
14948      parentNode = selection.getNode();
14949      var parserArgs = {
14950        context: parentNode.nodeName.toLowerCase(),
14951        data: details.data,
14952        insert: true
14953      };
14954      var fragment = parser.parse(value, parserArgs);
14955      if (details.paste === true && isListFragment(editor.schema, fragment) && isParentBlockLi(dom, parentNode)) {
14956        rng = insertAtCaret(serializer, dom, selection.getRng(), fragment);
14957        selection.setRng(rng);
14958        editor.fire('SetContent', args);
14959        return;
14960      }
14961      markFragmentElements(fragment);
14962      node = fragment.lastChild;
14963      if (node.attr('id') === 'mce_marker') {
14964        marker = node;
14965        for (node = node.prev; node; node = node.walk(true)) {
14966          if (node.type === 3 || !dom.isBlock(node.name)) {
14967            if (editor.schema.isValidChild(node.parent.name, 'span')) {
14968              node.parent.insert(marker, node, node.name === 'br');
14969            }
14970            break;
14971          }
14972        }
14973      }
14974      editor._selectionOverrides.showBlockCaretContainer(parentNode);
14975      if (!parserArgs.invalid) {
14976        value = serializer.serialize(fragment);
14977        validInsertion(editor, value, parentNode);
14978      } else {
14979        editor.selection.setContent(bookmarkHtml);
14980        parentNode = selection.getNode();
14981        rootNode = editor.getBody();
14982        if (parentNode.nodeType === 9) {
14983          parentNode = node = rootNode;
14984        } else {
14985          node = parentNode;
14986        }
14987        while (node !== rootNode) {
14988          parentNode = node;
14989          node = node.parentNode;
14990        }
14991        value = parentNode === rootNode ? rootNode.innerHTML : dom.getOuterHTML(parentNode);
14992        value = serializer.serialize(parser.parse(value.replace(/<span (id="mce_marker"|id=mce_marker).+?<\/span>/i, function () {
14993          return serializer.serialize(fragment);
14994        })));
14995        if (parentNode === rootNode) {
14996          dom.setHTML(rootNode, value);
14997        } else {
14998          dom.setOuterHTML(parentNode, value);
14999        }
15000      }
15001      reduceInlineTextElements(editor, merge);
15002      moveSelectionToMarker(editor, dom.get('mce_marker'));
15003      unmarkFragmentElements(editor.getBody());
15004      trimBrsFromTableCell(dom, selection.getStart());
15005      editor.fire('SetContent', args);
15006      editor.addVisual();
15007    };
15008
15009    var traverse = function (node, fn) {
15010      fn(node);
15011      if (node.firstChild) {
15012        traverse(node.firstChild, fn);
15013      }
15014      if (node.next) {
15015        traverse(node.next, fn);
15016      }
15017    };
15018    var findMatchingNodes = function (nodeFilters, attributeFilters, node) {
15019      var nodeMatches = {};
15020      var attrMatches = {};
15021      var matches = [];
15022      if (node.firstChild) {
15023        traverse(node.firstChild, function (node) {
15024          each(nodeFilters, function (filter) {
15025            if (filter.name === node.name) {
15026              if (nodeMatches[filter.name]) {
15027                nodeMatches[filter.name].nodes.push(node);
15028              } else {
15029                nodeMatches[filter.name] = {
15030                  filter: filter,
15031                  nodes: [node]
15032                };
15033              }
15034            }
15035          });
15036          each(attributeFilters, function (filter) {
15037            if (typeof node.attr(filter.name) === 'string') {
15038              if (attrMatches[filter.name]) {
15039                attrMatches[filter.name].nodes.push(node);
15040              } else {
15041                attrMatches[filter.name] = {
15042                  filter: filter,
15043                  nodes: [node]
15044                };
15045              }
15046            }
15047          });
15048        });
15049      }
15050      for (var name_1 in nodeMatches) {
15051        if (nodeMatches.hasOwnProperty(name_1)) {
15052          matches.push(nodeMatches[name_1]);
15053        }
15054      }
15055      for (var name_2 in attrMatches) {
15056        if (attrMatches.hasOwnProperty(name_2)) {
15057          matches.push(attrMatches[name_2]);
15058        }
15059      }
15060      return matches;
15061    };
15062    var filter$3 = function (nodeFilters, attributeFilters, node) {
15063      var matches = findMatchingNodes(nodeFilters, attributeFilters, node);
15064      each(matches, function (match) {
15065        each(match.filter.callbacks, function (callback) {
15066          callback(match.nodes, match.filter.name, {});
15067        });
15068      });
15069    };
15070
15071    var defaultFormat = 'html';
15072    var isTreeNode = function (content) {
15073      return content instanceof AstNode;
15074    };
15075    var moveSelection = function (editor) {
15076      if (hasFocus$1(editor)) {
15077        firstPositionIn(editor.getBody()).each(function (pos) {
15078          var node = pos.getNode();
15079          var caretPos = isTable(node) ? firstPositionIn(node).getOr(pos) : pos;
15080          editor.selection.setRng(caretPos.toRange());
15081        });
15082      }
15083    };
15084    var setEditorHtml = function (editor, html) {
15085      editor.dom.setHTML(editor.getBody(), html);
15086      moveSelection(editor);
15087    };
15088    var setContentString = function (editor, body, content, args) {
15089      var forcedRootBlockName, padd;
15090      if (content.length === 0 || /^\s+$/.test(content)) {
15091        padd = '<br data-mce-bogus="1">';
15092        if (body.nodeName === 'TABLE') {
15093          content = '<tr><td>' + padd + '</td></tr>';
15094        } else if (/^(UL|OL)$/.test(body.nodeName)) {
15095          content = '<li>' + padd + '</li>';
15096        }
15097        forcedRootBlockName = getForcedRootBlock(editor);
15098        if (forcedRootBlockName && editor.schema.isValidChild(body.nodeName.toLowerCase(), forcedRootBlockName.toLowerCase())) {
15099          content = padd;
15100          content = editor.dom.createHTML(forcedRootBlockName, getForcedRootBlockAttrs(editor), content);
15101        } else if (!content) {
15102          content = '<br data-mce-bogus="1">';
15103        }
15104        setEditorHtml(editor, content);
15105        editor.fire('SetContent', args);
15106      } else {
15107        if (args.format !== 'raw') {
15108          content = HtmlSerializer({ validate: editor.validate }, editor.schema).serialize(editor.parser.parse(content, {
15109            isRootContent: true,
15110            insert: true
15111          }));
15112        }
15113        args.content = isWsPreserveElement(SugarElement.fromDom(body)) ? content : Tools.trim(content);
15114        setEditorHtml(editor, args.content);
15115        if (!args.no_events) {
15116          editor.fire('SetContent', args);
15117        }
15118      }
15119      return args.content;
15120    };
15121    var setContentTree = function (editor, body, content, args) {
15122      filter$3(editor.parser.getNodeFilters(), editor.parser.getAttributeFilters(), content);
15123      var html = HtmlSerializer({ validate: editor.validate }, editor.schema).serialize(content);
15124      args.content = isWsPreserveElement(SugarElement.fromDom(body)) ? html : Tools.trim(html);
15125      setEditorHtml(editor, args.content);
15126      if (!args.no_events) {
15127        editor.fire('SetContent', args);
15128      }
15129      return content;
15130    };
15131    var setContentInternal = function (editor, content, args) {
15132      args.format = args.format ? args.format : defaultFormat;
15133      args.set = true;
15134      args.content = isTreeNode(content) ? '' : content;
15135      if (!isTreeNode(content) && !args.no_events) {
15136        editor.fire('BeforeSetContent', args);
15137        content = args.content;
15138      }
15139      return Optional.from(editor.getBody()).fold(constant(content), function (body) {
15140        return isTreeNode(content) ? setContentTree(editor, body, content, args) : setContentString(editor, body, content, args);
15141      });
15142    };
15143
15144    var isEq$2 = isEq;
15145    var matchesUnInheritedFormatSelector = function (ed, node, name) {
15146      var formatList = ed.formatter.get(name);
15147      if (formatList) {
15148        for (var i = 0; i < formatList.length; i++) {
15149          if (formatList[i].inherit === false && ed.dom.is(node, formatList[i].selector)) {
15150            return true;
15151          }
15152        }
15153      }
15154      return false;
15155    };
15156    var matchParents = function (editor, node, name, vars) {
15157      var root = editor.dom.getRoot();
15158      if (node === root) {
15159        return false;
15160      }
15161      node = editor.dom.getParent(node, function (node) {
15162        if (matchesUnInheritedFormatSelector(editor, node, name)) {
15163          return true;
15164        }
15165        return node.parentNode === root || !!matchNode(editor, node, name, vars, true);
15166      });
15167      return matchNode(editor, node, name, vars);
15168    };
15169    var matchName = function (dom, node, format) {
15170      if (isEq$2(node, format.inline)) {
15171        return true;
15172      }
15173      if (isEq$2(node, format.block)) {
15174        return true;
15175      }
15176      if (format.selector) {
15177        return node.nodeType === 1 && dom.is(node, format.selector);
15178      }
15179    };
15180    var matchItems = function (dom, node, format, itemName, similar, vars) {
15181      var key, value;
15182      var items = format[itemName];
15183      var i;
15184      if (format.onmatch) {
15185        return format.onmatch(node, format, itemName);
15186      }
15187      if (items) {
15188        if (typeof items.length === 'undefined') {
15189          for (key in items) {
15190            if (items.hasOwnProperty(key)) {
15191              if (itemName === 'attributes') {
15192                value = dom.getAttrib(node, key);
15193              } else {
15194                value = getStyle(dom, node, key);
15195              }
15196              if (similar && !value && !format.exact) {
15197                return;
15198              }
15199              if ((!similar || format.exact) && !isEq$2(value, normalizeStyleValue(dom, replaceVars(items[key], vars), key))) {
15200                return;
15201              }
15202            }
15203          }
15204        } else {
15205          for (i = 0; i < items.length; i++) {
15206            if (itemName === 'attributes' ? dom.getAttrib(node, items[i]) : getStyle(dom, node, items[i])) {
15207              return format;
15208            }
15209          }
15210        }
15211      }
15212      return format;
15213    };
15214    var matchNode = function (ed, node, name, vars, similar) {
15215      var formatList = ed.formatter.get(name);
15216      var format, i, x, classes;
15217      var dom = ed.dom;
15218      if (formatList && node) {
15219        for (i = 0; i < formatList.length; i++) {
15220          format = formatList[i];
15221          if (matchName(ed.dom, node, format) && matchItems(dom, node, format, 'attributes', similar, vars) && matchItems(dom, node, format, 'styles', similar, vars)) {
15222            if (classes = format.classes) {
15223              for (x = 0; x < classes.length; x++) {
15224                if (!ed.dom.hasClass(node, classes[x])) {
15225                  return;
15226                }
15227              }
15228            }
15229            return format;
15230          }
15231        }
15232      }
15233    };
15234    var match = function (editor, name, vars, node) {
15235      if (node) {
15236        return matchParents(editor, node, name, vars);
15237      }
15238      node = editor.selection.getNode();
15239      if (matchParents(editor, node, name, vars)) {
15240        return true;
15241      }
15242      var startNode = editor.selection.getStart();
15243      if (startNode !== node) {
15244        if (matchParents(editor, startNode, name, vars)) {
15245          return true;
15246        }
15247      }
15248      return false;
15249    };
15250    var matchAll = function (editor, names, vars) {
15251      var matchedFormatNames = [];
15252      var checkedMap = {};
15253      var startElement = editor.selection.getStart();
15254      editor.dom.getParent(startElement, function (node) {
15255        for (var i = 0; i < names.length; i++) {
15256          var name_1 = names[i];
15257          if (!checkedMap[name_1] && matchNode(editor, node, name_1, vars)) {
15258            checkedMap[name_1] = true;
15259            matchedFormatNames.push(name_1);
15260          }
15261        }
15262      }, editor.dom.getRoot());
15263      return matchedFormatNames;
15264    };
15265    var canApply = function (editor, name) {
15266      var formatList = editor.formatter.get(name);
15267      var startNode, parents, i, x, selector;
15268      var dom = editor.dom;
15269      if (formatList) {
15270        startNode = editor.selection.getStart();
15271        parents = getParents$1(dom, startNode);
15272        for (x = formatList.length - 1; x >= 0; x--) {
15273          selector = formatList[x].selector;
15274          if (!selector || formatList[x].defaultBlock) {
15275            return true;
15276          }
15277          for (i = parents.length - 1; i >= 0; i--) {
15278            if (dom.is(parents[i], selector)) {
15279              return true;
15280            }
15281          }
15282        }
15283      }
15284      return false;
15285    };
15286    var matchAllOnNode = function (editor, node, formatNames) {
15287      return foldl(formatNames, function (acc, name) {
15288        var matchSimilar = isVariableFormatName(editor, name);
15289        if (editor.formatter.matchNode(node, name, {}, matchSimilar)) {
15290          return acc.concat([name]);
15291        } else {
15292          return acc;
15293        }
15294      }, []);
15295    };
15296
15297    var ZWSP$1 = ZWSP, CARET_ID$1 = '_mce_caret';
15298    var importNode = function (ownerDocument, node) {
15299      return ownerDocument.importNode(node, true);
15300    };
15301    var getEmptyCaretContainers = function (node) {
15302      var nodes = [];
15303      while (node) {
15304        if (node.nodeType === 3 && node.nodeValue !== ZWSP$1 || node.childNodes.length > 1) {
15305          return [];
15306        }
15307        if (node.nodeType === 1) {
15308          nodes.push(node);
15309        }
15310        node = node.firstChild;
15311      }
15312      return nodes;
15313    };
15314    var isCaretContainerEmpty = function (node) {
15315      return getEmptyCaretContainers(node).length > 0;
15316    };
15317    var findFirstTextNode = function (node) {
15318      if (node) {
15319        var walker = new DomTreeWalker(node, node);
15320        for (node = walker.current(); node; node = walker.next()) {
15321          if (isText$1(node)) {
15322            return node;
15323          }
15324        }
15325      }
15326      return null;
15327    };
15328    var createCaretContainer = function (fill) {
15329      var caretContainer = SugarElement.fromTag('span');
15330      setAll(caretContainer, {
15331        'id': CARET_ID$1,
15332        'data-mce-bogus': '1',
15333        'data-mce-type': 'format-caret'
15334      });
15335      if (fill) {
15336        append(caretContainer, SugarElement.fromText(ZWSP$1));
15337      }
15338      return caretContainer;
15339    };
15340    var trimZwspFromCaretContainer = function (caretContainerNode) {
15341      var textNode = findFirstTextNode(caretContainerNode);
15342      if (textNode && textNode.nodeValue.charAt(0) === ZWSP$1) {
15343        textNode.deleteData(0, 1);
15344      }
15345      return textNode;
15346    };
15347    var removeCaretContainerNode = function (editor, node, moveCaret) {
15348      if (moveCaret === void 0) {
15349        moveCaret = true;
15350      }
15351      var dom = editor.dom, selection = editor.selection;
15352      if (isCaretContainerEmpty(node)) {
15353        deleteElement(editor, false, SugarElement.fromDom(node), moveCaret);
15354      } else {
15355        var rng = selection.getRng();
15356        var block = dom.getParent(node, dom.isBlock);
15357        var startContainer = rng.startContainer;
15358        var startOffset = rng.startOffset;
15359        var endContainer = rng.endContainer;
15360        var endOffset = rng.endOffset;
15361        var textNode = trimZwspFromCaretContainer(node);
15362        dom.remove(node, true);
15363        if (startContainer === textNode && startOffset > 0) {
15364          rng.setStart(textNode, startOffset - 1);
15365        }
15366        if (endContainer === textNode && endOffset > 0) {
15367          rng.setEnd(textNode, endOffset - 1);
15368        }
15369        if (block && dom.isEmpty(block)) {
15370          fillWithPaddingBr(SugarElement.fromDom(block));
15371        }
15372        selection.setRng(rng);
15373      }
15374    };
15375    var removeCaretContainer = function (editor, node, moveCaret) {
15376      if (moveCaret === void 0) {
15377        moveCaret = true;
15378      }
15379      var dom = editor.dom, selection = editor.selection;
15380      if (!node) {
15381        node = getParentCaretContainer(editor.getBody(), selection.getStart());
15382        if (!node) {
15383          while (node = dom.get(CARET_ID$1)) {
15384            removeCaretContainerNode(editor, node, false);
15385          }
15386        }
15387      } else {
15388        removeCaretContainerNode(editor, node, moveCaret);
15389      }
15390    };
15391    var insertCaretContainerNode = function (editor, caretContainer, formatNode) {
15392      var dom = editor.dom, block = dom.getParent(formatNode, curry(isTextBlock$1, editor));
15393      if (block && dom.isEmpty(block)) {
15394        formatNode.parentNode.replaceChild(caretContainer, formatNode);
15395      } else {
15396        removeTrailingBr(SugarElement.fromDom(formatNode));
15397        if (dom.isEmpty(formatNode)) {
15398          formatNode.parentNode.replaceChild(caretContainer, formatNode);
15399        } else {
15400          dom.insertAfter(caretContainer, formatNode);
15401        }
15402      }
15403    };
15404    var appendNode = function (parentNode, node) {
15405      parentNode.appendChild(node);
15406      return node;
15407    };
15408    var insertFormatNodesIntoCaretContainer = function (formatNodes, caretContainer) {
15409      var innerMostFormatNode = foldr(formatNodes, function (parentNode, formatNode) {
15410        return appendNode(parentNode, formatNode.cloneNode(false));
15411      }, caretContainer);
15412      return appendNode(innerMostFormatNode, innerMostFormatNode.ownerDocument.createTextNode(ZWSP$1));
15413    };
15414    var cleanFormatNode = function (editor, caretContainer, formatNode, name, vars, similar) {
15415      var formatter = editor.formatter;
15416      var dom = editor.dom;
15417      var validFormats = filter(keys(formatter.get()), function (formatName) {
15418        return formatName !== name && !contains$1(formatName, 'removeformat');
15419      });
15420      var matchedFormats = matchAllOnNode(editor, formatNode, validFormats);
15421      var uniqueFormats = filter(matchedFormats, function (fmtName) {
15422        return !areSimilarFormats(editor, fmtName, name);
15423      });
15424      if (uniqueFormats.length > 0) {
15425        var clonedFormatNode = formatNode.cloneNode(false);
15426        dom.add(caretContainer, clonedFormatNode);
15427        formatter.remove(name, vars, clonedFormatNode, similar);
15428        dom.remove(clonedFormatNode);
15429        return Optional.some(clonedFormatNode);
15430      } else {
15431        return Optional.none();
15432      }
15433    };
15434    var applyCaretFormat = function (editor, name, vars) {
15435      var caretContainer, textNode;
15436      var selection = editor.selection;
15437      var selectionRng = selection.getRng();
15438      var offset = selectionRng.startOffset;
15439      var container = selectionRng.startContainer;
15440      var text = container.nodeValue;
15441      caretContainer = getParentCaretContainer(editor.getBody(), selection.getStart());
15442      if (caretContainer) {
15443        textNode = findFirstTextNode(caretContainer);
15444      }
15445      var wordcharRegex = /[^\s\u00a0\u00ad\u200b\ufeff]/;
15446      if (text && offset > 0 && offset < text.length && wordcharRegex.test(text.charAt(offset)) && wordcharRegex.test(text.charAt(offset - 1))) {
15447        var bookmark = selection.getBookmark();
15448        selectionRng.collapse(true);
15449        var rng = expandRng(editor, selectionRng, editor.formatter.get(name));
15450        rng = split$1(rng);
15451        editor.formatter.apply(name, vars, rng);
15452        selection.moveToBookmark(bookmark);
15453      } else {
15454        if (!caretContainer || textNode.nodeValue !== ZWSP$1) {
15455          caretContainer = importNode(editor.getDoc(), createCaretContainer(true).dom);
15456          textNode = caretContainer.firstChild;
15457          selectionRng.insertNode(caretContainer);
15458          offset = 1;
15459          editor.formatter.apply(name, vars, caretContainer);
15460        } else {
15461          editor.formatter.apply(name, vars, caretContainer);
15462        }
15463        selection.setCursorLocation(textNode, offset);
15464      }
15465    };
15466    var removeCaretFormat = function (editor, name, vars, similar) {
15467      var dom = editor.dom;
15468      var selection = editor.selection;
15469      var hasContentAfter, node, formatNode;
15470      var parents = [];
15471      var rng = selection.getRng();
15472      var container = rng.startContainer;
15473      var offset = rng.startOffset;
15474      node = container;
15475      if (container.nodeType === 3) {
15476        if (offset !== container.nodeValue.length) {
15477          hasContentAfter = true;
15478        }
15479        node = node.parentNode;
15480      }
15481      while (node) {
15482        if (matchNode(editor, node, name, vars, similar)) {
15483          formatNode = node;
15484          break;
15485        }
15486        if (node.nextSibling) {
15487          hasContentAfter = true;
15488        }
15489        parents.push(node);
15490        node = node.parentNode;
15491      }
15492      if (!formatNode) {
15493        return;
15494      }
15495      if (hasContentAfter) {
15496        var bookmark = selection.getBookmark();
15497        rng.collapse(true);
15498        var expandedRng = expandRng(editor, rng, editor.formatter.get(name), true);
15499        expandedRng = split$1(expandedRng);
15500        editor.formatter.remove(name, vars, expandedRng, similar);
15501        selection.moveToBookmark(bookmark);
15502      } else {
15503        var caretContainer = getParentCaretContainer(editor.getBody(), formatNode);
15504        var newCaretContainer = createCaretContainer(false).dom;
15505        insertCaretContainerNode(editor, newCaretContainer, caretContainer !== null ? caretContainer : formatNode);
15506        var cleanedFormatNode = cleanFormatNode(editor, newCaretContainer, formatNode, name, vars, similar);
15507        var caretTextNode = insertFormatNodesIntoCaretContainer(parents.concat(cleanedFormatNode.toArray()), newCaretContainer);
15508        removeCaretContainerNode(editor, caretContainer, false);
15509        selection.setCursorLocation(caretTextNode, 1);
15510        if (dom.isEmpty(formatNode)) {
15511          dom.remove(formatNode);
15512        }
15513      }
15514    };
15515    var disableCaretContainer = function (editor, keyCode) {
15516      var selection = editor.selection, body = editor.getBody();
15517      removeCaretContainer(editor, null, false);
15518      if ((keyCode === 8 || keyCode === 46) && selection.isCollapsed() && selection.getStart().innerHTML === ZWSP$1) {
15519        removeCaretContainer(editor, getParentCaretContainer(body, selection.getStart()));
15520      }
15521      if (keyCode === 37 || keyCode === 39) {
15522        removeCaretContainer(editor, getParentCaretContainer(body, selection.getStart()));
15523      }
15524    };
15525    var setup$3 = function (editor) {
15526      editor.on('mouseup keydown', function (e) {
15527        disableCaretContainer(editor, e.keyCode);
15528      });
15529    };
15530    var replaceWithCaretFormat = function (targetNode, formatNodes) {
15531      var caretContainer = createCaretContainer(false);
15532      var innerMost = insertFormatNodesIntoCaretContainer(formatNodes, caretContainer.dom);
15533      before(SugarElement.fromDom(targetNode), caretContainer);
15534      remove(SugarElement.fromDom(targetNode));
15535      return CaretPosition$1(innerMost, 0);
15536    };
15537    var isFormatElement = function (editor, element) {
15538      var inlineElements = editor.schema.getTextInlineElements();
15539      return inlineElements.hasOwnProperty(name(element)) && !isCaretNode(element.dom) && !isBogus(element.dom);
15540    };
15541    var isEmptyCaretFormatElement = function (element) {
15542      return isCaretNode(element.dom) && isCaretContainerEmpty(element.dom);
15543    };
15544
15545    var postProcessHooks = {};
15546    var filter$4 = filter$2;
15547    var each$8 = each$2;
15548    var addPostProcessHook = function (name, hook) {
15549      var hooks = postProcessHooks[name];
15550      if (!hooks) {
15551        postProcessHooks[name] = [];
15552      }
15553      postProcessHooks[name].push(hook);
15554    };
15555    var postProcess = function (name, editor) {
15556      each$8(postProcessHooks[name], function (hook) {
15557        hook(editor);
15558      });
15559    };
15560    addPostProcessHook('pre', function (editor) {
15561      var rng = editor.selection.getRng();
15562      var blocks;
15563      var hasPreSibling = function (pre) {
15564        return isPre(pre.previousSibling) && indexOf$1(blocks, pre.previousSibling) !== -1;
15565      };
15566      var joinPre = function (pre1, pre2) {
15567        DomQuery(pre2).remove();
15568        DomQuery(pre1).append('<br><br>').append(pre2.childNodes);
15569      };
15570      var isPre = matchNodeNames(['pre']);
15571      if (!rng.collapsed) {
15572        blocks = editor.selection.getSelectedBlocks();
15573        each$8(filter$4(filter$4(blocks, isPre), hasPreSibling), function (pre) {
15574          joinPre(pre.previousSibling, pre);
15575        });
15576      }
15577    });
15578
15579    var each$9 = Tools.each;
15580    var isElementNode = function (node) {
15581      return isElement$1(node) && !isBookmarkNode$1(node) && !isCaretNode(node) && !isBogus(node);
15582    };
15583    var findElementSibling = function (node, siblingName) {
15584      var sibling;
15585      for (sibling = node; sibling; sibling = sibling[siblingName]) {
15586        if (isText$1(sibling) && sibling.nodeValue.length !== 0) {
15587          return node;
15588        }
15589        if (isElement$1(sibling) && !isBookmarkNode$1(sibling)) {
15590          return sibling;
15591        }
15592      }
15593      return node;
15594    };
15595    var mergeSiblingsNodes = function (dom, prev, next) {
15596      var sibling, tmpSibling;
15597      var elementUtils = new ElementUtils(dom);
15598      if (prev && next) {
15599        prev = findElementSibling(prev, 'previousSibling');
15600        next = findElementSibling(next, 'nextSibling');
15601        if (elementUtils.compare(prev, next)) {
15602          for (sibling = prev.nextSibling; sibling && sibling !== next;) {
15603            tmpSibling = sibling;
15604            sibling = sibling.nextSibling;
15605            prev.appendChild(tmpSibling);
15606          }
15607          dom.remove(next);
15608          Tools.each(Tools.grep(next.childNodes), function (node) {
15609            prev.appendChild(node);
15610          });
15611          return prev;
15612        }
15613      }
15614      return next;
15615    };
15616    var mergeSiblings = function (dom, format, vars, node) {
15617      if (node && format.merge_siblings !== false) {
15618        var newNode = mergeSiblingsNodes(dom, getNonWhiteSpaceSibling(node), node);
15619        mergeSiblingsNodes(dom, newNode, getNonWhiteSpaceSibling(newNode, true));
15620      }
15621    };
15622    var clearChildStyles = function (dom, format, node) {
15623      if (format.clear_child_styles) {
15624        var selector = format.links ? '*:not(a)' : '*';
15625        each$9(dom.select(selector, node), function (node) {
15626          if (isElementNode(node)) {
15627            each$9(format.styles, function (value, name) {
15628              dom.setStyle(node, name, '');
15629            });
15630          }
15631        });
15632      }
15633    };
15634    var processChildElements = function (node, filter, process) {
15635      each$9(node.childNodes, function (node) {
15636        if (isElementNode(node)) {
15637          if (filter(node)) {
15638            process(node);
15639          }
15640          if (node.hasChildNodes()) {
15641            processChildElements(node, filter, process);
15642          }
15643        }
15644      });
15645    };
15646    var unwrapEmptySpan = function (dom, node) {
15647      if (node.nodeName === 'SPAN' && dom.getAttribs(node).length === 0) {
15648        dom.remove(node, true);
15649      }
15650    };
15651    var hasStyle = function (dom, name) {
15652      return function (node) {
15653        return !!(node && getStyle(dom, node, name));
15654      };
15655    };
15656    var applyStyle = function (dom, name, value) {
15657      return function (node) {
15658        dom.setStyle(node, name, value);
15659        if (node.getAttribute('style') === '') {
15660          node.removeAttribute('style');
15661        }
15662        unwrapEmptySpan(dom, node);
15663      };
15664    };
15665
15666    var removeResult = Adt.generate([
15667      { keep: [] },
15668      { rename: ['name'] },
15669      { removed: [] }
15670    ]);
15671    var MCE_ATTR_RE = /^(src|href|style)$/;
15672    var each$a = Tools.each;
15673    var isEq$3 = isEq;
15674    var isTableCellOrRow = function (node) {
15675      return /^(TR|TH|TD)$/.test(node.nodeName);
15676    };
15677    var isChildOfInlineParent = function (dom, node, parent) {
15678      return dom.isChildOf(node, parent) && node !== parent && !dom.isBlock(parent);
15679    };
15680    var getContainer = function (ed, rng, start) {
15681      var container, offset;
15682      container = rng[start ? 'startContainer' : 'endContainer'];
15683      offset = rng[start ? 'startOffset' : 'endOffset'];
15684      if (isElement$1(container)) {
15685        var lastIdx = container.childNodes.length - 1;
15686        if (!start && offset) {
15687          offset--;
15688        }
15689        container = container.childNodes[offset > lastIdx ? lastIdx : offset];
15690      }
15691      if (isText$1(container) && start && offset >= container.nodeValue.length) {
15692        container = new DomTreeWalker(container, ed.getBody()).next() || container;
15693      }
15694      if (isText$1(container) && !start && offset === 0) {
15695        container = new DomTreeWalker(container, ed.getBody()).prev() || container;
15696      }
15697      return container;
15698    };
15699    var normalizeTableSelection = function (node, start) {
15700      var prop = start ? 'firstChild' : 'lastChild';
15701      if (isTableCellOrRow(node) && node[prop]) {
15702        var childNode = node[prop];
15703        if (node.nodeName === 'TR') {
15704          return childNode[prop] || childNode;
15705        } else {
15706          return childNode;
15707        }
15708      }
15709      return node;
15710    };
15711    var wrap$2 = function (dom, node, name, attrs) {
15712      var wrapper = dom.create(name, attrs);
15713      node.parentNode.insertBefore(wrapper, node);
15714      wrapper.appendChild(node);
15715      return wrapper;
15716    };
15717    var wrapWithSiblings = function (dom, node, next, name, attrs) {
15718      var start = SugarElement.fromDom(node);
15719      var wrapper = SugarElement.fromDom(dom.create(name, attrs));
15720      var siblings = next ? nextSiblings(start) : prevSiblings(start);
15721      append$1(wrapper, siblings);
15722      if (next) {
15723        before(start, wrapper);
15724        prepend(wrapper, start);
15725      } else {
15726        after(start, wrapper);
15727        append(wrapper, start);
15728      }
15729      return wrapper.dom;
15730    };
15731    var matchName$1 = function (dom, node, format) {
15732      if (isEq$3(node, format.inline)) {
15733        return true;
15734      }
15735      if (isEq$3(node, format.block)) {
15736        return true;
15737      }
15738      if (format.selector) {
15739        return isElement$1(node) && dom.is(node, format.selector);
15740      }
15741    };
15742    var isColorFormatAndAnchor = function (node, format) {
15743      return format.links && node.nodeName === 'A';
15744    };
15745    var find$3 = function (dom, node, next, inc) {
15746      node = getNonWhiteSpaceSibling(node, next, inc);
15747      return !node || (node.nodeName === 'BR' || dom.isBlock(node));
15748    };
15749    var removeNode$1 = function (ed, node, format) {
15750      var parentNode = node.parentNode;
15751      var rootBlockElm;
15752      var dom = ed.dom, forcedRootBlock = getForcedRootBlock(ed);
15753      if (format.block) {
15754        if (!forcedRootBlock) {
15755          if (dom.isBlock(node) && !dom.isBlock(parentNode)) {
15756            if (!find$3(dom, node, false) && !find$3(dom, node.firstChild, true, true)) {
15757              node.insertBefore(dom.create('br'), node.firstChild);
15758            }
15759            if (!find$3(dom, node, true) && !find$3(dom, node.lastChild, false, true)) {
15760              node.appendChild(dom.create('br'));
15761            }
15762          }
15763        } else {
15764          if (parentNode === dom.getRoot()) {
15765            if (!format.list_block || !isEq$3(node, format.list_block)) {
15766              each(from$1(node.childNodes), function (node) {
15767                if (isValid(ed, forcedRootBlock, node.nodeName.toLowerCase())) {
15768                  if (!rootBlockElm) {
15769                    rootBlockElm = wrap$2(dom, node, forcedRootBlock);
15770                    dom.setAttribs(rootBlockElm, ed.settings.forced_root_block_attrs);
15771                  } else {
15772                    rootBlockElm.appendChild(node);
15773                  }
15774                } else {
15775                  rootBlockElm = 0;
15776                }
15777              });
15778            }
15779          }
15780        }
15781      }
15782      if (format.selector && format.inline && !isEq$3(format.inline, node)) {
15783        return;
15784      }
15785      dom.remove(node, true);
15786    };
15787    var removeFormatInternal = function (ed, format, vars, node, compareNode) {
15788      var stylesModified;
15789      var dom = ed.dom;
15790      if (!matchName$1(dom, node, format) && !isColorFormatAndAnchor(node, format)) {
15791        return removeResult.keep();
15792      }
15793      var elm = node;
15794      if (format.inline && format.remove === 'all' && isArray(format.preserve_attributes)) {
15795        var attrsToPreserve = filter(dom.getAttribs(elm), function (attr) {
15796          return contains(format.preserve_attributes, attr.name.toLowerCase());
15797        });
15798        dom.removeAllAttribs(elm);
15799        each(attrsToPreserve, function (attr) {
15800          return dom.setAttrib(elm, attr.name, attr.value);
15801        });
15802        if (attrsToPreserve.length > 0) {
15803          return removeResult.rename('span');
15804        }
15805      }
15806      if (format.remove !== 'all') {
15807        each$a(format.styles, function (value, name) {
15808          value = normalizeStyleValue(dom, replaceVars(value, vars), name + '');
15809          if (isNumber(name)) {
15810            name = value;
15811            compareNode = null;
15812          }
15813          if (format.remove_similar || (!compareNode || isEq$3(getStyle(dom, compareNode, name), value))) {
15814            dom.setStyle(elm, name, '');
15815          }
15816          stylesModified = true;
15817        });
15818        if (stylesModified && dom.getAttrib(elm, 'style') === '') {
15819          elm.removeAttribute('style');
15820          elm.removeAttribute('data-mce-style');
15821        }
15822        each$a(format.attributes, function (value, name) {
15823          var valueOut;
15824          value = replaceVars(value, vars);
15825          if (isNumber(name)) {
15826            name = value;
15827            compareNode = null;
15828          }
15829          if (format.remove_similar || (!compareNode || isEq$3(dom.getAttrib(compareNode, name), value))) {
15830            if (name === 'class') {
15831              value = dom.getAttrib(elm, name);
15832              if (value) {
15833                valueOut = '';
15834                each(value.split(/\s+/), function (cls) {
15835                  if (/mce\-\w+/.test(cls)) {
15836                    valueOut += (valueOut ? ' ' : '') + cls;
15837                  }
15838                });
15839                if (valueOut) {
15840                  dom.setAttrib(elm, name, valueOut);
15841                  return;
15842                }
15843              }
15844            }
15845            if (name === 'class') {
15846              elm.removeAttribute('className');
15847            }
15848            if (MCE_ATTR_RE.test(name)) {
15849              elm.removeAttribute('data-mce-' + name);
15850            }
15851            elm.removeAttribute(name);
15852          }
15853        });
15854        each$a(format.classes, function (value) {
15855          value = replaceVars(value, vars);
15856          if (!compareNode || dom.hasClass(compareNode, value)) {
15857            dom.removeClass(elm, value);
15858          }
15859        });
15860        var attrs = dom.getAttribs(elm);
15861        for (var i = 0; i < attrs.length; i++) {
15862          var attrName = attrs[i].nodeName;
15863          if (attrName.indexOf('_') !== 0 && attrName.indexOf('data-') !== 0) {
15864            return removeResult.keep();
15865          }
15866        }
15867      }
15868      if (format.remove !== 'none') {
15869        removeNode$1(ed, elm, format);
15870        return removeResult.removed();
15871      }
15872      return removeResult.keep();
15873    };
15874    var removeFormat = function (ed, format, vars, node, compareNode) {
15875      return removeFormatInternal(ed, format, vars, node, compareNode).fold(never, function (newName) {
15876        ed.dom.rename(node, newName);
15877        return true;
15878      }, always);
15879    };
15880    var findFormatRoot = function (editor, container, name, vars, similar) {
15881      var formatRoot;
15882      each(getParents$1(editor.dom, container.parentNode).reverse(), function (parent) {
15883        if (!formatRoot && parent.id !== '_start' && parent.id !== '_end') {
15884          var format = matchNode(editor, parent, name, vars, similar);
15885          if (format && format.split !== false) {
15886            formatRoot = parent;
15887          }
15888        }
15889      });
15890      return formatRoot;
15891    };
15892    var removeFormatFromClone = function (editor, format, vars, clone) {
15893      return removeFormatInternal(editor, format, vars, clone, clone).fold(constant(clone), function (newName) {
15894        var fragment = editor.dom.createFragment();
15895        fragment.appendChild(clone);
15896        return editor.dom.rename(clone, newName);
15897      }, constant(null));
15898    };
15899    var wrapAndSplit = function (editor, formatList, formatRoot, container, target, split, format, vars) {
15900      var clone, lastClone, firstClone;
15901      var dom = editor.dom;
15902      if (formatRoot) {
15903        var formatRootParent = formatRoot.parentNode;
15904        for (var parent_1 = container.parentNode; parent_1 && parent_1 !== formatRootParent; parent_1 = parent_1.parentNode) {
15905          clone = dom.clone(parent_1, false);
15906          for (var i = 0; i < formatList.length; i++) {
15907            clone = removeFormatFromClone(editor, formatList[i], vars, clone);
15908            if (clone === null) {
15909              break;
15910            }
15911          }
15912          if (clone) {
15913            if (lastClone) {
15914              clone.appendChild(lastClone);
15915            }
15916            if (!firstClone) {
15917              firstClone = clone;
15918            }
15919            lastClone = clone;
15920          }
15921        }
15922        if (split && (!format.mixed || !dom.isBlock(formatRoot))) {
15923          container = dom.split(formatRoot, container);
15924        }
15925        if (lastClone) {
15926          target.parentNode.insertBefore(lastClone, target);
15927          firstClone.appendChild(target);
15928          if (format.inline) {
15929            mergeSiblings(dom, format, vars, lastClone);
15930          }
15931        }
15932      }
15933      return container;
15934    };
15935    var remove$6 = function (ed, name, vars, node, similar) {
15936      var formatList = ed.formatter.get(name);
15937      var format = formatList[0];
15938      var contentEditable = true;
15939      var dom = ed.dom;
15940      var selection = ed.selection;
15941      var splitToFormatRoot = function (container) {
15942        var formatRoot = findFormatRoot(ed, container, name, vars, similar);
15943        return wrapAndSplit(ed, formatList, formatRoot, container, container, true, format, vars);
15944      };
15945      var isRemoveBookmarkNode = function (node) {
15946        return isBookmarkNode$1(node) && isElement$1(node) && (node.id === '_start' || node.id === '_end');
15947      };
15948      var process = function (node) {
15949        var lastContentEditable, hasContentEditableState;
15950        if (isElement$1(node) && dom.getContentEditable(node)) {
15951          lastContentEditable = contentEditable;
15952          contentEditable = dom.getContentEditable(node) === 'true';
15953          hasContentEditableState = true;
15954        }
15955        var children = from$1(node.childNodes);
15956        if (contentEditable && !hasContentEditableState) {
15957          for (var i = 0; i < formatList.length; i++) {
15958            if (removeFormat(ed, formatList[i], vars, node, node)) {
15959              break;
15960            }
15961          }
15962        }
15963        if (format.deep) {
15964          if (children.length) {
15965            for (var i = 0; i < children.length; i++) {
15966              process(children[i]);
15967            }
15968            if (hasContentEditableState) {
15969              contentEditable = lastContentEditable;
15970            }
15971          }
15972        }
15973      };
15974      var unwrap = function (start) {
15975        var node = dom.get(start ? '_start' : '_end');
15976        var out = node[start ? 'firstChild' : 'lastChild'];
15977        if (isRemoveBookmarkNode(out)) {
15978          out = out[start ? 'firstChild' : 'lastChild'];
15979        }
15980        if (isText$1(out) && out.data.length === 0) {
15981          out = start ? node.previousSibling || node.nextSibling : node.nextSibling || node.previousSibling;
15982        }
15983        dom.remove(node, true);
15984        return out;
15985      };
15986      var removeRngStyle = function (rng) {
15987        var startContainer, endContainer;
15988        var expandedRng = expandRng(ed, rng, formatList, true);
15989        if (format.split) {
15990          expandedRng = split$1(expandedRng);
15991          startContainer = getContainer(ed, expandedRng, true);
15992          endContainer = getContainer(ed, expandedRng);
15993          if (startContainer !== endContainer) {
15994            startContainer = normalizeTableSelection(startContainer, true);
15995            endContainer = normalizeTableSelection(endContainer, false);
15996            if (isChildOfInlineParent(dom, startContainer, endContainer)) {
15997              var marker = Optional.from(startContainer.firstChild).getOr(startContainer);
15998              splitToFormatRoot(wrapWithSiblings(dom, marker, true, 'span', {
15999                'id': '_start',
16000                'data-mce-type': 'bookmark'
16001              }));
16002              unwrap(true);
16003              return;
16004            }
16005            if (isChildOfInlineParent(dom, endContainer, startContainer)) {
16006              var marker = Optional.from(endContainer.lastChild).getOr(endContainer);
16007              splitToFormatRoot(wrapWithSiblings(dom, marker, false, 'span', {
16008                'id': '_end',
16009                'data-mce-type': 'bookmark'
16010              }));
16011              unwrap(false);
16012              return;
16013            }
16014            startContainer = wrap$2(dom, startContainer, 'span', {
16015              'id': '_start',
16016              'data-mce-type': 'bookmark'
16017            });
16018            endContainer = wrap$2(dom, endContainer, 'span', {
16019              'id': '_end',
16020              'data-mce-type': 'bookmark'
16021            });
16022            var newRng = dom.createRng();
16023            newRng.setStartAfter(startContainer);
16024            newRng.setEndBefore(endContainer);
16025            walk$1(dom, newRng, function (nodes) {
16026              each(nodes, function (n) {
16027                if (!isBookmarkNode$1(n) && !isBookmarkNode$1(n.parentNode)) {
16028                  splitToFormatRoot(n);
16029                }
16030              });
16031            });
16032            splitToFormatRoot(startContainer);
16033            splitToFormatRoot(endContainer);
16034            startContainer = unwrap(true);
16035            endContainer = unwrap();
16036          } else {
16037            startContainer = endContainer = splitToFormatRoot(startContainer);
16038          }
16039          expandedRng.startContainer = startContainer.parentNode ? startContainer.parentNode : startContainer;
16040          expandedRng.startOffset = dom.nodeIndex(startContainer);
16041          expandedRng.endContainer = endContainer.parentNode ? endContainer.parentNode : endContainer;
16042          expandedRng.endOffset = dom.nodeIndex(endContainer) + 1;
16043        }
16044        walk$1(dom, expandedRng, function (nodes) {
16045          each(nodes, function (node) {
16046            process(node);
16047            var textDecorations = [
16048              'underline',
16049              'line-through',
16050              'overline'
16051            ];
16052            each(textDecorations, function (decoration) {
16053              if (isElement$1(node) && ed.dom.getStyle(node, 'text-decoration') === decoration && node.parentNode && getTextDecoration(dom, node.parentNode) === decoration) {
16054                removeFormat(ed, {
16055                  deep: false,
16056                  exact: true,
16057                  inline: 'span',
16058                  styles: { textDecoration: decoration }
16059                }, null, node);
16060              }
16061            });
16062          });
16063        });
16064      };
16065      if (node) {
16066        if (isNode(node)) {
16067          var rng = dom.createRng();
16068          rng.setStartBefore(node);
16069          rng.setEndAfter(node);
16070          removeRngStyle(rng);
16071        } else {
16072          removeRngStyle(node);
16073        }
16074        return;
16075      }
16076      if (dom.getContentEditable(selection.getNode()) === 'false') {
16077        node = selection.getNode();
16078        for (var i = 0; i < formatList.length; i++) {
16079          if (formatList[i].ceFalseOverride) {
16080            if (removeFormat(ed, formatList[i], vars, node, node)) {
16081              break;
16082            }
16083          }
16084        }
16085        return;
16086      }
16087      if (!selection.isCollapsed() || !format.inline || getCellsFromEditor(ed).length) {
16088        preserve(selection, true, function () {
16089          runOnRanges(ed, removeRngStyle);
16090        });
16091        if (format.inline && match(ed, name, vars, selection.getStart())) {
16092          moveStart(dom, selection, selection.getRng());
16093        }
16094        ed.nodeChanged();
16095      } else {
16096        removeCaretFormat(ed, name, vars, similar);
16097      }
16098    };
16099
16100    var each$b = Tools.each;
16101    var mergeTextDecorationsAndColor = function (dom, format, vars, node) {
16102      var processTextDecorationsAndColor = function (n) {
16103        if (n.nodeType === 1 && n.parentNode && n.parentNode.nodeType === 1) {
16104          var textDecoration = getTextDecoration(dom, n.parentNode);
16105          if (dom.getStyle(n, 'color') && textDecoration) {
16106            dom.setStyle(n, 'text-decoration', textDecoration);
16107          } else if (dom.getStyle(n, 'text-decoration') === textDecoration) {
16108            dom.setStyle(n, 'text-decoration', null);
16109          }
16110        }
16111      };
16112      if (format.styles && (format.styles.color || format.styles.textDecoration)) {
16113        Tools.walk(node, processTextDecorationsAndColor, 'childNodes');
16114        processTextDecorationsAndColor(node);
16115      }
16116    };
16117    var mergeBackgroundColorAndFontSize = function (dom, format, vars, node) {
16118      if (format.styles && format.styles.backgroundColor) {
16119        processChildElements(node, hasStyle(dom, 'fontSize'), applyStyle(dom, 'backgroundColor', replaceVars(format.styles.backgroundColor, vars)));
16120      }
16121    };
16122    var mergeSubSup = function (dom, format, vars, node) {
16123      if (format.inline === 'sub' || format.inline === 'sup') {
16124        processChildElements(node, hasStyle(dom, 'fontSize'), applyStyle(dom, 'fontSize', ''));
16125        dom.remove(dom.select(format.inline === 'sup' ? 'sub' : 'sup', node), true);
16126      }
16127    };
16128    var mergeWithChildren = function (editor, formatList, vars, node) {
16129      each$b(formatList, function (format) {
16130        each$b(editor.dom.select(format.inline, node), function (child) {
16131          if (!isElementNode(child)) {
16132            return;
16133          }
16134          removeFormat(editor, format, vars, child, format.exact ? child : null);
16135        });
16136        clearChildStyles(editor.dom, format, node);
16137      });
16138    };
16139    var mergeWithParents = function (editor, format, name, vars, node) {
16140      if (matchNode(editor, node.parentNode, name, vars)) {
16141        if (removeFormat(editor, format, vars, node)) {
16142          return;
16143        }
16144      }
16145      if (format.merge_with_parents) {
16146        editor.dom.getParent(node.parentNode, function (parent) {
16147          if (matchNode(editor, parent, name, vars)) {
16148            removeFormat(editor, format, vars, node);
16149            return true;
16150          }
16151        });
16152      }
16153    };
16154
16155    var each$c = Tools.each;
16156    var isElementNode$1 = function (node) {
16157      return node && node.nodeType === 1 && !isBookmarkNode$1(node) && !isCaretNode(node) && !isBogus(node);
16158    };
16159    var applyFormat = function (ed, name, vars, node) {
16160      var formatList = ed.formatter.get(name);
16161      var format = formatList[0];
16162      var rng;
16163      var isCollapsed = !node && ed.selection.isCollapsed();
16164      var dom = ed.dom, selection = ed.selection;
16165      var setElementFormat = function (elm, fmt) {
16166        fmt = fmt || format;
16167        if (elm) {
16168          if (fmt.onformat) {
16169            fmt.onformat(elm, fmt, vars, node);
16170          }
16171          each$c(fmt.styles, function (value, name) {
16172            dom.setStyle(elm, name, replaceVars(value, vars));
16173          });
16174          if (fmt.styles) {
16175            var styleVal = dom.getAttrib(elm, 'style');
16176            if (styleVal) {
16177              dom.setAttrib(elm, 'data-mce-style', styleVal);
16178            }
16179          }
16180          each$c(fmt.attributes, function (value, name) {
16181            dom.setAttrib(elm, name, replaceVars(value, vars));
16182          });
16183          each$c(fmt.classes, function (value) {
16184            value = replaceVars(value, vars);
16185            if (!dom.hasClass(elm, value)) {
16186              dom.addClass(elm, value);
16187            }
16188          });
16189        }
16190      };
16191      var applyNodeStyle = function (formatList, node) {
16192        var found = false;
16193        if (!format.selector) {
16194          return false;
16195        }
16196        each$c(formatList, function (format) {
16197          if ('collapsed' in format && format.collapsed !== isCollapsed) {
16198            return;
16199          }
16200          if (dom.is(node, format.selector) && !isCaretNode(node)) {
16201            setElementFormat(node, format);
16202            found = true;
16203            return false;
16204          }
16205        });
16206        return found;
16207      };
16208      var applyRngStyle = function (dom, rng, bookmark, nodeSpecific) {
16209        var newWrappers = [];
16210        var contentEditable = true;
16211        var wrapName = format.inline || format.block;
16212        var wrapElm = dom.create(wrapName);
16213        setElementFormat(wrapElm);
16214        walk$1(dom, rng, function (nodes) {
16215          var currentWrapElm;
16216          var process = function (node) {
16217            var hasContentEditableState = false;
16218            var lastContentEditable = contentEditable;
16219            var nodeName = node.nodeName.toLowerCase();
16220            var parentName = node.parentNode.nodeName.toLowerCase();
16221            if (isElement$1(node) && dom.getContentEditable(node)) {
16222              lastContentEditable = contentEditable;
16223              contentEditable = dom.getContentEditable(node) === 'true';
16224              hasContentEditableState = true;
16225            }
16226            if (isEq(nodeName, 'br')) {
16227              currentWrapElm = 0;
16228              if (format.block) {
16229                dom.remove(node);
16230              }
16231              return;
16232            }
16233            if (format.wrapper && matchNode(ed, node, name, vars)) {
16234              currentWrapElm = 0;
16235              return;
16236            }
16237            if (contentEditable && !hasContentEditableState && format.block && !format.wrapper && isTextBlock$1(ed, nodeName) && isValid(ed, parentName, wrapName)) {
16238              var elm = dom.rename(node, wrapName);
16239              setElementFormat(elm);
16240              newWrappers.push(elm);
16241              currentWrapElm = 0;
16242              return;
16243            }
16244            if (format.selector) {
16245              var found = applyNodeStyle(formatList, node);
16246              if (!format.inline || found) {
16247                currentWrapElm = 0;
16248                return;
16249              }
16250            }
16251            if (contentEditable && !hasContentEditableState && isValid(ed, wrapName, nodeName) && isValid(ed, parentName, wrapName) && !(!nodeSpecific && node.nodeType === 3 && node.nodeValue.length === 1 && node.nodeValue.charCodeAt(0) === 65279) && !isCaretNode(node) && (!format.inline || !dom.isBlock(node))) {
16252              if (!currentWrapElm) {
16253                currentWrapElm = dom.clone(wrapElm, false);
16254                node.parentNode.insertBefore(currentWrapElm, node);
16255                newWrappers.push(currentWrapElm);
16256              }
16257              currentWrapElm.appendChild(node);
16258            } else {
16259              currentWrapElm = 0;
16260              each$c(Tools.grep(node.childNodes), process);
16261              if (hasContentEditableState) {
16262                contentEditable = lastContentEditable;
16263              }
16264              currentWrapElm = 0;
16265            }
16266          };
16267          each$c(nodes, process);
16268        });
16269        if (format.links === true) {
16270          each$c(newWrappers, function (node) {
16271            var process = function (node) {
16272              if (node.nodeName === 'A') {
16273                setElementFormat(node, format);
16274              }
16275              each$c(Tools.grep(node.childNodes), process);
16276            };
16277            process(node);
16278          });
16279        }
16280        each$c(newWrappers, function (node) {
16281          var getChildCount = function (node) {
16282            var count = 0;
16283            each$c(node.childNodes, function (node) {
16284              if (!isEmptyTextNode(node) && !isBookmarkNode$1(node)) {
16285                count++;
16286              }
16287            });
16288            return count;
16289          };
16290          var getChildElementNode = function (root) {
16291            var child = false;
16292            each$c(root.childNodes, function (node) {
16293              if (isElementNode$1(node)) {
16294                child = node;
16295                return false;
16296              }
16297            });
16298            return child;
16299          };
16300          var mergeStyles = function (node) {
16301            var clone;
16302            var child = getChildElementNode(node);
16303            if (child && !isBookmarkNode$1(child) && matchName(dom, child, format)) {
16304              clone = dom.clone(child, false);
16305              setElementFormat(clone);
16306              dom.replace(clone, node, true);
16307              dom.remove(child, true);
16308            }
16309            return clone || node;
16310          };
16311          var childCount = getChildCount(node);
16312          if ((newWrappers.length > 1 || !dom.isBlock(node)) && childCount === 0) {
16313            dom.remove(node, true);
16314            return;
16315          }
16316          if (format.inline || format.wrapper) {
16317            if (!format.exact && childCount === 1) {
16318              node = mergeStyles(node);
16319            }
16320            mergeWithChildren(ed, formatList, vars, node);
16321            mergeWithParents(ed, format, name, vars, node);
16322            mergeBackgroundColorAndFontSize(dom, format, vars, node);
16323            mergeTextDecorationsAndColor(dom, format, vars, node);
16324            mergeSubSup(dom, format, vars, node);
16325            mergeSiblings(dom, format, vars, node);
16326          }
16327        });
16328      };
16329      if (dom.getContentEditable(selection.getNode()) === 'false') {
16330        node = selection.getNode();
16331        for (var i = 0, l = formatList.length; i < l; i++) {
16332          if (formatList[i].ceFalseOverride && dom.is(node, formatList[i].selector)) {
16333            setElementFormat(node, formatList[i]);
16334            return;
16335          }
16336        }
16337        return;
16338      }
16339      if (format) {
16340        if (node) {
16341          if (isNode(node)) {
16342            if (!applyNodeStyle(formatList, node)) {
16343              rng = dom.createRng();
16344              rng.setStartBefore(node);
16345              rng.setEndAfter(node);
16346              applyRngStyle(dom, expandRng(ed, rng, formatList), null, true);
16347            }
16348          } else {
16349            applyRngStyle(dom, node, null, true);
16350          }
16351        } else {
16352          if (!isCollapsed || !format.inline || getCellsFromEditor(ed).length) {
16353            var curSelNode = selection.getNode();
16354            if (!ed.settings.forced_root_block && formatList[0].defaultBlock && !dom.getParent(curSelNode, dom.isBlock)) {
16355              applyFormat(ed, formatList[0].defaultBlock);
16356            }
16357            selection.setRng(normalize$2(selection.getRng()));
16358            preserve(selection, true, function (bookmark) {
16359              runOnRanges(ed, function (selectionRng, fake) {
16360                var expandedRng = fake ? selectionRng : expandRng(ed, selectionRng, formatList);
16361                applyRngStyle(dom, expandedRng);
16362              });
16363            });
16364            moveStart(dom, selection, selection.getRng());
16365            ed.nodeChanged();
16366          } else {
16367            applyCaretFormat(ed, name, vars);
16368          }
16369        }
16370        postProcess(name, ed);
16371      }
16372    };
16373
16374    var toggle = function (editor, name, vars, node) {
16375      var fmt = editor.formatter.get(name);
16376      if (match(editor, name, vars, node) && (!('toggle' in fmt[0]) || fmt[0].toggle)) {
16377        remove$6(editor, name, vars, node);
16378      } else {
16379        applyFormat(editor, name, vars, node);
16380      }
16381    };
16382
16383    var fromElements = function (elements, scope) {
16384      var doc = scope || document;
16385      var fragment = doc.createDocumentFragment();
16386      each(elements, function (element) {
16387        fragment.appendChild(element.dom);
16388      });
16389      return SugarElement.fromDom(fragment);
16390    };
16391
16392    var tableModel = function (element, width, rows) {
16393      return {
16394        element: element,
16395        width: width,
16396        rows: rows
16397      };
16398    };
16399    var tableRow = function (element, cells) {
16400      return {
16401        element: element,
16402        cells: cells
16403      };
16404    };
16405    var cellPosition = function (x, y) {
16406      return {
16407        x: x,
16408        y: y
16409      };
16410    };
16411    var getSpan = function (td, key) {
16412      var value = parseInt(get$3(td, key), 10);
16413      return isNaN(value) ? 1 : value;
16414    };
16415    var fillout = function (table, x, y, tr, td) {
16416      var rowspan = getSpan(td, 'rowspan');
16417      var colspan = getSpan(td, 'colspan');
16418      var rows = table.rows;
16419      for (var y2 = y; y2 < y + rowspan; y2++) {
16420        if (!rows[y2]) {
16421          rows[y2] = tableRow(deep(tr), []);
16422        }
16423        for (var x2 = x; x2 < x + colspan; x2++) {
16424          var cells = rows[y2].cells;
16425          cells[x2] = y2 === y && x2 === x ? td : shallow(td);
16426        }
16427      }
16428    };
16429    var cellExists = function (table, x, y) {
16430      var rows = table.rows;
16431      var cells = rows[y] ? rows[y].cells : [];
16432      return !!cells[x];
16433    };
16434    var skipCellsX = function (table, x, y) {
16435      while (cellExists(table, x, y)) {
16436        x++;
16437      }
16438      return x;
16439    };
16440    var getWidth = function (rows) {
16441      return foldl(rows, function (acc, row) {
16442        return row.cells.length > acc ? row.cells.length : acc;
16443      }, 0);
16444    };
16445    var findElementPos = function (table, element) {
16446      var rows = table.rows;
16447      for (var y = 0; y < rows.length; y++) {
16448        var cells = rows[y].cells;
16449        for (var x = 0; x < cells.length; x++) {
16450          if (eq$2(cells[x], element)) {
16451            return Optional.some(cellPosition(x, y));
16452          }
16453        }
16454      }
16455      return Optional.none();
16456    };
16457    var extractRows = function (table, sx, sy, ex, ey) {
16458      var newRows = [];
16459      var rows = table.rows;
16460      for (var y = sy; y <= ey; y++) {
16461        var cells = rows[y].cells;
16462        var slice = sx < ex ? cells.slice(sx, ex + 1) : cells.slice(ex, sx + 1);
16463        newRows.push(tableRow(rows[y].element, slice));
16464      }
16465      return newRows;
16466    };
16467    var subTable = function (table, startPos, endPos) {
16468      var sx = startPos.x, sy = startPos.y;
16469      var ex = endPos.x, ey = endPos.y;
16470      var newRows = sy < ey ? extractRows(table, sx, sy, ex, ey) : extractRows(table, sx, ey, ex, sy);
16471      return tableModel(table.element, getWidth(newRows), newRows);
16472    };
16473    var createDomTable = function (table, rows) {
16474      var tableElement = shallow(table.element);
16475      var tableBody = SugarElement.fromTag('tbody');
16476      append$1(tableBody, rows);
16477      append(tableElement, tableBody);
16478      return tableElement;
16479    };
16480    var modelRowsToDomRows = function (table) {
16481      return map(table.rows, function (row) {
16482        var cells = map(row.cells, function (cell) {
16483          var td = deep(cell);
16484          remove$1(td, 'colspan');
16485          remove$1(td, 'rowspan');
16486          return td;
16487        });
16488        var tr = shallow(row.element);
16489        append$1(tr, cells);
16490        return tr;
16491      });
16492    };
16493    var fromDom$1 = function (tableElm) {
16494      var table = tableModel(shallow(tableElm), 0, []);
16495      each(descendants$1(tableElm, 'tr'), function (tr, y) {
16496        each(descendants$1(tr, 'td,th'), function (td, x) {
16497          fillout(table, skipCellsX(table, x, y), y, tr, td);
16498        });
16499      });
16500      return tableModel(table.element, getWidth(table.rows), table.rows);
16501    };
16502    var toDom = function (table) {
16503      return createDomTable(table, modelRowsToDomRows(table));
16504    };
16505    var subsection = function (table, startElement, endElement) {
16506      return findElementPos(table, startElement).bind(function (startPos) {
16507        return findElementPos(table, endElement).map(function (endPos) {
16508          return subTable(table, startPos, endPos);
16509        });
16510      });
16511    };
16512
16513    var findParentListContainer = function (parents) {
16514      return find(parents, function (elm) {
16515        return name(elm) === 'ul' || name(elm) === 'ol';
16516      });
16517    };
16518    var getFullySelectedListWrappers = function (parents, rng) {
16519      return find(parents, function (elm) {
16520        return name(elm) === 'li' && hasAllContentsSelected(elm, rng);
16521      }).fold(constant([]), function (_li) {
16522        return findParentListContainer(parents).map(function (listCont) {
16523          var listElm = SugarElement.fromTag(name(listCont));
16524          var listStyles = filter$1(getAllRaw(listCont), function (_style, name) {
16525            return startsWith(name, 'list-style');
16526          });
16527          setAll$1(listElm, listStyles);
16528          return [
16529            SugarElement.fromTag('li'),
16530            listElm
16531          ];
16532        }).getOr([]);
16533      });
16534    };
16535    var wrap$3 = function (innerElm, elms) {
16536      var wrapped = foldl(elms, function (acc, elm) {
16537        append(elm, acc);
16538        return elm;
16539      }, innerElm);
16540      return elms.length > 0 ? fromElements([wrapped]) : wrapped;
16541    };
16542    var directListWrappers = function (commonAnchorContainer) {
16543      if (isListItem(commonAnchorContainer)) {
16544        return parent(commonAnchorContainer).filter(isList).fold(constant([]), function (listElm) {
16545          return [
16546            commonAnchorContainer,
16547            listElm
16548          ];
16549        });
16550      } else {
16551        return isList(commonAnchorContainer) ? [commonAnchorContainer] : [];
16552      }
16553    };
16554    var getWrapElements = function (rootNode, rng) {
16555      var commonAnchorContainer = SugarElement.fromDom(rng.commonAncestorContainer);
16556      var parents = parentsAndSelf(commonAnchorContainer, rootNode);
16557      var wrapElements = filter(parents, function (elm) {
16558        return isInline(elm) || isHeading(elm);
16559      });
16560      var listWrappers = getFullySelectedListWrappers(parents, rng);
16561      var allWrappers = wrapElements.concat(listWrappers.length ? listWrappers : directListWrappers(commonAnchorContainer));
16562      return map(allWrappers, shallow);
16563    };
16564    var emptyFragment = function () {
16565      return fromElements([]);
16566    };
16567    var getFragmentFromRange = function (rootNode, rng) {
16568      return wrap$3(SugarElement.fromDom(rng.cloneContents()), getWrapElements(rootNode, rng));
16569    };
16570    var getParentTable = function (rootElm, cell) {
16571      return ancestor$1(cell, 'table', curry(eq$2, rootElm));
16572    };
16573    var getTableFragment = function (rootNode, selectedTableCells) {
16574      return getParentTable(rootNode, selectedTableCells[0]).bind(function (tableElm) {
16575        var firstCell = selectedTableCells[0];
16576        var lastCell = selectedTableCells[selectedTableCells.length - 1];
16577        var fullTableModel = fromDom$1(tableElm);
16578        return subsection(fullTableModel, firstCell, lastCell).map(function (sectionedTableModel) {
16579          return fromElements([toDom(sectionedTableModel)]);
16580        });
16581      }).getOrThunk(emptyFragment);
16582    };
16583    var getSelectionFragment = function (rootNode, ranges) {
16584      return ranges.length > 0 && ranges[0].collapsed ? emptyFragment() : getFragmentFromRange(rootNode, ranges[0]);
16585    };
16586    var read$1 = function (rootNode, ranges) {
16587      var selectedCells = getCellsFromElementOrRanges(ranges, rootNode);
16588      return selectedCells.length > 0 ? getTableFragment(rootNode, selectedCells) : getSelectionFragment(rootNode, ranges);
16589    };
16590
16591    var trimLeadingCollapsibleText = function (text) {
16592      return text.replace(/^[ \f\n\r\t\v]+/, '');
16593    };
16594    var isCollapsibleWhitespace = function (text, index) {
16595      return index >= 0 && index < text.length && isWhiteSpace$1(text.charAt(index));
16596    };
16597    var getInnerText = function (bin) {
16598      var text = trim$2(bin.innerText);
16599      return Env.browser.isIE() ? trimLeadingCollapsibleText(text) : text;
16600    };
16601    var getTextContent = function (editor) {
16602      return Optional.from(editor.selection.getRng()).map(function (rng) {
16603        var bin = editor.dom.add(editor.getBody(), 'div', {
16604          'data-mce-bogus': 'all',
16605          'style': 'overflow: hidden; opacity: 0;'
16606        }, rng.cloneContents());
16607        var text = getInnerText(bin);
16608        var nonRenderedText = trim$2(bin.textContent);
16609        editor.dom.remove(bin);
16610        if (isCollapsibleWhitespace(nonRenderedText, 0) || isCollapsibleWhitespace(nonRenderedText, nonRenderedText.length - 1)) {
16611          var parentBlock = editor.dom.getParent(rng.commonAncestorContainer, editor.dom.isBlock);
16612          var parentBlockText = getInnerText(parentBlock);
16613          var textIndex = parentBlockText.indexOf(text);
16614          if (textIndex !== -1) {
16615            var hasProceedingSpace = isCollapsibleWhitespace(parentBlockText, textIndex - 1);
16616            var hasTrailingSpace = isCollapsibleWhitespace(parentBlockText, textIndex + text.length);
16617            return (hasProceedingSpace ? ' ' : '') + text + (hasTrailingSpace ? ' ' : '');
16618          } else {
16619            return text;
16620          }
16621        } else {
16622          return text;
16623        }
16624      }).getOr('');
16625    };
16626    var getSerializedContent = function (editor, args) {
16627      var rng = editor.selection.getRng(), tmpElm = editor.dom.create('body');
16628      var sel = editor.selection.getSel();
16629      var ranges = processRanges(editor, getRanges(sel));
16630      var fragment = args.contextual ? read$1(SugarElement.fromDom(editor.getBody()), ranges).dom : rng.cloneContents();
16631      if (fragment) {
16632        tmpElm.appendChild(fragment);
16633      }
16634      return editor.selection.serializer.serialize(tmpElm, args);
16635    };
16636    var getSelectedContentInternal = function (editor, format, args) {
16637      if (args === void 0) {
16638        args = {};
16639      }
16640      args.get = true;
16641      args.format = format;
16642      args.selection = true;
16643      args = editor.fire('BeforeGetContent', args);
16644      if (args.isDefaultPrevented()) {
16645        editor.fire('GetContent', args);
16646        return args.content;
16647      }
16648      if (args.format === 'text') {
16649        return getTextContent(editor);
16650      } else {
16651        args.getInner = true;
16652        var content = getSerializedContent(editor, args);
16653        if (args.format === 'tree') {
16654          return content;
16655        } else {
16656          args.content = editor.selection.isCollapsed() ? '' : content;
16657          editor.fire('GetContent', args);
16658          return args.content;
16659        }
16660      }
16661    };
16662
16663    var KEEP = 0, INSERT = 1, DELETE = 2;
16664    var diff = function (left, right) {
16665      var size = left.length + right.length + 2;
16666      var vDown = new Array(size);
16667      var vUp = new Array(size);
16668      var snake = function (start, end, diag) {
16669        return {
16670          start: start,
16671          end: end,
16672          diag: diag
16673        };
16674      };
16675      var buildScript = function (start1, end1, start2, end2, script) {
16676        var middle = getMiddleSnake(start1, end1, start2, end2);
16677        if (middle === null || middle.start === end1 && middle.diag === end1 - end2 || middle.end === start1 && middle.diag === start1 - start2) {
16678          var i = start1;
16679          var j = start2;
16680          while (i < end1 || j < end2) {
16681            if (i < end1 && j < end2 && left[i] === right[j]) {
16682              script.push([
16683                KEEP,
16684                left[i]
16685              ]);
16686              ++i;
16687              ++j;
16688            } else {
16689              if (end1 - start1 > end2 - start2) {
16690                script.push([
16691                  DELETE,
16692                  left[i]
16693                ]);
16694                ++i;
16695              } else {
16696                script.push([
16697                  INSERT,
16698                  right[j]
16699                ]);
16700                ++j;
16701              }
16702            }
16703          }
16704        } else {
16705          buildScript(start1, middle.start, start2, middle.start - middle.diag, script);
16706          for (var i2 = middle.start; i2 < middle.end; ++i2) {
16707            script.push([
16708              KEEP,
16709              left[i2]
16710            ]);
16711          }
16712          buildScript(middle.end, end1, middle.end - middle.diag, end2, script);
16713        }
16714      };
16715      var buildSnake = function (start, diag, end1, end2) {
16716        var end = start;
16717        while (end - diag < end2 && end < end1 && left[end] === right[end - diag]) {
16718          ++end;
16719        }
16720        return snake(start, end, diag);
16721      };
16722      var getMiddleSnake = function (start1, end1, start2, end2) {
16723        var m = end1 - start1;
16724        var n = end2 - start2;
16725        if (m === 0 || n === 0) {
16726          return null;
16727        }
16728        var delta = m - n;
16729        var sum = n + m;
16730        var offset = (sum % 2 === 0 ? sum : sum + 1) / 2;
16731        vDown[1 + offset] = start1;
16732        vUp[1 + offset] = end1 + 1;
16733        var d, k, i, x, y;
16734        for (d = 0; d <= offset; ++d) {
16735          for (k = -d; k <= d; k += 2) {
16736            i = k + offset;
16737            if (k === -d || k !== d && vDown[i - 1] < vDown[i + 1]) {
16738              vDown[i] = vDown[i + 1];
16739            } else {
16740              vDown[i] = vDown[i - 1] + 1;
16741            }
16742            x = vDown[i];
16743            y = x - start1 + start2 - k;
16744            while (x < end1 && y < end2 && left[x] === right[y]) {
16745              vDown[i] = ++x;
16746              ++y;
16747            }
16748            if (delta % 2 !== 0 && delta - d <= k && k <= delta + d) {
16749              if (vUp[i - delta] <= vDown[i]) {
16750                return buildSnake(vUp[i - delta], k + start1 - start2, end1, end2);
16751              }
16752            }
16753          }
16754          for (k = delta - d; k <= delta + d; k += 2) {
16755            i = k + offset - delta;
16756            if (k === delta - d || k !== delta + d && vUp[i + 1] <= vUp[i - 1]) {
16757              vUp[i] = vUp[i + 1] - 1;
16758            } else {
16759              vUp[i] = vUp[i - 1];
16760            }
16761            x = vUp[i] - 1;
16762            y = x - start1 + start2 - k;
16763            while (x >= start1 && y >= start2 && left[x] === right[y]) {
16764              vUp[i] = x--;
16765              y--;
16766            }
16767            if (delta % 2 === 0 && -d <= k && k <= d) {
16768              if (vUp[i] <= vDown[i + delta]) {
16769                return buildSnake(vUp[i], k + start1 - start2, end1, end2);
16770              }
16771            }
16772          }
16773        }
16774      };
16775      var script = [];
16776      buildScript(0, left.length, 0, right.length, script);
16777      return script;
16778    };
16779
16780    var getOuterHtml = function (elm) {
16781      if (isElement$1(elm)) {
16782        return elm.outerHTML;
16783      } else if (isText$1(elm)) {
16784        return Entities.encodeRaw(elm.data, false);
16785      } else if (isComment$1(elm)) {
16786        return '<!--' + elm.data + '-->';
16787      }
16788      return '';
16789    };
16790    var createFragment$1 = function (html) {
16791      var node;
16792      var container = document.createElement('div');
16793      var frag = document.createDocumentFragment();
16794      if (html) {
16795        container.innerHTML = html;
16796      }
16797      while (node = container.firstChild) {
16798        frag.appendChild(node);
16799      }
16800      return frag;
16801    };
16802    var insertAt = function (elm, html, index) {
16803      var fragment = createFragment$1(html);
16804      if (elm.hasChildNodes() && index < elm.childNodes.length) {
16805        var target = elm.childNodes[index];
16806        target.parentNode.insertBefore(fragment, target);
16807      } else {
16808        elm.appendChild(fragment);
16809      }
16810    };
16811    var removeAt = function (elm, index) {
16812      if (elm.hasChildNodes() && index < elm.childNodes.length) {
16813        var target = elm.childNodes[index];
16814        target.parentNode.removeChild(target);
16815      }
16816    };
16817    var applyDiff = function (diff, elm) {
16818      var index = 0;
16819      each(diff, function (action) {
16820        if (action[0] === KEEP) {
16821          index++;
16822        } else if (action[0] === INSERT) {
16823          insertAt(elm, action[1], index);
16824          index++;
16825        } else if (action[0] === DELETE) {
16826          removeAt(elm, index);
16827        }
16828      });
16829    };
16830    var read$2 = function (elm) {
16831      return filter(map(from$1(elm.childNodes), getOuterHtml), function (item) {
16832        return item.length > 0;
16833      });
16834    };
16835    var write = function (fragments, elm) {
16836      var currentFragments = map(from$1(elm.childNodes), getOuterHtml);
16837      applyDiff(diff(currentFragments, fragments), elm);
16838      return elm;
16839    };
16840
16841    var undoLevelDocument = Cell(Optional.none());
16842    var lazyTempDocument = function () {
16843      return undoLevelDocument.get().getOrThunk(function () {
16844        var doc = document.implementation.createHTMLDocument('undo');
16845        undoLevelDocument.set(Optional.some(doc));
16846        return doc;
16847      });
16848    };
16849    var hasIframes = function (html) {
16850      return html.indexOf('</iframe>') !== -1;
16851    };
16852    var createFragmentedLevel = function (fragments) {
16853      return {
16854        type: 'fragmented',
16855        fragments: fragments,
16856        content: '',
16857        bookmark: null,
16858        beforeBookmark: null
16859      };
16860    };
16861    var createCompleteLevel = function (content) {
16862      return {
16863        type: 'complete',
16864        fragments: null,
16865        content: content,
16866        bookmark: null,
16867        beforeBookmark: null
16868      };
16869    };
16870    var createFromEditor = function (editor) {
16871      var fragments = read$2(editor.getBody());
16872      var trimmedFragments = bind(fragments, function (html) {
16873        var trimmed = trimInternal(editor.serializer, html);
16874        return trimmed.length > 0 ? [trimmed] : [];
16875      });
16876      var content = trimmedFragments.join('');
16877      return hasIframes(content) ? createFragmentedLevel(trimmedFragments) : createCompleteLevel(content);
16878    };
16879    var applyToEditor = function (editor, level, before) {
16880      if (level.type === 'fragmented') {
16881        write(level.fragments, editor.getBody());
16882      } else {
16883        editor.setContent(level.content, { format: 'raw' });
16884      }
16885      editor.selection.moveToBookmark(before ? level.beforeBookmark : level.bookmark);
16886    };
16887    var getLevelContent = function (level) {
16888      return level.type === 'fragmented' ? level.fragments.join('') : level.content;
16889    };
16890    var getCleanLevelContent = function (level) {
16891      var elm = SugarElement.fromTag('body', lazyTempDocument());
16892      set$1(elm, getLevelContent(level));
16893      each(descendants$1(elm, '*[data-mce-bogus]'), unwrap);
16894      return get$6(elm);
16895    };
16896    var hasEqualContent = function (level1, level2) {
16897      return getLevelContent(level1) === getLevelContent(level2);
16898    };
16899    var hasEqualCleanedContent = function (level1, level2) {
16900      return getCleanLevelContent(level1) === getCleanLevelContent(level2);
16901    };
16902    var isEq$4 = function (level1, level2) {
16903      if (!level1 || !level2) {
16904        return false;
16905      } else if (hasEqualContent(level1, level2)) {
16906        return true;
16907      } else {
16908        return hasEqualCleanedContent(level1, level2);
16909      }
16910    };
16911
16912    var isUnlocked = function (locks) {
16913      return locks.get() === 0;
16914    };
16915
16916    var setTyping = function (undoManager, typing, locks) {
16917      if (isUnlocked(locks)) {
16918        undoManager.typing = typing;
16919      }
16920    };
16921    var endTyping = function (undoManager, locks) {
16922      if (undoManager.typing) {
16923        setTyping(undoManager, false, locks);
16924        undoManager.add();
16925      }
16926    };
16927    var endTypingLevelIgnoreLocks = function (undoManager) {
16928      if (undoManager.typing) {
16929        undoManager.typing = false;
16930        undoManager.add();
16931      }
16932    };
16933
16934    var beforeChange = function (editor, locks, beforeBookmark) {
16935      if (isUnlocked(locks)) {
16936        beforeBookmark.set(Optional.some(getUndoBookmark(editor.selection)));
16937      }
16938    };
16939    var addUndoLevel = function (editor, undoManager, index, locks, beforeBookmark, level, event) {
16940      var currentLevel = createFromEditor(editor);
16941      level = level || {};
16942      level = Tools.extend(level, currentLevel);
16943      if (isUnlocked(locks) === false || editor.removed) {
16944        return null;
16945      }
16946      var lastLevel = undoManager.data[index.get()];
16947      if (editor.fire('BeforeAddUndo', {
16948          level: level,
16949          lastLevel: lastLevel,
16950          originalEvent: event
16951        }).isDefaultPrevented()) {
16952        return null;
16953      }
16954      if (lastLevel && isEq$4(lastLevel, level)) {
16955        return null;
16956      }
16957      if (undoManager.data[index.get()]) {
16958        beforeBookmark.get().each(function (bm) {
16959          undoManager.data[index.get()].beforeBookmark = bm;
16960        });
16961      }
16962      var customUndoRedoLevels = getCustomUndoRedoLevels(editor);
16963      if (customUndoRedoLevels) {
16964        if (undoManager.data.length > customUndoRedoLevels) {
16965          for (var i = 0;
16965 i < undoManager.data.length - 1; i++) {
16966            undoManager.data[i] = undoManager.data[i + 1];
16967          }
16968          undoManager.data.length--;
16969          index.set(undoManager.data.length);
16970        }
16971      }
16972      level.bookmark = getUndoBookmark(editor.selection);
16973      if (index.get() < undoManager.data.length - 1) {
16974        undoManager.data.length = index.get() + 1;
16975      }
16976      undoManager.data.push(level);
16977      index.set(undoManager.data.length - 1);
16978      var args = {
16979        level: level,
16980        lastLevel: lastLevel,
16981        originalEvent: event
16982      };
16983      if (index.get() > 0) {
16984        editor.setDirty(true);
16985        editor.fire('AddUndo', args);
16986        editor.fire('change', args);
16987      } else {
16988        editor.fire('AddUndo', args);
16989      }
16990      return level;
16991    };
16992    var clear = function (editor, undoManager, index) {
16993      undoManager.data = [];
16994      index.set(0);
16995      undoManager.typing = false;
16996      editor.fire('ClearUndos');
16997    };
16998    var extra = function (editor, undoManager, index, callback1, callback2) {
16999      if (undoManager.transact(callback1)) {
17000        var bookmark = undoManager.data[index.get()].bookmark;
17001        var lastLevel = undoManager.data[index.get() - 1];
17002        applyToEditor(editor, lastLevel, true);
17003        if (undoManager.transact(callback2)) {
17004          undoManager.data[index.get() - 1].beforeBookmark = bookmark;
17005        }
17006      }
17007    };
17008    var redo = function (editor, index, data) {
17009      var level;
17010      if (index.get() < data.length - 1) {
17011        index.set(index.get() + 1);
17012        level = data[index.get()];
17013        applyToEditor(editor, level, false);
17014        editor.setDirty(true);
17015        editor.fire('Redo', { level: level });
17016      }
17017      return level;
17018    };
17019    var undo = function (editor, undoManager, locks, index) {
17020      var level;
17021      if (undoManager.typing) {
17022        undoManager.add();
17023        undoManager.typing = false;
17024        setTyping(undoManager, false, locks);
17025      }
17026      if (index.get() > 0) {
17027        index.set(index.get() - 1);
17028        level = undoManager.data[index.get()];
17029        applyToEditor(editor, level, true);
17030        editor.setDirty(true);
17031        editor.fire('Undo', { level: level });
17032      }
17033      return level;
17034    };
17035    var reset = function (undoManager) {
17036      undoManager.clear();
17037      undoManager.add();
17038    };
17039    var hasUndo = function (editor, undoManager, index) {
17040      return index.get() > 0 || undoManager.typing && undoManager.data[0] && !isEq$4(createFromEditor(editor), undoManager.data[0]);
17041    };
17042    var hasRedo = function (undoManager, index) {
17043      return index.get() < undoManager.data.length - 1 && !undoManager.typing;
17044    };
17045    var transact = function (undoManager, locks, callback) {
17046      endTyping(undoManager, locks);
17047      undoManager.beforeChange();
17048      undoManager.ignore(callback);
17049      return undoManager.add();
17050    };
17051    var ignore = function (locks, callback) {
17052      try {
17053        locks.set(locks.get() + 1);
17054        callback();
17055      } finally {
17056        locks.set(locks.get() - 1);
17057      }
17058    };
17059
17060    var isTreeNode$1 = function (content) {
17061      return content instanceof AstNode;
17062    };
17063    var runSerializerFiltersOnFragment = function (editor, fragment) {
17064      filter$3(editor.serializer.getNodeFilters(), editor.serializer.getAttributeFilters(), fragment);
17065    };
17066    var getInsertContext = function (editor) {
17067      return Optional.from(editor.selection.getStart(true)).map(function (elm) {
17068        return elm.nodeName.toLowerCase();
17069      });
17070    };
17071    var createDummyUndoLevel = function () {
17072      return {
17073        type: 'complete',
17074        fragments: [],
17075        content: '',
17076        bookmark: null,
17077        beforeBookmark: null
17078      };
17079    };
17080    var makePlainAdaptor = function (editor) {
17081      return {
17082        undoManager: {
17083          beforeChange: function (locks, beforeBookmark) {
17084            return beforeChange(editor, locks, beforeBookmark);
17085          },
17086          addUndoLevel: function (undoManager, index, locks, beforeBookmark, level, event) {
17087            return addUndoLevel(editor, undoManager, index, locks, beforeBookmark, level, event);
17088          },
17089          undo: function (undoManager, locks, index) {
17090            return undo(editor, undoManager, locks, index);
17091          },
17092          redo: function (index, data) {
17093            return redo(editor, index, data);
17094          },
17095          clear: function (undoManager, index) {
17096            return clear(editor, undoManager, index);
17097          },
17098          reset: function (undoManager) {
17099            return reset(undoManager);
17100          },
17101          hasUndo: function (undoManager, index) {
17102            return hasUndo(editor, undoManager, index);
17103          },
17104          hasRedo: function (undoManager, index) {
17105            return hasRedo(undoManager, index);
17106          },
17107          transact: function (undoManager, locks, callback) {
17108            return transact(undoManager, locks, callback);
17109          },
17110          ignore: function (locks, callback) {
17111            return ignore(locks, callback);
17112          },
17113          extra: function (undoManager, index, callback1, callback2) {
17114            return extra(editor, undoManager, index, callback1, callback2);
17115          }
17116        },
17117        formatter: {
17118          apply: function (name, vars, node) {
17119            return applyFormat(editor, name, vars, node);
17120          },
17121          remove: function (name, vars, node, similar) {
17122            return remove$6(editor, name, vars, node, similar);
17123          },
17124          toggle: function (name, vars, node) {
17125            return toggle(editor, name, vars, node);
17126          }
17127        },
17128        editor: {
17129          getContent: function (args, format) {
17130            return getContentInternal(editor, args, format);
17131          },
17132          setContent: function (content, args) {
17133            return setContentInternal(editor, content, args);
17134          },
17135          insertContent: function (value, details) {
17136            return insertHtmlAtCaret(editor, value, details);
17137          }
17138        },
17139        selection: {
17140          getContent: function (format, args) {
17141            return getSelectedContentInternal(editor, format, args);
17142          }
17143        },
17144        raw: {
17145          getModel: function () {
17146            return Optional.none();
17147          }
17148        }
17149      };
17150    };
17151    var makeRtcAdaptor = function (tinymceEditor, rtcEditor) {
17152      var defaultVars = function (vars) {
17153        return isObject(vars) ? vars : {};
17154      };
17155      var unsupported = die('Unimplemented feature for rtc');
17156      var ignore = noop;
17157      return {
17158        undoManager: {
17159          beforeChange: ignore,
17160          addUndoLevel: unsupported,
17161          undo: function () {
17162            rtcEditor.undo();
17163            return createDummyUndoLevel();
17164          },
17165          redo: function () {
17166            rtcEditor.redo();
17167            return createDummyUndoLevel();
17168          },
17169          clear: unsupported,
17170          reset: unsupported,
17171          hasUndo: function () {
17172            return rtcEditor.hasUndo();
17173          },
17174          hasRedo: function () {
17175            return rtcEditor.hasRedo();
17176          },
17177          transact: function (_undoManager, _locks, fn) {
17178            rtcEditor.transact(fn);
17179            return createDummyUndoLevel();
17180          },
17181          ignore: unsupported,
17182          extra: unsupported
17183        },
17184        formatter: {
17185          apply: function (name, vars, _node) {
17186            return rtcEditor.applyFormat(name, defaultVars(vars));
17187          },
17188          remove: function (name, vars, _node, _similar) {
17189            return rtcEditor.removeFormat(name, defaultVars(vars));
17190          },
17191          toggle: function (name, vars, _node) {
17192            return rtcEditor.toggleFormat(name, defaultVars(vars));
17193          }
17194        },
17195        editor: {
17196          getContent: function (args, format) {
17197            if (format === 'html' || format === 'tree') {
17198              var fragment = rtcEditor.getContent();
17199              var serializer = HtmlSerializer({ inner: true });
17200              runSerializerFiltersOnFragment(tinymceEditor, fragment);
17201              return format === 'tree' ? fragment : serializer.serialize(fragment);
17202            } else {
17203              return makePlainAdaptor(tinymceEditor).editor.getContent(args, format);
17204            }
17205          },
17206          setContent: function (content, _args) {
17207            var fragment = isTreeNode$1(content) ? content : tinymceEditor.parser.parse(content, {
17208              isRootContent: true,
17209              insert: true
17210            });
17211            rtcEditor.setContent(fragment);
17212            return content;
17213          },
17214          insertContent: function (value, _details) {
17215            var contextArgs = getInsertContext(tinymceEditor).fold(function () {
17216              return {};
17217            }, function (context) {
17218              return { context: context };
17219            });
17220            var fragment = isTreeNode$1(value) ? value : tinymceEditor.parser.parse(value, __assign(__assign({}, contextArgs), { insert: true }));
17221            rtcEditor.insertContent(fragment);
17222          }
17223        },
17224        selection: {
17225          getContent: function (format, args) {
17226            if (format === 'html' || format === 'tree') {
17227              var fragment = rtcEditor.getSelectedContent();
17228              var serializer = HtmlSerializer({});
17229              runSerializerFiltersOnFragment(tinymceEditor, fragment);
17230              return format === 'tree' ? fragment : serializer.serialize(fragment);
17231            } else {
17232              return makePlainAdaptor(tinymceEditor).selection.getContent(format, args);
17233            }
17234          }
17235        },
17236        raw: {
17237          getModel: function () {
17238            return Optional.some(rtcEditor.getRawModel());
17239          }
17240        }
17241      };
17242    };
17243    var isRtc = function (editor) {
17244      return has(editor.plugins, 'rtc');
17245    };
17246    var setup$4 = function (editor) {
17247      var editorCast = editor;
17248      return get(editor.plugins, 'rtc').fold(function () {
17249        editorCast.rtcInstance = makePlainAdaptor(editor);
17250        return Optional.none();
17251      }, function (rtc) {
17252        return Optional.some(rtc.setup().then(function (rtcEditor) {
17253          editorCast.rtcInstance = makeRtcAdaptor(editor, rtcEditor);
17254          return rtcEditor.isRemote;
17255        }));
17256      });
17257    };
17258    var getRtcInstanceWithFallback = function (editor) {
17259      return editor.rtcInstance ? editor.rtcInstance : makePlainAdaptor(editor);
17260    };
17261    var getRtcInstanceWithError = function (editor) {
17262      var rtcInstance = editor.rtcInstance;
17263      if (!rtcInstance) {
17264        throw new Error('Failed to get RTC instance not yet initialized.');
17265      } else {
17266        return rtcInstance;
17267      }
17268    };
17269    var beforeChange$1 = function (editor, locks, beforeBookmark) {
17270      getRtcInstanceWithError(editor).undoManager.beforeChange(locks, beforeBookmark);
17271    };
17272    var addUndoLevel$1 = function (editor, undoManager, index, locks, beforeBookmark, level, event) {
17273      return getRtcInstanceWithError(editor).undoManager.addUndoLevel(undoManager, index, locks, beforeBookmark, level, event);
17274    };
17275    var undo$1 = function (editor, undoManager, locks, index) {
17276      return getRtcInstanceWithError(editor).undoManager.undo(undoManager, locks, index);
17277    };
17278    var redo$1 = function (editor, index, data) {
17279      return getRtcInstanceWithError(editor).undoManager.redo(index, data);
17280    };
17281    var clear$1 = function (editor, undoManager, index) {
17282      getRtcInstanceWithError(editor).undoManager.clear(undoManager, index);
17283    };
17284    var reset$1 = function (editor, undoManager) {
17285      getRtcInstanceWithError(editor).undoManager.reset(undoManager);
17286    };
17287    var hasUndo$1 = function (editor, undoManager, index) {
17288      return getRtcInstanceWithError(editor).undoManager.hasUndo(undoManager, index);
17289    };
17290    var hasRedo$1 = function (editor, undoManager, index) {
17291      return getRtcInstanceWithError(editor).undoManager.hasRedo(undoManager, index);
17292    };
17293    var transact$1 = function (editor, undoManager, locks, callback) {
17294      return getRtcInstanceWithError(editor).undoManager.transact(undoManager, locks, callback);
17295    };
17296    var ignore$1 = function (editor, locks, callback) {
17297      getRtcInstanceWithError(editor).undoManager.ignore(locks, callback);
17298    };
17299    var extra$1 = function (editor, undoManager, index, callback1, callback2) {
17300      getRtcInstanceWithError(editor).undoManager.extra(undoManager, index, callback1, callback2);
17301    };
17302    var applyFormat$1 = function (editor, name, vars, node) {
17303      getRtcInstanceWithError(editor).formatter.apply(name, vars, node);
17304    };
17305    var removeFormat$1 = function (editor, name, vars, node, similar) {
17306      getRtcInstanceWithError(editor).formatter.remove(name, vars, node, similar);
17307    };
17308    var toggleFormat = function (editor, name, vars, node) {
17309      getRtcInstanceWithError(editor).formatter.toggle(name, vars, node);
17310    };
17311    var getContent = function (editor, args, format) {
17312      return getRtcInstanceWithFallback(editor).editor.getContent(args, format);
17313    };
17314    var setContent = function (editor, content, args) {
17315      return getRtcInstanceWithFallback(editor).editor.setContent(content, args);
17316    };
17317    var insertContent = function (editor, value, details) {
17318      return getRtcInstanceWithFallback(editor).editor.insertContent(value, details);
17319    };
17320    var getSelectedContent = function (editor, format, args) {
17321      return getRtcInstanceWithError(editor).selection.getContent(format, args);
17322    };
17323
17324    var getContent$1 = function (editor, args) {
17325      if (args === void 0) {
17326        args = {};
17327      }
17328      var format = args.format ? args.format : 'html';
17329      return getSelectedContent(editor, format, args);
17330    };
17331
17332    var removeEmpty = function (text) {
17333      if (text.dom.length === 0) {
17334        remove(text);
17335        return Optional.none();
17336      } else {
17337        return Optional.some(text);
17338      }
17339    };
17340    var walkPastBookmark = function (node, start) {
17341      return node.filter(function (elm) {
17342        return BookmarkManager$1.isBookmarkNode(elm.dom);
17343      }).bind(start ? nextSibling : prevSibling);
17344    };
17345    var merge = function (outer, inner, rng, start) {
17346      var outerElm = outer.dom;
17347      var innerElm = inner.dom;
17348      var oldLength = start ? outerElm.length : innerElm.length;
17349      if (start) {
17350        mergeTextNodes(outerElm, innerElm, false, !start);
17351        rng.setStart(innerElm, oldLength);
17352      } else {
17353        mergeTextNodes(innerElm, outerElm, false, !start);
17354        rng.setEnd(innerElm, oldLength);
17355      }
17356    };
17357    var normalizeTextIfRequired = function (inner, start) {
17358      parent(inner).each(function (root) {
17359        var text = inner.dom;
17360        if (start && needsToBeNbspLeft(root, CaretPosition$1(text, 0))) {
17361          normalizeWhitespaceAfter(text, 0);
17362        } else if (!start && needsToBeNbspRight(root, CaretPosition$1(text, text.length))) {
17363          normalizeWhitespaceBefore(text, text.length);
17364        }
17365      });
17366    };
17367    var mergeAndNormalizeText = function (outerNode, innerNode, rng, start) {
17368      outerNode.bind(function (outer) {
17369        var normalizer = start ? normalizeWhitespaceBefore : normalizeWhitespaceAfter;
17370        normalizer(outer.dom, start ? outer.dom.length : 0);
17371        return innerNode.filter(isText).map(function (inner) {
17372          return merge(outer, inner, rng, start);
17373        });
17374      }).orThunk(function () {
17375        var innerTextNode = walkPastBookmark(innerNode, start).or(innerNode).filter(isText);
17376        return innerTextNode.map(function (inner) {
17377          return normalizeTextIfRequired(inner, start);
17378        });
17379      });
17380    };
17381    var rngSetContent = function (rng, fragment) {
17382      var firstChild = Optional.from(fragment.firstChild).map(SugarElement.fromDom);
17383      var lastChild = Optional.from(fragment.lastChild).map(SugarElement.fromDom);
17384      rng.deleteContents();
17385      rng.insertNode(fragment);
17386      var prevText = firstChild.bind(prevSibling).filter(isText).bind(removeEmpty);
17387      var nextText = lastChild.bind(nextSibling).filter(isText).bind(removeEmpty);
17388      mergeAndNormalizeText(prevText, firstChild, rng, true);
17389      mergeAndNormalizeText(nextText, lastChild, rng, false);
17390      rng.collapse(false);
17391    };
17392    var setupArgs = function (args, content) {
17393      return __assign(__assign({ format: 'html' }, args), {
17394        set: true,
17395        selection: true,
17396        content: content
17397      });
17398    };
17399    var cleanContent = function (editor, args) {
17400      if (args.format !== 'raw') {
17401        var rng = editor.selection.getRng();
17402        var contextBlock = editor.dom.getParent(rng.commonAncestorContainer, editor.dom.isBlock);
17403        var contextArgs = contextBlock ? { context: contextBlock.nodeName.toLowerCase() } : {};
17404        var node = editor.parser.parse(args.content, __assign(__assign({
17405          isRootContent: true,
17406          forced_root_block: false
17407        }, contextArgs), args));
17408        return HtmlSerializer({ validate: editor.validate }, editor.schema).serialize(node);
17409      } else {
17410        return args.content;
17411      }
17412    };
17413    var setContent$1 = function (editor, content, args) {
17414      if (args === void 0) {
17415        args = {};
17416      }
17417      var contentArgs = setupArgs(args, content);
17418      if (!contentArgs.no_events) {
17419        contentArgs = editor.fire('BeforeSetContent', contentArgs);
17420        if (contentArgs.isDefaultPrevented()) {
17421          editor.fire('SetContent', contentArgs);
17422          return;
17423        }
17424      }
17425      args.content = cleanContent(editor, contentArgs);
17426      var rng = editor.selection.getRng();
17427      rngSetContent(rng, rng.createContextualFragment(args.content));
17428      editor.selection.setRng(rng);
17429      scrollRangeIntoView(editor, rng);
17430      if (!contentArgs.no_events) {
17431        editor.fire('SetContent', contentArgs);
17432      }
17433    };
17434
17435    var deleteFromCallbackMap = function (callbackMap, selector, callback) {
17436      if (callbackMap && callbackMap.hasOwnProperty(selector)) {
17437        var newCallbacks = filter(callbackMap[selector], function (cb) {
17438          return cb !== callback;
17439        });
17440        if (newCallbacks.length === 0) {
17441          delete callbackMap[selector];
17442        } else {
17443          callbackMap[selector] = newCallbacks;
17444        }
17445      }
17446    };
17447    function SelectorChanged (dom, editor) {
17448      var selectorChangedData;
17449      var currentSelectors;
17450      return {
17451        selectorChangedWithUnbind: function (selector, callback) {
17452          if (!selectorChangedData) {
17453            selectorChangedData = {};
17454            currentSelectors = {};
17455            editor.on('NodeChange', function (e) {
17456              var node = e.element, parents = dom.getParents(node, null, dom.getRoot()), matchedSelectors = {};
17457              Tools.each(selectorChangedData, function (callbacks, selector) {
17458                Tools.each(parents, function (node) {
17459                  if (dom.is(node, selector)) {
17460                    if (!currentSelectors[selector]) {
17461                      Tools.each(callbacks, function (callback) {
17462                        callback(true, {
17463                          node: node,
17464                          selector: selector,
17465                          parents: parents
17466                        });
17467                      });
17468                      currentSelectors[selector] = callbacks;
17469                    }
17470                    matchedSelectors[selector] = callbacks;
17471                    return false;
17472                  }
17473                });
17474              });
17475              Tools.each(currentSelectors, function (callbacks, selector) {
17476                if (!matchedSelectors[selector]) {
17477                  delete currentSelectors[selector];
17478                  Tools.each(callbacks, function (callback) {
17479                    callback(false, {
17480                      node: node,
17481                      selector: selector,
17482                      parents: parents
17483                    });
17484                  });
17485                }
17486              });
17487            });
17488          }
17489          if (!selectorChangedData[selector]) {
17490            selectorChangedData[selector] = [];
17491          }
17492          selectorChangedData[selector].push(callback);
17493          return {
17494            unbind: function () {
17495              deleteFromCallbackMap(selectorChangedData, selector, callback);
17496              deleteFromCallbackMap(currentSelectors, selector, callback);
17497            }
17498          };
17499        }
17500      };
17501    }
17502
17503    var isNativeIeSelection = function (rng) {
17504      return !!rng.select;
17505    };
17506    var isAttachedToDom = function (node) {
17507      return !!(node && node.ownerDocument) && contains$2(SugarElement.fromDom(node.ownerDocument), SugarElement.fromDom(node));
17508    };
17509    var isValidRange = function (rng) {
17510      if (!rng) {
17511        return false;
17512      } else if (isNativeIeSelection(rng)) {
17513        return true;
17514      } else {
17515        return isAttachedToDom(rng.startContainer) && isAttachedToDom(rng.endContainer);
17516      }
17517    };
17518    var EditorSelection = function (dom, win, serializer, editor) {
17519      var selectedRange;
17520      var explicitRange;
17521      var selectorChangedWithUnbind = SelectorChanged(dom, editor).selectorChangedWithUnbind;
17522      var setCursorLocation = function (node, offset) {
17523        var rng = dom.createRng();
17524        if (!node) {
17525          moveEndPoint$1(dom, rng, editor.getBody(), true);
17526          setRng(rng);
17527        } else {
17528          rng.setStart(node, offset);
17529          rng.setEnd(node, offset);
17530          setRng(rng);
17531          collapse(false);
17532        }
17533      };
17534      var getContent = function (args) {
17535        return getContent$1(editor, args);
17536      };
17537      var setContent = function (content, args) {
17538        return setContent$1(editor, content, args);
17539      };
17540      var getStart = function (real) {
17541        return getStart$2(editor.getBody(), getRng$1(), real);
17542      };
17543      var getEnd$1 = function (real) {
17544        return getEnd(editor.getBody(), getRng$1(), real);
17545      };
17546      var getBookmark = function (type, normalized) {
17547        return bookmarkManager.getBookmark(type, normalized);
17548      };
17549      var moveToBookmark = function (bookmark) {
17550        return bookmarkManager.moveToBookmark(bookmark);
17551      };
17552      var select = function (node, content) {
17553        select$1(dom, node, content).each(setRng);
17554        return node;
17555      };
17556      var isCollapsed = function () {
17557        var rng = getRng$1(), sel = getSel();
17558        if (!rng || rng.item) {
17559          return false;
17560        }
17561        if (rng.compareEndPoints) {
17562          return rng.compareEndPoints('StartToEnd', rng) === 0;
17563        }
17564        return !sel || rng.collapsed;
17565      };
17566      var collapse = function (toStart) {
17567        var rng = getRng$1();
17568        rng.collapse(!!toStart);
17569        setRng(rng);
17570      };
17571      var getSel = function () {
17572        return win.getSelection ? win.getSelection() : win.document.selection;
17573      };
17574      var getRng$1 = function () {
17575        var selection, rng, elm;
17576        var tryCompareBoundaryPoints = function (how, sourceRange, destinationRange) {
17577          try {
17578            return sourceRange.compareBoundaryPoints(how, destinationRange);
17579          } catch (ex) {
17580            return -1;
17581          }
17582        };
17583        if (!win) {
17584          return null;
17585        }
17586        var doc = win.document;
17587        if (typeof doc === 'undefined' || doc === null) {
17588          return null;
17589        }
17590        if (editor.bookmark !== undefined && hasFocus$1(editor) === false) {
17591          var bookmark = getRng(editor);
17592          if (bookmark.isSome()) {
17593            return bookmark.map(function (r) {
17594              return processRanges(editor, [r])[0];
17595            }).getOr(doc.createRange());
17596          }
17597        }
17598        try {
17599          if ((selection = getSel()) && !isRestrictedNode(selection.anchorNode)) {
17600            if (selection.rangeCount > 0) {
17601              rng = selection.getRangeAt(0);
17602            } else {
17603              rng = selection.createRange ? selection.createRange() : doc.createRange();
17604            }
17605            rng = processRanges(editor, [rng])[0];
17606          }
17607        } catch (ex) {
17608        }
17609        if (!rng) {
17610          rng = doc.createRange ? doc.createRange() : doc.body.createTextRange();
17611        }
17612        if (rng.setStart && rng.startContainer.nodeType === 9 && rng.collapsed) {
17613          elm = dom.getRoot();
17614          rng.setStart(elm, 0);
17615          rng.setEnd(elm, 0);
17616        }
17617        if (selectedRange && explicitRange) {
17618          if (tryCompareBoundaryPoints(rng.START_TO_START, rng, selectedRange) === 0 && tryCompareBoundaryPoints(rng.END_TO_END, rng, selectedRange) === 0) {
17619            rng = explicitRange;
17620          } else {
17621            selectedRange = null;
17622            explicitRange = null;
17623          }
17624        }
17625        return rng;
17626      };
17627      var setRng = function (rng, forward) {
17628        var node;
17629        if (!isValidRange(rng)) {
17630          return;
17631        }
17632        var ieRange = isNativeIeSelection(rng) ? rng : null;
17633        if (ieRange) {
17634          explicitRange = null;
17635          try {
17636            ieRange.select();
17637          } catch (ex) {
17638          }
17639          return;
17640        }
17641        var sel = getSel();
17642        var evt = editor.fire('SetSelectionRange', {
17643          range: rng,
17644          forward: forward
17645        });
17646        rng = evt.range;
17647        if (sel) {
17648          explicitRange = rng;
17649          try {
17650            sel.removeAllRanges();
17651            sel.addRange(rng);
17652          } catch (ex) {
17653          }
17654          if (forward === false && sel.extend) {
17655            sel.collapse(rng.endContainer, rng.endOffset);
17656            sel.extend(rng.startContainer, rng.startOffset);
17657          }
17658          selectedRange = sel.rangeCount > 0 ? sel.getRangeAt(0) : null;
17659        }
17660        if (!rng.collapsed && rng.startContainer === rng.endContainer && sel.setBaseAndExtent && !Env.ie) {
17661          if (rng.endOffset - rng.startOffset < 2) {
17662            if (rng.startContainer.hasChildNodes()) {
17663              node = rng.startContainer.childNodes[rng.startOffset];
17664              if (node && node.tagName === 'IMG') {
17665                sel.setBaseAndExtent(rng.startContainer, rng.startOffset, rng.endContainer, rng.endOffset);
17666                if (sel.anchorNode !== rng.startContainer || sel.focusNode !== rng.endContainer) {
17667                  sel.setBaseAndExtent(node, 0, node, 1);
17668                }
17669              }
17670            }
17671          }
17672        }
17673        editor.fire('AfterSetSelectionRange', {
17674          range: rng,
17675          forward: forward
17676        });
17677      };
17678      var setNode = function (elm) {
17679        setContent(dom.getOuterHTML(elm));
17680        return elm;
17681      };
17682      var getNode = function () {
17683        return getNode$1(editor.getBody(), getRng$1());
17684      };
17685      var getSelectedBlocks$1 = function (startElm, endElm) {
17686        return getSelectedBlocks(dom, getRng$1(), startElm, endElm);
17687      };
17688      var isForward = function () {
17689        var sel = getSel();
17690        var anchorNode = sel === null || sel === void 0 ? void 0 : sel.anchorNode;
17691        var focusNode = sel === null || sel === void 0 ? void 0 : sel.focusNode;
17692        if (!sel || !anchorNode || !focusNode || isRestrictedNode(anchorNode) || isRestrictedNode(focusNode)) {
17693          return true;
17694        }
17695        var anchorRange = dom.createRng();
17696        anchorRange.setStart(anchorNode, sel.anchorOffset);
17697        anchorRange.collapse(true);
17698        var focusRange = dom.createRng();
17699        focusRange.setStart(focusNode, sel.focusOffset);
17700        focusRange.collapse(true);
17701        return anchorRange.compareBoundaryPoints(anchorRange.START_TO_START, focusRange) <= 0;
17702      };
17703      var normalize$1 = function () {
17704        var rng = getRng$1();
17705        var sel = getSel();
17706        if (!hasMultipleRanges(sel) && hasAnyRanges(editor)) {
17707          var normRng = normalize(dom, rng);
17708          normRng.each(function (normRng) {
17709            setRng(normRng, isForward());
17710          });
17711          return normRng.getOr(rng);
17712        }
17713        return rng;
17714      };
17715      var selectorChanged = function (selector, callback) {
17716        selectorChangedWithUnbind(selector, callback);
17717        return exports;
17718      };
17719      var getScrollContainer = function () {
17720        var scrollContainer;
17721        var node = dom.getRoot();
17722        while (node && node.nodeName !== 'BODY') {
17723          if (node.scrollHeight > node.clientHeight) {
17724            scrollContainer = node;
17725            break;
17726          }
17727          node = node.parentNode;
17728        }
17729        return scrollContainer;
17730      };
17731      var scrollIntoView = function (elm, alignToTop) {
17732        return scrollElementIntoView(editor, elm, alignToTop);
17733      };
17734      var placeCaretAt = function (clientX, clientY) {
17735        return setRng(fromPoint$1(clientX, clientY, editor.getDoc()));
17736      };
17737      var getBoundingClientRect = function () {
17738        var rng = getRng$1();
17739        return rng.collapsed ? CaretPosition$1.fromRangeStart(rng).getClientRects()[0] : rng.getBoundingClientRect();
17740      };
17741      var destroy = function () {
17742        win = selectedRange = explicitRange = null;
17743        controlSelection.destroy();
17744      };
17745      var exports = {
17746        bookmarkManager: null,
17747        controlSelection: null,
17748        dom: dom,
17749        win: win,
17750        serializer: serializer,
17751        editor: editor,
17752        collapse: collapse,
17753        setCursorLocation: setCursorLocation,
17754        getContent: getContent,
17755        setContent: setContent,
17756        getBookmark: getBookmark,
17757        moveToBookmark: moveToBookmark,
17758        select: select,
17759        isCollapsed: isCollapsed,
17760        isForward: isForward,
17761        setNode: setNode,
17762        getNode: getNode,
17763        getSel: getSel,
17764        setRng: setRng,
17765        getRng: getRng$1,
17766        getStart: getStart,
17767        getEnd: getEnd$1,
17768        getSelectedBlocks: getSelectedBlocks$1,
17769        normalize: normalize$1,
17770        selectorChanged: selectorChanged,
17771        selectorChangedWithUnbind: selectorChangedWithUnbind,
17772        getScrollContainer: getScrollContainer,
17773        scrollIntoView: scrollIntoView,
17774        placeCaretAt: placeCaretAt,
17775        getBoundingClientRect: getBoundingClientRect,
17776        destroy: destroy
17777      };
17778      var bookmarkManager = BookmarkManager$1(exports);
17779      var controlSelection = ControlSelection(exports, editor);
17780      exports.bookmarkManager = bookmarkManager;
17781      exports.controlSelection = controlSelection;
17782      return exports;
17783    };
17784
17785    var removeAttrs = function (node, names) {
17786      each(names, function (name) {
17787        node.attr(name, null);
17788      });
17789    };
17790    var addFontToSpansFilter = function (domParser, styles, fontSizes) {
17791      domParser.addNodeFilter('font', function (nodes) {
17792        each(nodes, function (node) {
17793          var props = styles.parse(node.attr('style'));
17794          var color = node.attr('color');
17795          var face = node.attr('face');
17796          var size = node.attr('size');
17797          if (color) {
17798            props.color = color;
17799          }
17800          if (face) {
17801            props['font-family'] = face;
17802          }
17803          if (size) {
17804            props['font-size'] = fontSizes[parseInt(node.attr('size'), 10) - 1];
17805          }
17806          node.name = 'span';
17807          node.attr('style', styles.serialize(props));
17808          removeAttrs(node, [
17809            'color',
17810            'face',
17811            'size'
17812          ]);
17813        });
17814      });
17815    };
17816    var addStrikeToSpanFilter = function (domParser, styles) {
17817      domParser.addNodeFilter('strike', function (nodes) {
17818        each(nodes, function (node) {
17819          var props = styles.parse(node.attr('style'));
17820          props['text-decoration'] = 'line-through';
17821          node.name = 'span';
17822          node.attr('style', styles.serialize(props));
17823        });
17824      });
17825    };
17826    var addFilters = function (domParser, settings) {
17827      var styles = Styles();
17828      if (settings.convert_fonts_to_spans) {
17829        addFontToSpansFilter(domParser, styles, Tools.explode(settings.font_size_legacy_values));
17830      }
17831      addStrikeToSpanFilter(domParser, styles);
17832    };
17833    var register$1 = function (domParser, settings) {
17834      if (settings.inline_styles) {
17835        addFilters(domParser, settings);
17836      }
17837    };
17838
17839    var blobUriToBlob = function (url) {
17840      return new promiseObj(function (resolve, reject) {
17841        var rejectWithError = function () {
17842          reject('Cannot convert ' + url + ' to Blob. Resource might not exist or is inaccessible.');
17843        };
17844        try {
17845          var xhr = new XMLHttpRequest();
17846          xhr.open('GET', url, true);
17847          xhr.responseType = 'blob';
17848          xhr.onload = function () {
17849            if (this.status === 200) {
17850              resolve(this.response);
17851            } else {
17852              rejectWithError();
17853            }
17854          };
17855          xhr.onerror = rejectWithError;
17856          xhr.send();
17857        } catch (ex) {
17858          rejectWithError();
17859        }
17860      });
17861    };
17862    var parseDataUri$1 = function (uri) {
17863      var type;
17864      var uriParts = decodeURIComponent(uri).split(',');
17865      var matches = /data:([^;]+)/.exec(uriParts[0]);
17866      if (matches) {
17867        type = matches[1];
17868      }
17869      return {
17870        type: type,
17871        data: uriParts[1]
17872      };
17873    };
17874    var buildBlob = function (type, data) {
17875      var str;
17876      try {
17877        str = atob(data);
17878      } catch (e) {
17879        return Optional.none();
17880      }
17881      var arr = new Uint8Array(str.length);
17882      for (var i = 0; i < arr.length; i++) {
17883        arr[i] = str.charCodeAt(i);
17884      }
17885      return Optional.some(new Blob([arr], { type: type }));
17886    };
17887    var dataUriToBlob = function (uri) {
17888      return new promiseObj(function (resolve) {
17889        var _a = parseDataUri$1(uri), type = _a.type, data = _a.data;
17890        buildBlob(type, data).fold(function () {
17891          return resolve(new Blob([]));
17892        }, resolve);
17893      });
17894    };
17895    var uriToBlob = function (url) {
17896      if (url.indexOf('blob:') === 0) {
17897        return blobUriToBlob(url);
17898      }
17899      if (url.indexOf('data:') === 0) {
17900        return dataUriToBlob(url);
17901      }
17902      return null;
17903    };
17904    var blobToDataUri = function (blob) {
17905      return new promiseObj(function (resolve) {
17906        var reader = new FileReader();
17907        reader.onloadend = function () {
17908          resolve(reader.result);
17909        };
17910        reader.readAsDataURL(blob);
17911      });
17912    };
17913
17914    var count = 0;
17915    var uniqueId = function (prefix) {
17916      return (prefix || 'blobid') + count++;
17917    };
17918    var imageToBlobInfo = function (blobCache, img, resolve, reject) {
17919      var base64, blobInfo;
17920      if (img.src.indexOf('blob:') === 0) {
17921        blobInfo = blobCache.getByUri(img.src);
17922        if (blobInfo) {
17923          resolve({
17924            image: img,
17925            blobInfo: blobInfo
17926          });
17927        } else {
17928          uriToBlob(img.src).then(function (blob) {
17929            blobToDataUri(blob).then(function (dataUri) {
17930              base64 = parseDataUri$1(dataUri).data;
17931              blobInfo = blobCache.create(uniqueId(), blob, base64);
17932              blobCache.add(blobInfo);
17933              resolve({
17934                image: img,
17935                blobInfo: blobInfo
17936              });
17937            });
17938          }, function (err) {
17939            reject(err);
17940          });
17941        }
17942        return;
17943      }
17944      var _a = parseDataUri$1(img.src), data = _a.data, type = _a.type;
17945      base64 = data;
17946      blobInfo = blobCache.getByData(base64, type);
17947      if (blobInfo) {
17948        resolve({
17949          image: img,
17950          blobInfo: blobInfo
17951        });
17952      } else {
17953        uriToBlob(img.src).then(function (blob) {
17954          blobInfo = blobCache.create(uniqueId(), blob, base64);
17955          blobCache.add(blobInfo);
17956          resolve({
17957            image: img,
17958            blobInfo: blobInfo
17959          });
17960        }, function (err) {
17961          reject(err);
17962        });
17963      }
17964    };
17965    var getAllImages = function (elm) {
17966      return elm ? from$1(elm.getElementsByTagName('img')) : [];
17967    };
17968    function ImageScanner(uploadStatus, blobCache) {
17969      var cachedPromises = {};
17970      var findAll = function (elm, predicate) {
17971        if (!predicate) {
17972          predicate = always;
17973        }
17974        var images = filter(getAllImages(elm), function (img) {
17975          var src = img.src;
17976          if (!Env.fileApi) {
17977            return false;
17978          }
17979          if (img.hasAttribute('data-mce-bogus')) {
17980            return false;
17981          }
17982          if (img.hasAttribute('data-mce-placeholder')) {
17983            return false;
17984          }
17985          if (!src || src === Env.transparentSrc) {
17986            return false;
17987          }
17988          if (src.indexOf('blob:') === 0) {
17989            return !uploadStatus.isUploaded(src) && predicate(img);
17990          }
17991          if (src.indexOf('data:') === 0) {
17992            return predicate(img);
17993          }
17994          return false;
17995        });
17996        var promises = map(images, function (img) {
17997          if (cachedPromises[img.src] !== undefined) {
17998            return new promiseObj(function (resolve) {
17999              cachedPromises[img.src].then(function (imageInfo) {
18000                if (typeof imageInfo === 'string') {
18001                  return imageInfo;
18002                }
18003                resolve({
18004                  image: img,
18005                  blobInfo: imageInfo.blobInfo
18006                });
18007              });
18008            });
18009          }
18010          var newPromise = new promiseObj(function (resolve, reject) {
18011            imageToBlobInfo(blobCache, img, resolve, reject);
18012          }).then(function (result) {
18013            delete cachedPromises[result.image.src];
18014            return result;
18015          }).catch(function (error) {
18016            delete cachedPromises[img.src];
18017            return error;
18018          });
18019          cachedPromises[img.src] = newPromise;
18020          return newPromise;
18021        });
18022        return promiseObj.all(promises);
18023      };
18024      return { findAll: findAll };
18025    }
18026
18027    var paddEmptyNode = function (settings, args, blockElements, node) {
18028      var brPreferred = settings.padd_empty_with_br || args.insert;
18029      if (brPreferred && blockElements[node.name]) {
18030        node.empty().append(new AstNode('br', 1)).shortEnded = true;
18031      } else {
18032        node.empty().append(new AstNode('#text', 3)).value = nbsp;
18033      }
18034    };
18035    var isPaddedWithNbsp = function (node) {
18036      return hasOnlyChild(node, '#text') && node.firstChild.value === nbsp;
18037    };
18038    var hasOnlyChild = function (node, name) {
18039      return node && node.firstChild && node.firstChild === node.lastChild && node.firstChild.name === name;
18040    };
18041    var isPadded = function (schema, node) {
18042      var rule = schema.getElementRule(node.name);
18043      return rule && rule.paddEmpty;
18044    };
18045    var isEmpty$2 = function (schema, nonEmptyElements, whitespaceElements, node) {
18046      return node.isEmpty(nonEmptyElements, whitespaceElements, function (node) {
18047        return isPadded(schema, node);
18048      });
18049    };
18050    var isLineBreakNode = function (node, blockElements) {
18051      return node && (blockElements[node.name] || node.name === 'br');
18052    };
18053
18054    var isBogusImage = function (img) {
18055      return img.attr('data-mce-bogus');
18056    };
18057    var isInternalImageSource = function (img) {
18058      return img.attr('src') === Env.transparentSrc || img.attr('data-mce-placeholder');
18059    };
18060    var isValidDataImg = function (img, settings) {
18061      if (settings.images_dataimg_filter) {
18062        var imgElem_1 = new Image();
18063        imgElem_1.src = img.attr('src');
18064        each$1(img.attributes.map, function (value, key) {
18065          imgElem_1.setAttribute(key, value);
18066        });
18067        return settings.images_dataimg_filter(imgElem_1);
18068      } else {
18069        return true;
18070      }
18071    };
18072    var registerBase64ImageFilter = function (parser, settings) {
18073      var blobCache = settings.blob_cache;
18074      var processImage = function (img) {
18075        var inputSrc = img.attr('src');
18076        if (isInternalImageSource(img) || isBogusImage(img)) {
18077          return;
18078        }
18079        parseDataUri(inputSrc).filter(function () {
18080          return isValidDataImg(img, settings);
18081        }).bind(function (_a) {
18082          var type = _a.type, data = _a.data;
18083          return Optional.from(blobCache.getByData(data, type)).orThunk(function () {
18084            return buildBlob(type, data).map(function (blob) {
18085              var blobInfo = blobCache.create(uniqueId(), blob, data);
18086              blobCache.add(blobInfo);
18087              return blobInfo;
18088            });
18089          });
18090        }).each(function (blobInfo) {
18091          img.attr('src', blobInfo.blobUri());
18092        });
18093      };
18094      if (blobCache) {
18095        parser.addAttributeFilter('src', function (nodes) {
18096          return each(nodes, processImage);
18097        });
18098      }
18099    };
18100    var register$2 = function (parser, settings) {
18101      var schema = parser.schema;
18102      if (settings.remove_trailing_brs) {
18103        parser.addNodeFilter('br', function (nodes, _, args) {
18104          var i;
18105          var l = nodes.length;
18106          var node;
18107          var blockElements = Tools.extend({}, schema.getBlockElements());
18108          var nonEmptyElements = schema.getNonEmptyElements();
18109          var parent, lastParent, prev, prevName;
18110          var whiteSpaceElements = schema.getWhiteSpaceElements();
18111          var elementRule, textNode;
18112          blockElements.body = 1;
18113          for (i = 0; i < l; i++) {
18114            node = nodes[i];
18115            parent = node.parent;
18116            if (blockElements[node.parent.name] && node === parent.lastChild) {
18117              prev = node.prev;
18118              while (prev) {
18119                prevName = prev.name;
18120                if (prevName !== 'span' || prev.attr('data-mce-type') !== 'bookmark') {
18121                  if (prevName === 'br') {
18122                    node = null;
18123                  }
18124                  break;
18125                }
18126                prev = prev.prev;
18127              }
18128              if (node) {
18129                node.remove();
18130                if (isEmpty$2(schema, nonEmptyElements, whiteSpaceElements, parent)) {
18131                  elementRule = schema.getElementRule(parent.name);
18132                  if (elementRule) {
18133                    if (elementRule.removeEmpty) {
18134                      parent.remove();
18135                    } else if (elementRule.paddEmpty) {
18136                      paddEmptyNode(settings, args, blockElements, parent);
18137                    }
18138                  }
18139                }
18140              }
18141            } else {
18142              lastParent = node;
18143              while (parent && parent.firstChild === lastParent && parent.lastChild === lastParent) {
18144                lastParent = parent;
18145                if (blockElements[parent.name]) {
18146                  break;
18147                }
18148                parent = parent.parent;
18149              }
18150              if (lastParent === parent && settings.padd_empty_with_br !== true) {
18151                textNode = new AstNode('#text', 3);
18152                textNode.value = nbsp;
18153                node.replace(textNode);
18154              }
18155            }
18156          }
18157        });
18158      }
18159      parser.addAttributeFilter('href', function (nodes) {
18160        var i = nodes.length;
18161        var appendRel = function (rel) {
18162          var parts = rel.split(' ').filter(function (p) {
18163            return p.length > 0;
18164          });
18165          return parts.concat(['noopener']).sort().join(' ');
18166        };
18167        var addNoOpener = function (rel) {
18168          var newRel = rel ? Tools.trim(rel) : '';
18169          if (!/\b(noopener)\b/g.test(newRel)) {
18170            return appendRel(newRel);
18171          } else {
18172            return newRel;
18173          }
18174        };
18175        if (!settings.allow_unsafe_link_target) {
18176          while (i--) {
18177            var node = nodes[i];
18178            if (node.name === 'a' && node.attr('target') === '_blank') {
18179              node.attr('rel', addNoOpener(node.attr('rel')));
18180            }
18181          }
18182        }
18183      });
18184      if (!settings.allow_html_in_named_anchor) {
18185        parser.addAttributeFilter('id,name', function (nodes) {
18186          var i = nodes.length, sibling, prevSibling, parent, node;
18187          while (i--) {
18188            node = nodes[i];
18189            if (node.name === 'a' && node.firstChild && !node.attr('href')) {
18190              parent = node.parent;
18191              sibling = node.lastChild;
18192              do {
18193                prevSibling = sibling.prev;
18194                parent.insert(sibling, node);
18195                sibling = prevSibling;
18196              } while (sibling);
18197            }
18198          }
18199        });
18200      }
18201      if (settings.fix_list_elements) {
18202        parser.addNodeFilter('ul,ol', function (nodes) {
18203          var i = nodes.length, node, parentNode;
18204          while (i--) {
18205            node = nodes[i];
18206            parentNode = node.parent;
18207            if (parentNode.name === 'ul' || parentNode.name === 'ol') {
18208              if (node.prev && node.prev.name === 'li') {
18209                node.prev.append(node);
18210              } else {
18211                var li = new AstNode('li', 1);
18212                li.attr('style', 'list-style-type: none');
18213                node.wrap(li);
18214              }
18215            }
18216          }
18217        });
18218      }
18219      if (settings.validate && schema.getValidClasses()) {
18220        parser.addAttributeFilter('class', function (nodes) {
18221          var i = nodes.length, node, classList, ci, className, classValue;
18222          var validClasses = schema.getValidClasses();
18223          var validClassesMap, valid;
18224          while (i--) {
18225            node = nodes[i];
18226            classList = node.attr('class').split(' ');
18227            classValue = '';
18228            for (ci = 0; ci < classList.length; ci++) {
18229              className = classList[ci];
18230              valid = false;
18231              validClassesMap = validClasses['*'];
18232              if (validClassesMap && validClassesMap[className]) {
18233                valid = true;
18234              }
18235              validClassesMap = validClasses[node.name];
18236              if (!valid && validClassesMap && validClassesMap[className]) {
18237                valid = true;
18238              }
18239              if (valid) {
18240                if (classValue) {
18241                  classValue += ' ';
18242                }
18243                classValue += className;
18244              }
18245            }
18246            if (!classValue.length) {
18247              classValue = null;
18248            }
18249            node.attr('class', classValue);
18250          }
18251        });
18252      }
18253      registerBase64ImageFilter(parser, settings);
18254    };
18255
18256    var makeMap$4 = Tools.makeMap, each$d = Tools.each, explode$2 = Tools.explode, extend$2 = Tools.extend;
18257    var DomParser = function (settings, schema) {
18258      if (schema === void 0) {
18259        schema = Schema();
18260      }
18261      var nodeFilters = {};
18262      var attributeFilters = [];
18263      var matchedNodes = {};
18264      var matchedAttributes = {};
18265      settings = settings || {};
18266      settings.validate = 'validate' in settings ? settings.validate : true;
18267      settings.root_name = settings.root_name || 'body';
18268      var fixInvalidChildren = function (nodes) {
18269        var ni, node, parent, parents, newParent, currentNode, tempNode, childNode, i;
18270        var sibling, nextNode;
18271        var nonSplitableElements = makeMap$4('tr,td,th,tbody,thead,tfoot,table');
18272        var nonEmptyElements = schema.getNonEmptyElements();
18273        var whitespaceElements = schema.getWhiteSpaceElements();
18274        var textBlockElements = schema.getTextBlockElements();
18275        var specialElements = schema.getSpecialElements();
18276        for (ni = 0; ni < nodes.length; ni++) {
18277          node = nodes[ni];
18278          if (!node.parent || node.fixed) {
18279            continue;
18280          }
18281          if (textBlockElements[node.name] && node.parent.name === 'li') {
18282            sibling = node.next;
18283            while (sibling) {
18284              if (textBlockElements[sibling.name]) {
18285                sibling.name = 'li';
18286                sibling.fixed = true;
18287                node.parent.insert(sibling, node.parent);
18288              } else {
18289                break;
18290              }
18291              sibling = sibling.next;
18292            }
18293            node.unwrap(node);
18294            continue;
18295          }
18296          parents = [node];
18297          for (parent = node.parent; parent && !schema.isValidChild(parent.name, node.name) && !nonSplitableElements[parent.name]; parent = parent.parent) {
18298            parents.push(parent);
18299          }
18300          if (parent && parents.length > 1) {
18301            parents.reverse();
18302            newParent = currentNode = filterNode(parents[0].clone());
18303            for (i = 0; i < parents.length - 1; i++) {
18304              if (schema.isValidChild(currentNode.name, parents[i].name)) {
18305                tempNode = filterNode(parents[i].clone());
18306                currentNode.append(tempNode);
18307              } else {
18308                tempNode = currentNode;
18309              }
18310              for (childNode = parents[i].firstChild; childNode && childNode !== parents[i + 1];) {
18311                nextNode = childNode.next;
18312                tempNode.append(childNode);
18313                childNode = nextNode;
18314              }
18315              currentNode = tempNode;
18316            }
18317            if (!isEmpty$2(schema, nonEmptyElements, whitespaceElements, newParent)) {
18318              parent.insert(newParent, parents[0], true);
18319              parent.insert(node, newParent);
18320            } else {
18321              parent.insert(node, parents[0], true);
18322            }
18323            parent = parents[0];
18324            if (isEmpty$2(schema, nonEmptyElements, whitespaceElements, parent) || hasOnlyChild(parent, 'br')) {
18325              parent.empty().remove();
18326            }
18327          } else if (node.parent) {
18328            if (node.name === 'li') {
18329              sibling = node.prev;
18330              if (sibling && (sibling.name === 'ul' || sibling.name === 'ol')) {
18331                sibling.append(node);
18332                continue;
18333              }
18334              sibling = node.next;
18335              if (sibling && (sibling.name === 'ul' || sibling.name === 'ol')) {
18336                sibling.insert(node, sibling.firstChild, true);
18337                continue;
18338              }
18339              node.wrap(filterNode(new AstNode('ul', 1)));
18340              continue;
18341            }
18342            if (schema.isValidChild(node.parent.name, 'div') && schema.isValidChild('div', node.name)) {
18343              node.wrap(filterNode(new AstNode('div', 1)));
18344            } else {
18345              if (specialElements[node.name]) {
18346                node.empty().remove();
18347              } else {
18348                node.unwrap();
18349              }
18350            }
18351          }
18352        }
18353      };
18354      var filterNode = function (node) {
18355        var i, name, list;
18356        name = node.name;
18357        if (name in nodeFilters) {
18358          list = matchedNodes[name];
18359          if (list) {
18360            list.push(node);
18361          } else {
18362            matchedNodes[name] = [node];
18363          }
18364        }
18365        i = attributeFilters.length;
18366        while (i--) {
18367          name = attributeFilters[i].name;
18368          if (name in node.attributes.map) {
18369            list = matchedAttributes[name];
18370            if (list) {
18371              list.push(node);
18372            } else {
18373              matchedAttributes[name] = [node];
18374            }
18375          }
18376        }
18377        return node;
18378      };
18379      var addNodeFilter = function (name, callback) {
18380        each$d(explode$2(name), function (name) {
18381          var list = nodeFilters[name];
18382          if (!list) {
18383            nodeFilters[name] = list = [];
18384          }
18385          list.push(callback);
18386        });
18387      };
18388      var getNodeFilters = function () {
18389        var out = [];
18390        for (var name_1 in nodeFilters) {
18391          if (nodeFilters.hasOwnProperty(name_1)) {
18392            out.push({
18393              name: name_1,
18394              callbacks: nodeFilters[name_1]
18395            });
18396          }
18397        }
18398        return out;
18399      };
18400      var addAttributeFilter = function (name, callback) {
18401        each$d(explode$2(name), function (name) {
18402          var i;
18403          for (i = 0; i < attributeFilters.length; i++) {
18404            if (attributeFilters[i].name === name) {
18405              attributeFilters[i].callbacks.push(callback);
18406              return;
18407            }
18408          }
18409          attributeFilters.push({
18410            name: name,
18411            callbacks: [callback]
18412          });
18413        });
18414      };
18415      var getAttributeFilters = function () {
18416        return [].concat(attributeFilters);
18417      };
18418      var parse = function (html, args) {
18419        var nodes, i, l, fi, fl, list, name;
18420        var invalidChildren = [];
18421        var isInWhiteSpacePreservedElement;
18422        var node;
18423        var getRootBlockName = function (name) {
18424          if (name === false) {
18425            return '';
18426          } else if (name === true) {
18427            return 'p';
18428          } else {
18429            return name;
18430          }
18431        };
18432        args = args || {};
18433        matchedNodes = {};
18434        matchedAttributes = {};
18435        var blockElements = extend$2(makeMap$4('script,style,head,html,body,title,meta,param'), schema.getBlockElements());
18436        var nonEmptyElements = schema.getNonEmptyElements();
18437        var children = schema.children;
18438        var validate = settings.validate;
18439        var forcedRootBlockName = 'forced_root_block' in args ? args.forced_root_block : settings.forced_root_block;
18440        var rootBlockName = getRootBlockName(forcedRootBlockName);
18441        var whiteSpaceElements = schema.getWhiteSpaceElements();
18442        var startWhiteSpaceRegExp = /^[ \t\r\n]+/;
18443        var endWhiteSpaceRegExp = /[ \t\r\n]+$/;
18444        var allWhiteSpaceRegExp = /[ \t\r\n]+/g;
18445        var isAllWhiteSpaceRegExp = /^[ \t\r\n]+$/;
18446        isInWhiteSpacePreservedElement = whiteSpaceElements.hasOwnProperty(args.context) || whiteSpaceElements.hasOwnProperty(settings.root_name);
18447        var addRootBlocks = function () {
18448          var node = rootNode.firstChild, next, rootBlockNode;
18449          var trim = function (rootBlockNode) {
18450            if (rootBlockNode) {
18451              node = rootBlockNode.firstChild;
18452              if (node && node.type === 3) {
18453                node.value = node.value.replace(startWhiteSpaceRegExp, '');
18454              }
18455              node = rootBlockNode.lastChild;
18456              if (node && node.type === 3) {
18457                node.value = node.value.replace(endWhiteSpaceRegExp, '');
18458              }
18459            }
18460          };
18461          if (!schema.isValidChild(rootNode.name, rootBlockName.toLowerCase())) {
18462            return;
18463          }
18464          while (node) {
18465            next = node.next;
18466            if (node.type === 3 || node.type === 1 && node.name !== 'p' && !blockElements[node.name] && !node.attr('data-mce-type')) {
18467              if (!rootBlockNode) {
18468                rootBlockNode = createNode(rootBlockName, 1);
18469                rootBlockNode.attr(settings.forced_root_block_attrs);
18470                rootNode.insert(rootBlockNode, node);
18471                rootBlockNode.append(node);
18472              } else {
18473                rootBlockNode.append(node);
18474              }
18475            } else {
18476              trim(rootBlockNode);
18477              rootBlockNode = null;
18478            }
18479            node = next;
18480          }
18481          trim(rootBlockNode);
18482        };
18483        var createNode = function (name, type) {
18484          var node = new AstNode(name, type);
18485          var list;
18486          if (name in nodeFilters) {
18487            list = matchedNodes[name];
18488            if (list) {
18489              list.push(node);
18490            } else {
18491              matchedNodes[name] = [node];
18492            }
18493          }
18494          return node;
18495        };
18496        var removeWhitespaceBefore = function (node) {
18497          var textNode, textNodeNext, textVal, sibling;
18498          var blockElements = schema.getBlockElements();
18499          for (textNode = node.prev; textNode && textNode.type === 3;) {
18500            textVal = textNode.value.replace(endWhiteSpaceRegExp, '');
18501            if (textVal.length > 0) {
18502              textNode.value = textVal;
18503              return;
18504            }
18505            textNodeNext = textNode.next;
18506            if (textNodeNext) {
18507              if (textNodeNext.type === 3 && textNodeNext.value.length) {
18508                textNode = textNode.prev;
18509                continue;
18510              }
18511              if (!blockElements[textNodeNext.name] && textNodeNext.name !== 'script' && textNodeNext.name !== 'style') {
18512                textNode = textNode.prev;
18513                continue;
18514              }
18515            }
18516            sibling = textNode.prev;
18517            textNode.remove();
18518            textNode = sibling;
18519          }
18520        };
18521        var cloneAndExcludeBlocks = function (input) {
18522          var name;
18523          var output = {};
18524          for (name in input) {
18525            if (name !== 'li' && name !== 'p') {
18526              output[name] = input[name];
18527            }
18528          }
18529          return output;
18530        };
18531        var parser = SaxParser$1({
18532          validate: validate,
18533          allow_html_data_urls: settings.allow_html_data_urls,
18534          allow_script_urls: settings.allow_script_urls,
18535          allow_conditional_comments: settings.allow_conditional_comments,
18536          preserve_cdata: settings.preserve_cdata,
18537          self_closing_elements: cloneAndExcludeBlocks(schema.getSelfClosingElements()),
18538          cdata: function (text) {
18539            node.append(createNode('#cdata', 4)).value = text;
18540          },
18541          text: function (text, raw) {
18542            var textNode;
18543            if (!isInWhiteSpacePreservedElement) {
18544              text = text.replace(allWhiteSpaceRegExp, ' ');
18545              if (isLineBreakNode(node.lastChild, blockElements)) {
18546                text = text.replace(startWhiteSpaceRegExp, '');
18547              }
18548            }
18549            if (text.length !== 0) {
18550              textNode = createNode('#text', 3);
18551              textNode.raw = !!raw;
18552              node.append(textNode).value = text;
18553            }
18554          },
18555          comment: function (text) {
18556            node.append(createNode('#comment', 8)).value = text;
18557          },
18558          pi: function (name, text) {
18559            node.append(createNode(name, 7)).value = text;
18560            removeWhitespaceBefore(node);
18561          },
18562          doctype: function (text) {
18563            var newNode = node.append(createNode('#doctype', 10));
18564            newNode.value = text;
18565            removeWhitespaceBefore(node);
18566          },
18567          start: function (name, attrs, empty) {
18568            var newNode, attrFiltersLen, attrName, parent;
18569            var elementRule = validate ? schema.getElementRule(name) : {};
18570            if (elementRule) {
18571              newNode = createNode(elementRule.outputName || name, 1);
18572              newNode.attributes = attrs;
18573              newNode.shortEnded = empty;
18574              node.append(newNode);
18575              parent = children[node.name];
18576              if (parent && children[newNode.name] && !parent[newNode.name]) {
18577                invalidChildren.push(newNode);
18578              }
18579              attrFiltersLen = attributeFilters.length;
18580              while (attrFiltersLen--) {
18581                attrName = attributeFilters[attrFiltersLen].name;
18582                if (attrName in attrs.map) {
18583                  list = matchedAttributes[attrName];
18584                  if (list) {
18585                    list.push(newNode);
18586                  } else {
18587                    matchedAttributes[attrName] = [newNode];
18588                  }
18589                }
18590              }
18591              if (blockElements[name]) {
18592                removeWhitespaceBefore(newNode);
18593              }
18594              if (!empty) {
18595                node = newNode;
18596              }
18597              if (!isInWhiteSpacePreservedElement && whiteSpaceElements[name]) {
18598                isInWhiteSpacePreservedElement = true;
18599              }
18600            }
18601          },
18602          end: function (name) {
18603            var textNode, text, sibling, tempNode;
18604            var elementRule = validate ? schema.getElementRule(name) : {};
18605            if (elementRule) {
18606              if (blockElements[name]) {
18607                if (!isInWhiteSpacePreservedElement) {
18608                  textNode = node.firstChild;
18609                  if (textNode && textNode.type === 3) {
18610                    text = textNode.value.replace(startWhiteSpaceRegExp, '');
18611                    if (text.length > 0) {
18612                      textNode.value = text;
18613                      textNode = textNode.next;
18614                    } else {
18615                      sibling = textNode.next;
18616                      textNode.remove();
18617                      textNode = sibling;
18618                      while (textNode && textNode.type === 3) {
18619                        text = textNode.value;
18620                        sibling = textNode.next;
18621                        if (text.length === 0 || isAllWhiteSpaceRegExp.test(text)) {
18622                          textNode.remove();
18623                          textNode = sibling;
18624                        }
18625                        textNode = sibling;
18626                      }
18627                    }
18628                  }
18629                  textNode = node.lastChild;
18630                  if (textNode && textNode.type === 3) {
18631                    text = textNode.value.replace(endWhiteSpaceRegExp, '');
18632                    if (text.length > 0) {
18633                      textNode.value = text;
18634                      textNode = textNode.prev;
18635                    } else {
18636                      sibling = textNode.prev;
18637                      textNode.remove();
18638                      textNode = sibling;
18639                      while (textNode && textNode.type === 3) {
18640                        text = textNode.value;
18641                        sibling = textNode.prev;
18642                        if (text.length === 0 || isAllWhiteSpaceRegExp.test(text)) {
18643                          textNode.remove();
18644                          textNode = sibling;
18645                        }
18646                        textNode = sibling;
18647                      }
18648                    }
18649                  }
18650                }
18651              }
18652              if (isInWhiteSpacePreservedElement && whiteSpaceElements[name]) {
18653                isInWhiteSpacePreservedElement = false;
18654              }
18655              if (elementRule.removeEmpty && isEmpty$2(schema, nonEmptyElements, whiteSpaceElements, node)) {
18656                tempNode = node.parent;
18657                if (blockElements[node.name]) {
18658                  node.empty().remove();
18659                } else {
18660                  node.unwrap();
18661                }
18662                node = tempNode;
18663                return;
18664              }
18665              if (elementRule.paddEmpty && (isPaddedWithNbsp(node) || isEmpty$2(schema, nonEmptyElements, whiteSpaceElements, node))) {
18666                paddEmptyNode(settings, args, blockElements, node);
18667              }
18668              node = node.parent;
18669            }
18670          }
18671        }, schema);
18672        var rootNode = node = new AstNode(args.context || settings.root_name, 11);
18673        parser.parse(html, args.format);
18674        if (validate && invalidChildren.length) {
18675          if (!args.context) {
18676            fixInvalidChildren(invalidChildren);
18677          } else {
18678            args.invalid = true;
18679          }
18680        }
18681        if (rootBlockName && (rootNode.name === 'body' || args.isRootContent)) {
18682          addRootBlocks();
18683        }
18684        if (!args.invalid) {
18685          for (name in matchedNodes) {
18686            if (!matchedNodes.hasOwnProperty(name)) {
18687              continue;
18688            }
18689            list = nodeFilters[name];
18690            nodes = matchedNodes[name];
18691            fi = nodes.length;
18692            while (fi--) {
18693              if (!nodes[fi].parent) {
18694                nodes.splice(fi, 1);
18695              }
18696            }
18697            for (i = 0, l = list.length; i < l; i++) {
18698              list[i](nodes, name, args);
18699            }
18700          }
18701          for (i = 0, l = attributeFilters.length; i < l; i++) {
18702            list = attributeFilters[i];
18703            if (list.name in matchedAttributes) {
18704              nodes = matchedAttributes[list.name];
18705              fi = nodes.length;
18706              while (fi--) {
18707                if (!nodes[fi].parent) {
18708                  nodes.splice(fi, 1);
18709                }
18710              }
18711              for (fi = 0, fl = list.callbacks.length; fi < fl; fi++) {
18712                list.callbacks[fi](nodes, list.name, args);
18713              }
18714            }
18715          }
18716        }
18717        return rootNode;
18718      };
18719      var exports = {
18720        schema: schema,
18721        addAttributeFilter: addAttributeFilter,
18722        getAttributeFilters: getAttributeFilters,
18723        addNodeFilter: addNodeFilter,
18724        getNodeFilters: getNodeFilters,
18725        filterNode: filterNode,
18726        parse: parse
18727      };
18728      register$2(exports, settings);
18729      register$1(exports, settings);
18730      return exports;
18731    };
18732
18733    var register$3 = function (htmlParser, settings, dom) {
18734      htmlParser.addAttributeFilter('data-mce-tabindex', function (nodes, name) {
18735        var i = nodes.length, node;
18736        while (i--) {
18737          node = nodes[i];
18738          node.attr('tabindex', node.attr('data-mce-tabindex'));
18739          node.attr(name, null);
18740        }
18741      });
18742      htmlParser.addAttributeFilter('src,href,style', function (nodes, name) {
18743        var i = nodes.length, node, value;
18744        var internalName = 'data-mce-' + name;
18745        var urlConverter = settings.url_converter;
18746        var urlConverterScope = settings.url_converter_scope;
18747        while (i--) {
18748          node = nodes[i];
18749          value = node.attr(internalName);
18750          if (value !== undefined) {
18751            node.attr(name, value.length > 0 ? value : null);
18752            node.attr(internalName, null);
18753          } else {
18754            value = node.attr(name);
18755            if (name === 'style') {
18756              value = dom.serializeStyle(dom.parseStyle(value), node.name);
18757            } else if (urlConverter) {
18758              value = urlConverter.call(urlConverterScope, value, name, node.name);
18759            }
18760            node.attr(name, value.length > 0 ? value : null);
18761          }
18762        }
18763      });
18764      htmlParser.addAttributeFilter('class', function (nodes) {
18765        var i = nodes.length, node, value;
18766        while (i--) {
18767          node = nodes[i];
18768          value = node.attr('class');
18769          if (value) {
18770            value = node.attr('class').replace(/(?:^|\s)mce-item-\w+(?!\S)/g, '');
18771            node.attr('class', value.length > 0 ? value : null);
18772          }
18773        }
18774      });
18775      htmlParser.addAttributeFilter('data-mce-type', function (nodes, name, args) {
18776        var i = nodes.length, node;
18777        while (i--) {
18778          node = nodes[i];
18779          if (node.attr('data-mce-type') === 'bookmark' && !args.cleanup) {
18780            var hasChildren = Optional.from(node.firstChild).exists(function (firstChild) {
18781              return !isZwsp$1(firstChild.value);
18782            });
18783            if (hasChildren) {
18784              node.unwrap();
18785            } else {
18786              node.remove();
18787            }
18788          }
18789        }
18790      });
18791      htmlParser.addNodeFilter('noscript', function (nodes) {
18792        var i = nodes.length, node;
18793        while (i--) {
18794          node = nodes[i].firstChild;
18795          if (node) {
18796            node.value = Entities.decode(node.value);
18797          }
18798        }
18799      });
18800      htmlParser.addNodeFilter('script,style', function (nodes, name) {
18801        var i = nodes.length, node, value, type;
18802        var trim = function (value) {
18803          return value.replace(/(<!--\[CDATA\[|\]\]-->)/g, '\n').replace(/^[\r\n]*|[\r\n]*$/g, '').replace(/^\s*((<!--)?(\s*\/\/)?\s*<!\[CDATA\[|(<!--\s*)?\/\*\s*<!\[CDATA\[\s*\*\/|(\/\/)?\s*<!--|\/\*\s*<!--\s*\*\/)\s*[\r\n]*/gi, '').replace(/\s*(\/\*\s*\]\]>\s*\*\/(-->)?|\s*\/\/\s*\]\]>(-->)?|\/\/\s*(-->)?|\]\]>|\/\*\s*-->\s*\*\/|\s*-->\s*)\s*$/g, '');
18804        };
18805        while (i--) {
18806          node = nodes[i];
18807          value = node.firstChild ? node.firstChild.value : '';
18808          if (name === 'script') {
18809            type = node.attr('type');
18810            if (type) {
18811              node.attr('type', type === 'mce-no/type' ? null : type.replace(/^mce\-/, ''));
18812            }
18813            if (settings.element_format === 'xhtml' && value.length > 0) {
18814              node.firstChild.value = '// <![CDATA[\n' + trim(value) + '\n// ]]>';
18815            }
18816          } else {
18817            if (settings.element_format === 'xhtml' && value.length > 0) {
18818              node.firstChild.value = '<!--\n' + trim(value) + '\n-->';
18819            }
18820          }
18821        }
18822      });
18823      htmlParser.addNodeFilter('#comment', function (nodes) {
18824        var i = nodes.length, node;
18825        while (i--) {
18826          node = nodes[i];
18827          if (settings.preserve_cdata && node.value.indexOf('[CDATA[') 
18827=== 0) {
18828            node.name = '#cdata';
18829            node.type = 4;
18830            node.value = dom.decode(node.value.replace(/^\[CDATA\[|\]\]$/g, ''));
18831          } else if (node.value.indexOf('mce:protected ') === 0) {
18832            node.name = '#text';
18833            node.type = 3;
18834            node.raw = true;
18835            node.value = unescape(node.value).substr(14);
18836          }
18837        }
18838      });
18839      htmlParser.addNodeFilter('xml:namespace,input', function (nodes, name) {
18840        var i = nodes.length, node;
18841        while (i--) {
18842          node = nodes[i];
18843          if (node.type === 7) {
18844            node.remove();
18845          } else if (node.type === 1) {
18846            if (name === 'input' && !node.attr('type')) {
18847              node.attr('type', 'text');
18848            }
18849          }
18850        }
18851      });
18852      htmlParser.addAttributeFilter('data-mce-type', function (nodes) {
18853        each(nodes, function (node) {
18854          if (node.attr('data-mce-type') === 'format-caret') {
18855            if (node.isEmpty(htmlParser.schema.getNonEmptyElements())) {
18856              node.remove();
18857            } else {
18858              node.unwrap();
18859            }
18860          }
18861        });
18862      });
18863      htmlParser.addAttributeFilter('data-mce-src,data-mce-href,data-mce-style,' + 'data-mce-selected,data-mce-expando,' + 'data-mce-type,data-mce-resize,data-mce-placeholder', function (nodes, name) {
18864        var i = nodes.length;
18865        while (i--) {
18866          nodes[i].attr(name, null);
18867        }
18868      });
18869    };
18870    var trimTrailingBr = function (rootNode) {
18871      var isBr = function (node) {
18872        return node && node.name === 'br';
18873      };
18874      var brNode1 = rootNode.lastChild;
18875      if (isBr(brNode1)) {
18876        var brNode2 = brNode1.prev;
18877        if (isBr(brNode2)) {
18878          brNode1.remove();
18879          brNode2.remove();
18880        }
18881      }
18882    };
18883
18884    var preProcess = function (editor, node, args) {
18885      var doc, oldDoc;
18886      var dom = editor.dom;
18887      node = node.cloneNode(true);
18888      var impl = document.implementation;
18889      if (impl.createHTMLDocument) {
18890        doc = impl.createHTMLDocument('');
18891        Tools.each(node.nodeName === 'BODY' ? node.childNodes : [node], function (node) {
18892          doc.body.appendChild(doc.importNode(node, true));
18893        });
18894        if (node.nodeName !== 'BODY') {
18895          node = doc.body.firstChild;
18896        } else {
18897          node = doc.body;
18898        }
18899        oldDoc = dom.doc;
18900        dom.doc = doc;
18901      }
18902      firePreProcess(editor, __assign(__assign({}, args), { node: node }));
18903      if (oldDoc) {
18904        dom.doc = oldDoc;
18905      }
18906      return node;
18907    };
18908    var shouldFireEvent = function (editor, args) {
18909      return editor && editor.hasEventListeners('PreProcess') && !args.no_events;
18910    };
18911    var process = function (editor, node, args) {
18912      return shouldFireEvent(editor, args) ? preProcess(editor, node, args) : node;
18913    };
18914
18915    var addTempAttr = function (htmlParser, tempAttrs, name) {
18916      if (Tools.inArray(tempAttrs, name) === -1) {
18917        htmlParser.addAttributeFilter(name, function (nodes, name) {
18918          var i = nodes.length;
18919          while (i--) {
18920            nodes[i].attr(name, null);
18921          }
18922        });
18923        tempAttrs.push(name);
18924      }
18925    };
18926    var postProcess$1 = function (editor, args, content) {
18927      if (!args.no_events && editor) {
18928        var outArgs = firePostProcess(editor, __assign(__assign({}, args), { content: content }));
18929        return outArgs.content;
18930      } else {
18931        return content;
18932      }
18933    };
18934    var getHtmlFromNode = function (dom, node, args) {
18935      var html = trim$2(args.getInner ? node.innerHTML : dom.getOuterHTML(node));
18936      return args.selection || isWsPreserveElement(SugarElement.fromDom(node)) ? html : Tools.trim(html);
18937    };
18938    var parseHtml = function (htmlParser, html, args) {
18939      var parserArgs = args.selection ? __assign({ forced_root_block: false }, args) : args;
18940      var rootNode = htmlParser.parse(html, parserArgs);
18941      trimTrailingBr(rootNode);
18942      return rootNode;
18943    };
18944    var serializeNode = function (settings, schema, node) {
18945      var htmlSerializer = HtmlSerializer(settings, schema);
18946      return htmlSerializer.serialize(node);
18947    };
18948    var toHtml = function (editor, settings, schema, rootNode, args) {
18949      var content = serializeNode(settings, schema, rootNode);
18950      return postProcess$1(editor, args, content);
18951    };
18952    var DomSerializerImpl = function (settings, editor) {
18953      var tempAttrs = ['data-mce-selected'];
18954      var dom = editor && editor.dom ? editor.dom : DOMUtils$1.DOM;
18955      var schema = editor && editor.schema ? editor.schema : Schema(settings);
18956      settings.entity_encoding = settings.entity_encoding || 'named';
18957      settings.remove_trailing_brs = 'remove_trailing_brs' in settings ? settings.remove_trailing_brs : true;
18958      var htmlParser = DomParser(settings, schema);
18959      register$3(htmlParser, settings, dom);
18960      var serialize = function (node, parserArgs) {
18961        if (parserArgs === void 0) {
18962          parserArgs = {};
18963        }
18964        var args = __assign({ format: 'html' }, parserArgs);
18965        var targetNode = process(editor, node, args);
18966        var html = getHtmlFromNode(dom, targetNode, args);
18967        var rootNode = parseHtml(htmlParser, html, args);
18968        return args.format === 'tree' ? rootNode : toHtml(editor, settings, schema, rootNode, args);
18969      };
18970      return {
18971        schema: schema,
18972        addNodeFilter: htmlParser.addNodeFilter,
18973        addAttributeFilter: htmlParser.addAttributeFilter,
18974        serialize: serialize,
18975        addRules: function (rules) {
18976          schema.addValidElements(rules);
18977        },
18978        setRules: function (rules) {
18979          schema.setValidElements(rules);
18980        },
18981        addTempAttr: curry(addTempAttr, htmlParser, tempAttrs),
18982        getTempAttrs: function () {
18983          return tempAttrs;
18984        },
18985        getNodeFilters: htmlParser.getNodeFilters,
18986        getAttributeFilters: htmlParser.getAttributeFilters
18987      };
18988    };
18989
18990    var DomSerializer = function (settings, editor) {
18991      var domSerializer = DomSerializerImpl(settings, editor);
18992      return {
18993        schema: domSerializer.schema,
18994        addNodeFilter: domSerializer.addNodeFilter,
18995        addAttributeFilter: domSerializer.addAttributeFilter,
18996        serialize: domSerializer.serialize,
18997        addRules: domSerializer.addRules,
18998        setRules: domSerializer.setRules,
18999        addTempAttr: domSerializer.addTempAttr,
19000        getTempAttrs: domSerializer.getTempAttrs,
19001        getNodeFilters: domSerializer.getNodeFilters,
19002        getAttributeFilters: domSerializer.getAttributeFilters
19003      };
19004    };
19005
19006    var defaultFormat$1 = 'html';
19007    var getContent$2 = function (editor, args) {
19008      if (args === void 0) {
19009        args = {};
19010      }
19011      var format = args.format ? args.format : defaultFormat$1;
19012      return getContent(editor, args, format);
19013    };
19014
19015    var setContent$2 = function (editor, content, args) {
19016      if (args === void 0) {
19017        args = {};
19018      }
19019      return setContent(editor, content, args);
19020    };
19021
19022    var DOM$3 = DOMUtils$1.DOM;
19023    var restoreOriginalStyles = function (editor) {
19024      DOM$3.setStyle(editor.id, 'display', editor.orgDisplay);
19025    };
19026    var safeDestroy = function (x) {
19027      return Optional.from(x).each(function (x) {
19028        return x.destroy();
19029      });
19030    };
19031    var clearDomReferences = function (editor) {
19032      editor.contentAreaContainer = editor.formElement = editor.container = editor.editorContainer = null;
19033      editor.bodyElement = editor.contentDocument = editor.contentWindow = null;
19034      editor.iframeElement = editor.targetElm = null;
19035      if (editor.selection) {
19036        editor.selection = editor.selection.win = editor.selection.dom = editor.selection.dom.doc = null;
19037      }
19038    };
19039    var restoreForm = function (editor) {
19040      var form = editor.formElement;
19041      if (form) {
19042        if (form._mceOldSubmit) {
19043          form.submit = form._mceOldSubmit;
19044          form._mceOldSubmit = null;
19045        }
19046        DOM$3.unbind(form, 'submit reset', editor.formEventDelegate);
19047      }
19048    };
19049    var remove$7 = function (editor) {
19050      if (!editor.removed) {
19051        var _selectionOverrides = editor._selectionOverrides, editorUpload = editor.editorUpload;
19052        var body = editor.getBody();
19053        var element = editor.getElement();
19054        if (body) {
19055          editor.save({ is_removing: true });
19056        }
19057        editor.removed = true;
19058        editor.unbindAllNativeEvents();
19059        if (editor.hasHiddenInput && element) {
19060          DOM$3.remove(element.nextSibling);
19061        }
19062        fireRemove(editor);
19063        editor.editorManager.remove(editor);
19064        if (!editor.inline && body) {
19065          restoreOriginalStyles(editor);
19066        }
19067        fireDetach(editor);
19068        DOM$3.remove(editor.getContainer());
19069        safeDestroy(_selectionOverrides);
19070        safeDestroy(editorUpload);
19071        editor.destroy();
19072      }
19073    };
19074    var destroy = function (editor, automatic) {
19075      var selection = editor.selection, dom = editor.dom;
19076      if (editor.destroyed) {
19077        return;
19078      }
19079      if (!automatic && !editor.removed) {
19080        editor.remove();
19081        return;
19082      }
19083      if (!automatic) {
19084        editor.editorManager.off('beforeunload', editor._beforeUnload);
19085        if (editor.theme && editor.theme.destroy) {
19086          editor.theme.destroy();
19087        }
19088        safeDestroy(selection);
19089        safeDestroy(dom);
19090      }
19091      restoreForm(editor);
19092      clearDomReferences(editor);
19093      editor.destroyed = true;
19094    };
19095
19096    var hasOwnProperty$2 = Object.prototype.hasOwnProperty;
19097    var deep$1 = function (old, nu) {
19098      var bothObjects = isObject(old) && isObject(nu);
19099      return bothObjects ? deepMerge(old, nu) : nu;
19100    };
19101    var baseMerge = function (merger) {
19102      return function () {
19103        var objects = new Array(arguments.length);
19104        for (var i = 0; i < objects.length; i++) {
19105          objects[i] = arguments[i];
19106        }
19107        if (objects.length === 0) {
19108          throw new Error('Can\'t merge zero objects');
19109        }
19110        var ret = {};
19111        for (var j = 0; j < objects.length; j++) {
19112          var curObject = objects[j];
19113          for (var key in curObject) {
19114            if (hasOwnProperty$2.call(curObject, key)) {
19115              ret[key] = merger(ret[key], curObject[key]);
19116            }
19117          }
19118        }
19119        return ret;
19120      };
19121    };
19122    var deepMerge = baseMerge(deep$1);
19123
19124    var sectionResult = function (sections, settings) {
19125      return {
19126        sections: constant(sections),
19127        settings: constant(settings)
19128      };
19129    };
19130    var deviceDetection = detect$3().deviceType;
19131    var isTouch = deviceDetection.isTouch();
19132    var isPhone = deviceDetection.isPhone();
19133    var isTablet = deviceDetection.isTablet();
19134    var legacyMobilePlugins = [
19135      'lists',
19136      'autolink',
19137      'autosave'
19138    ];
19139    var defaultTouchSettings = {
19140      table_grid: false,
19141      object_resizing: false,
19142      resize: false
19143    };
19144    var normalizePlugins = function (plugins) {
19145      var pluginNames = isArray(plugins) ? plugins.join(' ') : plugins;
19146      var trimmedPlugins = map(isString(pluginNames) ? pluginNames.split(' ') : [], trim);
19147      return filter(trimmedPlugins, function (item) {
19148        return item.length > 0;
19149      });
19150    };
19151    var filterLegacyMobilePlugins = function (plugins) {
19152      return filter(plugins, curry(contains, legacyMobilePlugins));
19153    };
19154    var extractSections = function (keys, settings) {
19155      var result = bifilter(settings, function (value, key) {
19156        return contains(keys, key);
19157      });
19158      return sectionResult(result.t, result.f);
19159    };
19160    var getSection = function (sectionResult, name, defaults) {
19161      if (defaults === void 0) {
19162        defaults = {};
19163      }
19164      var sections = sectionResult.sections();
19165      var sectionSettings = sections.hasOwnProperty(name) ? sections[name] : {};
19166      return Tools.extend({}, defaults, sectionSettings);
19167    };
19168    var hasSection = function (sectionResult, name) {
19169      return sectionResult.sections().hasOwnProperty(name);
19170    };
19171    var isSectionTheme = function (sectionResult, name, theme) {
19172      var section = sectionResult.sections();
19173      return hasSection(sectionResult, name) && section[name].theme === theme;
19174    };
19175    var getSectionConfig = function (sectionResult, name) {
19176      return hasSection(sectionResult, name) ? sectionResult.sections()[name] : {};
19177    };
19178    var getToolbarMode = function (settings, defaultVal) {
19179      return get(settings, 'toolbar_mode').orThunk(function () {
19180        return get(settings, 'toolbar_drawer').map(function (val) {
19181          return val === false ? 'wrap' : val;
19182        });
19183      }).getOr(defaultVal);
19184    };
19185    var getDefaultSettings = function (settings, id, documentBaseUrl, isTouch, editor) {
19186      var baseDefaults = {
19187        id: id,
19188        theme: 'silver',
19189        toolbar_mode: getToolbarMode(settings, 'floating'),
19190        plugins: '',
19191        document_base_url: documentBaseUrl,
19192        add_form_submit_trigger: true,
19193        submit_patch: true,
19194        add_unload_trigger: true,
19195        convert_urls: true,
19196        relative_urls: true,
19197        remove_script_host: true,
19198        object_resizing: true,
19199        doctype: '<!DOCTYPE html>',
19200        visual: true,
19201        font_size_legacy_values: 'xx-small,small,medium,large,x-large,xx-large,300%',
19202        forced_root_block: 'p',
19203        hidden_input: true,
19204        inline_styles: true,
19205        convert_fonts_to_spans: true,
19206        indent: true,
19207        indent_before: 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,th,ul,ol,li,dl,dt,dd,area,table,thead,' + 'tfoot,tbody,tr,section,summary,article,hgroup,aside,figure,figcaption,option,optgroup,datalist',
19208        indent_after: 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,th,ul,ol,li,dl,dt,dd,area,table,thead,' + 'tfoot,tbody,tr,section,summary,article,hgroup,aside,figure,figcaption,option,optgroup,datalist',
19209        entity_encoding: 'named',
19210        url_converter: editor.convertURL,
19211        url_converter_scope: editor
19212      };
19213      return __assign(__assign({}, baseDefaults), isTouch ? defaultTouchSettings : {});
19214    };
19215    var getDefaultMobileSettings = function (mobileSettings, isPhone) {
19216      var defaultMobileSettings = {
19217        resize: false,
19218        toolbar_mode: getToolbarMode(mobileSettings, 'scrolling'),
19219        toolbar_sticky: false
19220      };
19221      var defaultPhoneSettings = { menubar: false };
19222      return __assign(__assign(__assign({}, defaultTouchSettings), defaultMobileSettings), isPhone ? defaultPhoneSettings : {});
19223    };
19224    var getExternalPlugins$1 = function (overrideSettings, settings) {
19225      var userDefinedExternalPlugins = settings.external_plugins ? settings.external_plugins : {};
19226      if (overrideSettings && overrideSettings.external_plugins) {
19227        return Tools.extend({}, overrideSettings.external_plugins, userDefinedExternalPlugins);
19228      } else {
19229        return userDefinedExternalPlugins;
19230      }
19231    };
19232    var combinePlugins = function (forcedPlugins, plugins) {
19233      return [].concat(normalizePlugins(forcedPlugins)).concat(normalizePlugins(plugins));
19234    };
19235    var processPlugins = function (isMobileDevice, sectionResult, defaultOverrideSettings, settings) {
19236      var forcedPlugins = normalizePlugins(defaultOverrideSettings.forced_plugins);
19237      var desktopPlugins = normalizePlugins(settings.plugins);
19238      var mobileConfig = getSectionConfig(sectionResult, 'mobile');
19239      var mobilePlugins = mobileConfig.plugins ? normalizePlugins(mobileConfig.plugins) : desktopPlugins;
19240      var platformPlugins = isMobileDevice && isSectionTheme(sectionResult, 'mobile', 'mobile') ? filterLegacyMobilePlugins(mobilePlugins) : isMobileDevice && hasSection(sectionResult, 'mobile') ? mobilePlugins : desktopPlugins;
19241      var combinedPlugins = combinePlugins(forcedPlugins, platformPlugins);
19242      return Tools.extend(settings, { plugins: combinedPlugins.join(' ') });
19243    };
19244    var isOnMobile = function (isMobileDevice, sectionResult) {
19245      return isMobileDevice && hasSection(sectionResult, 'mobile');
19246    };
19247    var combineSettings = function (isMobileDevice, isPhone, defaultSettings, defaultOverrideSettings, settings) {
19248      var defaultDeviceSettings = isMobileDevice ? { mobile: getDefaultMobileSettings(settings.mobile || {}, isPhone) } : {};
19249      var sectionResult = extractSections(['mobile'], deepMerge(defaultDeviceSettings, settings));
19250      var extendedSettings = Tools.extend(defaultSettings, defaultOverrideSettings, sectionResult.settings(), isOnMobile(isMobileDevice, sectionResult) ? getSection(sectionResult, 'mobile') : {}, {
19251        validate: true,
19252        external_plugins: getExternalPlugins$1(defaultOverrideSettings, sectionResult.settings())
19253      });
19254      return processPlugins(isMobileDevice, sectionResult, defaultOverrideSettings, extendedSettings);
19255    };
19256    var getEditorSettings = function (editor, id, documentBaseUrl, defaultOverrideSettings, settings) {
19257      var defaultSettings = getDefaultSettings(settings, id, documentBaseUrl, isTouch, editor);
19258      return combineSettings(isPhone || isTablet, isPhone, defaultSettings, defaultOverrideSettings, settings);
19259    };
19260    var getFiltered = function (predicate, editor, name) {
19261      return Optional.from(editor.settings[name]).filter(predicate);
19262    };
19263    var getParamObject = function (value) {
19264      var output = {};
19265      if (typeof value === 'string') {
19266        each(value.indexOf('=') > 0 ? value.split(/[;,](?![^=;,]*(?:[;,]|$))/) : value.split(','), function (val) {
19267          var arr = val.split('=');
19268          if (arr.length > 1) {
19269            output[Tools.trim(arr[0])] = Tools.trim(arr[1]);
19270          } else {
19271            output[Tools.trim(arr[0])] = Tools.trim(arr[0]);
19272          }
19273        });
19274      } else {
19275        output = value;
19276      }
19277      return output;
19278    };
19279    var isArrayOf = function (p) {
19280      return function (a) {
19281        return isArray(a) && forall(a, p);
19282      };
19283    };
19284    var getParam = function (editor, name, defaultVal, type) {
19285      var value = name in editor.settings ? editor.settings[name] : defaultVal;
19286      if (type === 'hash') {
19287        return getParamObject(value);
19288      } else if (type === 'string') {
19289        return getFiltered(isString, editor, name).getOr(defaultVal);
19290      } else if (type === 'number') {
19291        return getFiltered(isNumber, editor, name).getOr(defaultVal);
19292      } else if (type === 'boolean') {
19293        return getFiltered(isBoolean, editor, name).getOr(defaultVal);
19294      } else if (type === 'object') {
19295        return getFiltered(isObject, editor, name).getOr(defaultVal);
19296      } else if (type === 'array') {
19297        return getFiltered(isArray, editor, name).getOr(defaultVal);
19298      } else if (type === 'string[]') {
19299        return getFiltered(isArrayOf(isString), editor, name).getOr(defaultVal);
19300      } else if (type === 'function') {
19301        return getFiltered(isFunction, editor, name).getOr(defaultVal);
19302      } else {
19303        return value;
19304      }
19305    };
19306
19307    var CreateIconManager = function () {
19308      var lookup = {};
19309      var add = function (id, iconPack) {
19310        lookup[id] = iconPack;
19311      };
19312      var get = function (id) {
19313        if (lookup[id]) {
19314          return lookup[id];
19315        }
19316        return { icons: {} };
19317      };
19318      var has$1 = function (id) {
19319        return has(lookup, id);
19320      };
19321      return {
19322        add: add,
19323        get: get,
19324        has: has$1
19325      };
19326    };
19327    var IconManager = CreateIconManager();
19328
19329    var getProp = function (propName, elm) {
19330      var rawElm = elm.dom;
19331      return rawElm[propName];
19332    };
19333    var getComputedSizeProp = function (propName, elm) {
19334      return parseInt(get$4(elm, propName), 10);
19335    };
19336    var getClientWidth = curry(getProp, 'clientWidth');
19337    var getClientHeight = curry(getProp, 'clientHeight');
19338    var getMarginTop = curry(getComputedSizeProp, 'margin-top');
19339    var getMarginLeft = curry(getComputedSizeProp, 'margin-left');
19340    var getBoundingClientRect$1 = function (elm) {
19341      return elm.dom.getBoundingClientRect();
19342    };
19343    var isInsideElementContentArea = function (bodyElm, clientX, clientY) {
19344      var clientWidth = getClientWidth(bodyElm);
19345      var clientHeight = getClientHeight(bodyElm);
19346      return clientX >= 0 && clientY >= 0 && clientX <= clientWidth && clientY <= clientHeight;
19347    };
19348    var transpose = function (inline, elm, clientX, clientY) {
19349      var clientRect = getBoundingClientRect$1(elm);
19350      var deltaX = inline ? clientRect.left + elm.dom.clientLeft + getMarginLeft(elm) : 0;
19351      var deltaY = inline ? clientRect.top + elm.dom.clientTop + getMarginTop(elm) : 0;
19352      var x = clientX - deltaX;
19353      var y = clientY - deltaY;
19354      return {
19355        x: x,
19356        y: y
19357      };
19358    };
19359    var isXYInContentArea = function (editor, clientX, clientY) {
19360      var bodyElm = SugarElement.fromDom(editor.getBody());
19361      var targetElm = editor.inline ? bodyElm : documentElement(bodyElm);
19362      var transposedPoint = transpose(editor.inline, targetElm, clientX, clientY);
19363      return isInsideElementContentArea(targetElm, transposedPoint.x, transposedPoint.y);
19364    };
19365    var fromDomSafe = function (node) {
19366      return Optional.from(node).map(SugarElement.fromDom);
19367    };
19368    var isEditorAttachedToDom = function (editor) {
19369      var rawContainer = editor.inline ? editor.getBody() : editor.getContentAreaContainer();
19370      return fromDomSafe(rawContainer).map(inBody).getOr(false);
19371    };
19372
19373    function NotificationManagerImpl() {
19374      var unimplemented = function () {
19375        throw new Error('Theme did not provide a NotificationManager implementation.');
19376      };
19377      return {
19378        open: unimplemented,
19379        close: unimplemented,
19380        reposition: unimplemented,
19381        getArgs: unimplemented
19382      };
19383    }
19384
19385    function NotificationManager(editor) {
19386      var notifications = [];
19387      var getImplementation = function () {
19388        var theme = editor.theme;
19389        return theme && theme.getNotificationManagerImpl ? theme.getNotificationManagerImpl() : NotificationManagerImpl();
19390      };
19391      var getTopNotification = function () {
19392        return Optional.from(notifications[0]);
19393      };
19394      var isEqual = function (a, b) {
19395        return a.type === b.type && a.text === b.text && !a.progressBar && !a.timeout && !b.progressBar && !b.timeout;
19396      };
19397      var reposition = function () {
19398        if (notifications.length > 0) {
19399          getImplementation().reposition(notifications);
19400        }
19401      };
19402      var addNotification = function (notification) {
19403        notifications.push(notification);
19404      };
19405      var closeNotification = function (notification) {
19406        findIndex(notifications, function (otherNotification) {
19407          return otherNotification === notification;
19408        }).each(function (index) {
19409          notifications.splice(index, 1);
19410        });
19411      };
19412      var open = function (spec) {
19413        if (editor.removed || !isEditorAttachedToDom(editor)) {
19414          return;
19415        }
19416        return find(notifications, function (notification) {
19417          return isEqual(getImplementation().getArgs(notification), spec);
19418        }).getOrThunk(function () {
19419          editor.editorManager.setActive(editor);
19420          var notification = getImplementation().open(spec, function () {
19421            closeNotification(notification);
19422            reposition();
19423            getTopNotification().fold(function () {
19424              return editor.focus();
19425            }, function (top) {
19426              return focus(SugarElement.fromDom(top.getEl()));
19427            });
19428          });
19429          addNotification(notification);
19430          reposition();
19431          return notification;
19432        });
19433      };
19434      var close = function () {
19435        getTopNotification().each(function (notification) {
19436          getImplementation().close(notification);
19437          closeNotification(notification);
19438          reposition();
19439        });
19440      };
19441      var getNotifications = function () {
19442        return notifications;
19443      };
19444      var registerEvents = function (editor) {
19445        editor.on('SkinLoaded', function () {
19446          var serviceMessage = getServiceMessage(editor);
19447          if (serviceMessage) {
19448            open({
19449              text: serviceMessage,
19450              type: 'warning',
19451              timeout: 0
19452            });
19453          }
19454        });
19455        editor.on('ResizeEditor ResizeWindow NodeChange', function () {
19456          Delay.requestAnimationFrame(reposition);
19457        });
19458        editor.on('remove', function () {
19459          each(notifications.slice(), function (notification) {
19460            getImplementation().close(notification);
19461          });
19462        });
19463      };
19464      registerEvents(editor);
19465      return {
19466        open: open,
19467        close: close,
19468        getNotifications: getNotifications
19469      };
19470    }
19471
19472    var PluginManager = AddOnManager$1.PluginManager;
19473
19474    var ThemeManager = AddOnManager$1.ThemeManager;
19475
19476    function WindowManagerImpl () {
19477      var unimplemented = function () {
19478        throw new Error('Theme did not provide a WindowManager implementation.');
19479      };
19480      return {
19481        open: unimplemented,
19482        openUrl: unimplemented,
19483        alert: unimplemented,
19484        confirm: unimplemented,
19485        close: unimplemented,
19486        getParams: unimplemented,
19487        setParams: unimplemented
19488      };
19489    }
19490
19491    var WindowManager = function (editor) {
19492      var dialogs = [];
19493      var getImplementation = function () {
19494        var theme = editor.theme;
19495        return theme && theme.getWindowManagerImpl ? theme.getWindowManagerImpl() : WindowManagerImpl();
19496      };
19497      var funcBind = function (scope, f) {
19498        return function () {
19499          return f ? f.apply(scope, arguments) : undefined;
19500        };
19501      };
19502      var fireOpenEvent = function (dialog) {
19503        editor.fire('OpenWindow', { dialog: dialog });
19504      };
19505      var fireCloseEvent = function (dialog) {
19506        editor.fire('CloseWindow', { dialog: dialog });
19507      };
19508      var addDialog = function (dialog) {
19509        dialogs.push(dialog);
19510        fireOpenEvent(dialog);
19511      };
19512      var closeDialog = function (dialog) {
19513        fireCloseEvent(dialog);
19514        dialogs = filter(dialogs, function (otherDialog) {
19515          return otherDialog !== dialog;
19516        });
19517        if (dialogs.length === 0) {
19518          editor.focus();
19519        }
19520      };
19521      var getTopDialog = function () {
19522        return Optional.from(dialogs[dialogs.length - 1]);
19523      };
19524      var storeSelectionAndOpenDialog = function (openDialog) {
19525        editor.editorManager.setActive(editor);
19526        store(editor);
19527        var dialog = openDialog();
19528        addDialog(dialog);
19529        return dialog;
19530      };
19531      var open = function (args, params) {
19532        return storeSelectionAndOpenDialog(function () {
19533          return getImplementation().open(args, params, closeDialog);
19534        });
19535      };
19536      var openUrl = function (args) {
19537        return storeSelectionAndOpenDialog(function () {
19538          return getImplementation().openUrl(args, closeDialog);
19539        });
19540      };
19541      var alert = function (message, callback, scope) {
19542        getImplementation().alert(message, funcBind(scope ? scope : this, callback));
19543      };
19544      var confirm = function (message, callback, scope) {
19545        getImplementation().confirm(message, funcBind(scope ? scope : this, callback));
19546      };
19547      var close = function () {
19548        getTopDialog().each(function (dialog) {
19549          getImplementation().close(dialog);
19550          closeDialog(dialog);
19551        });
19552      };
19553      editor.on('remove', function () {
19554        each(dialogs, function (dialog) {
19555          getImplementation().close(dialog);
19556        });
19557      });
19558      return {
19559        open: open,
19560        openUrl: openUrl,
19561        alert: alert,
19562        confirm: confirm,
19563        close: close
19564      };
19565    };
19566
19567    var displayNotification = function (editor, message) {
19568      editor.notificationManager.open({
19569        type: 'error',
19570        text: message
19571      });
19572    };
19573    var displayError = function (editor, message) {
19574      if (editor._skinLoaded) {
19575        displayNotification(editor, message);
19576      } else {
19577        editor.on('SkinLoaded', function () {
19578          displayNotification(editor, message);
19579        });
19580      }
19581    };
19582    var uploadError = function (editor, message) {
19583      displayError(editor, I18n.translate([
19584        'Failed to upload image: {0}',
19585        message
19586      ]));
19587    };
19588    var logError = function (editor, errorType, msg) {
19589      fireError(editor, errorType, { message: msg });
19590      console.error(msg);
19591    };
19592    var createLoadError = function (type, url, name) {
19593      return name ? 'Failed to load ' + type + ': ' + name + ' from url ' + url : 'Failed to load ' + type + ' url: ' + url;
19594    };
19595    var pluginLoadError = function (editor, url, name) {
19596      logError(editor, 'PluginLoadError', createLoadError('plugin', url, name));
19597    };
19598    var iconsLoadError = function (editor, url, name) {
19599      logError(editor, 'IconsLoadError', createLoadError('icons', url, name));
19600    };
19601    var languageLoadError = function (editor, url, name) {
19602      logError(editor, 'LanguageLoadError', createLoadError('language', url, name));
19603    };
19604    var pluginInitError = function (editor, name, err) {
19605      var message = I18n.translate([
19606        'Failed to initialize plugin: {0}',
19607        name
19608      ]);
19609      initError(message, err);
19610      displayError(editor, message);
19611    };
19612    var initError = function (message) {
19613      var x = [];
19614      for (var _i = 1; _i < arguments.length; _i++) {
19615        x[_i - 1] = arguments[_i];
19616      }
19617      var console = window.console;
19618      if (console) {
19619        if (console.error) {
19620          console.error.apply(console, __spreadArrays([message], x));
19621        } else {
19622          console.log.apply(console, __spreadArrays([message], x));
19623        }
19624      }
19625    };
19626
19627    var isContentCssSkinName = function (url) {
19628      return /^[a-z0-9\-]+$/i.test(url);
19629    };
19630    var getContentCssUrls = function (editor) {
19631      var contentCss = getContentCss(editor);
19632      var skinUrl = editor.editorManager.baseURL + '/skins/content';
19633      var suffix = editor.editorManager.suffix;
19634      var contentCssFile = 'content' + suffix + '.css';
19635      var inline = editor.inline === true;
19636      return map(contentCss, function (url) {
19637        if (isContentCssSkinName(url) && !inline) {
19638          return skinUrl + '/' + url + '/' + contentCssFile;
19639        } else {
19640          return editor.documentBaseURI.toAbsolute(url);
19641        }
19642      });
19643    };
19644    var appendContentCssFromSettings = function (editor) {
19645      editor.contentCSS = editor.contentCSS.concat(getContentCssUrls(editor));
19646    };
19647
19648    function Uploader(uploadStatus, settings) {
19649      var pendingPromises = {};
19650      var pathJoin = function (path1, path2) {
19651        if (path1) {
19652          return path1.replace(/\/$/, '') + '/' + path2.replace(/^\//, '');
19653        }
19654        return path2;
19655      };
19656      var defaultHandler = function (blobInfo, success, failure, progress) {
19657        var xhr = new XMLHttpRequest();
19658        xhr.open('POST', settings.url);
19659        xhr.withCredentials = settings.credentials;
19660        xhr.upload.onprogress = function (e) {
19661          progress(e.loaded / e.total * 100);
19662        };
19663        xhr.onerror = function () {
19664          failure('Image upload failed due to a XHR Transport error. Code: ' + xhr.status);
19665        };
19666        xhr.onload = function () {
19667          if (xhr.status < 200 || xhr.status >= 300) {
19668            failure('HTTP Error: ' + xhr.status);
19669            return;
19670          }
19671          var json = JSON.parse(xhr.responseText);
19672          if (!json || typeof json.location !== 'string') {
19673            failure('Invalid JSON: ' + xhr.responseText);
19674            return;
19675          }
19676          success(pathJoin(settings.basePath, json.location));
19677        };
19678        var formData = new FormData();
19679        formData.append('file', blobInfo.blob(), blobInfo.filename());
19680        xhr.send(formData);
19681      };
19682      var noUpload = function () {
19683        return new promiseObj(function (resolve) {
19684          resolve([]);
19685        });
19686      };
19687      var handlerSuccess = function (blobInfo, url) {
19688        return {
19689          url: url,
19690          blobInfo: blobInfo,
19691          status: true
19692        };
19693      };
19694      var handlerFailure = function (blobInfo, message, options) {
19695        return {
19696          url: '',
19697          blobInfo: blobInfo,
19698          status: false,
19699          error: {
19700            message: message,
19701            options: options
19702          }
19703        };
19704      };
19705      var resolvePending = function (blobUri, result) {
19706        Tools.each(pendingPromises[blobUri], function (resolve) {
19707          resolve(result);
19708        });
19709        delete pendingPromises[blobUri];
19710      };
19711      var uploadBlobInfo = function (blobInfo, handler, openNotification) {
19712        uploadStatus.markPending(blobInfo.blobUri());
19713        return new promiseObj(function (resolve) {
19714          var notification, progress;
19715          var noop = function () {
19716          };
19717          try {
19718            var closeNotification_1 = function () {
19719              if (notification) {
19720                notification.close();
19721                progress = noop;
19722              }
19723            };
19724            var success = function (url) {
19725              closeNotification_1();
19726              uploadStatus.markUploaded(blobInfo.blobUri(), url);
19727              resolvePending(blobInfo.blobUri(), handlerSuccess(blobInfo, url));
19728              resolve(handlerSuccess(blobInfo, url));
19729            };
19730            var failure = function (error, options) {
19731              var failureOptions = options ? options : {};
19732              closeNotification_1();
19733              uploadStatus.removeFailed(blobInfo.blobUri());
19734              resolvePending(blobInfo.blobUri(), handlerFailure(blobInfo, error, failureOptions));
19735              resolve(handlerFailure(blobInfo, error, failureOptions));
19736            };
19737            progress = function (percent) {
19738              if (percent < 0 || percent > 100) {
19739                return;
19740              }
19741              if (!notification) {
19742                notification = openNotification();
19743              }
19744              notification.progressBar.value(percent);
19745            };
19746            handler(blobInfo, success, failure, progress);
19747          } catch (ex) {
19748            resolve(handlerFailure(blobInfo, ex.message, {}));
19749          }
19750        });
19751      };
19752      var isDefaultHandler = function (handler) {
19753        return handler === defaultHandler;
19754      };
19755      var pendingUploadBlobInfo = function (blobInfo) {
19756        var blobUri = blobInfo.blobUri();
19757        return new promiseObj(function (resolve) {
19758          pendingPromises[blobUri] = pendingPromises[blobUri] || [];
19759          pendingPromises[blobUri].push(resolve);
19760        });
19761      };
19762      var uploadBlobs = function (blobInfos, openNotification) {
19763        blobInfos = Tools.grep(blobInfos, function (blobInfo) {
19764          return !uploadStatus.isUploaded(blobInfo.blobUri());
19765        });
19766        return promiseObj.all(Tools.map(blobInfos, function (blobInfo) {
19767          return uploadStatus.isPending(blobInfo.blobUri()) ? pe
19767ndingUploadBlobInfo(blobInfo) : uploadBlobInfo(blobInfo, settings.handler, openNotification);
19768        }));
19769      };
19770      var upload = function (blobInfos, openNotification) {
19771        return !settings.url && isDefaultHandler(settings.handler) ? noUpload() : uploadBlobs(blobInfos, openNotification);
19772      };
19773      if (isFunction(settings.handler) === false) {
19774        settings.handler = defaultHandler;
19775      }
19776      return { upload: upload };
19777    }
19778
19779    function UploadStatus () {
19780      var PENDING = 1, UPLOADED = 2;
19781      var blobUriStatuses = {};
19782      var createStatus = function (status, resultUri) {
19783        return {
19784          status: status,
19785          resultUri: resultUri
19786        };
19787      };
19788      var hasBlobUri = function (blobUri) {
19789        return blobUri in blobUriStatuses;
19790      };
19791      var getResultUri = function (blobUri) {
19792        var result = blobUriStatuses[blobUri];
19793        return result ? result.resultUri : null;
19794      };
19795      var isPending = function (blobUri) {
19796        return hasBlobUri(blobUri) ? blobUriStatuses[blobUri].status === PENDING : false;
19797      };
19798      var isUploaded = function (blobUri) {
19799        return hasBlobUri(blobUri) ? blobUriStatuses[blobUri].status === UPLOADED : false;
19800      };
19801      var markPending = function (blobUri) {
19802        blobUriStatuses[blobUri] = createStatus(PENDING, null);
19803      };
19804      var markUploaded = function (blobUri, resultUri) {
19805        blobUriStatuses[blobUri] = createStatus(UPLOADED, resultUri);
19806      };
19807      var removeFailed = function (blobUri) {
19808        delete blobUriStatuses[blobUri];
19809      };
19810      var destroy = function () {
19811        blobUriStatuses = {};
19812      };
19813      return {
19814        hasBlobUri: hasBlobUri,
19815        getResultUri: getResultUri,
19816        isPending: isPending,
19817        isUploaded: isUploaded,
19818        markPending: markPending,
19819        markUploaded: markUploaded,
19820        removeFailed: removeFailed,
19821        destroy: destroy
19822      };
19823    }
19824
19825    var count$1 = 0;
19826    var seed = function () {
19827      var rnd = function () {
19828        return Math.round(Math.random() * 4294967295).toString(36);
19829      };
19830      var now = new Date().getTime();
19831      return 's' + now.toString(36) + rnd() + rnd() + rnd();
19832    };
19833    var uuid = function (prefix) {
19834      return prefix + count$1++ + seed();
19835    };
19836
19837    var BlobCache = function () {
19838      var cache = [];
19839      var mimeToExt = function (mime) {
19840        var mimes = {
19841          'image/jpeg': 'jpg',
19842          'image/jpg': 'jpg',
19843          'image/gif': 'gif',
19844          'image/png': 'png'
19845        };
19846        return mimes[mime.toLowerCase()] || 'dat';
19847      };
19848      var create = function (o, blob, base64, filename) {
19849        if (isString(o)) {
19850          var id = o;
19851          return toBlobInfo({
19852            id: id,
19853            name: filename,
19854            blob: blob,
19855            base64: base64
19856          });
19857        } else if (isObject(o)) {
19858          return toBlobInfo(o);
19859        } else {
19860          throw new Error('Unknown input type');
19861        }
19862      };
19863      var toBlobInfo = function (o) {
19864        if (!o.blob || !o.base64) {
19865          throw new Error('blob and base64 representations of the image are required for BlobInfo to be created');
19866        }
19867        var id = o.id || uuid('blobid');
19868        var name = o.name || id;
19869        return {
19870          id: constant(id),
19871          name: constant(name),
19872          filename: constant(name + '.' + mimeToExt(o.blob.type)),
19873          blob: constant(o.blob),
19874          base64: constant(o.base64),
19875          blobUri: constant(o.blobUri || URL.createObjectURL(o.blob)),
19876          uri: constant(o.uri)
19877        };
19878      };
19879      var add = function (blobInfo) {
19880        if (!get(blobInfo.id())) {
19881          cache.push(blobInfo);
19882        }
19883      };
19884      var findFirst = function (predicate) {
19885        return find(cache, predicate).getOrUndefined();
19886      };
19887      var get = function (id) {
19888        return findFirst(function (cachedBlobInfo) {
19889          return cachedBlobInfo.id() === id;
19890        });
19891      };
19892      var getByUri = function (blobUri) {
19893        return findFirst(function (blobInfo) {
19894          return blobInfo.blobUri() === blobUri;
19895        });
19896      };
19897      var getByData = function (base64, type) {
19898        return findFirst(function (blobInfo) {
19899          return blobInfo.base64() === base64 && blobInfo.blob().type === type;
19900        });
19901      };
19902      var removeByUri = function (blobUri) {
19903        cache = filter(cache, function (blobInfo) {
19904          if (blobInfo.blobUri() === blobUri) {
19905            URL.revokeObjectURL(blobInfo.blobUri());
19906            return false;
19907          }
19908          return true;
19909        });
19910      };
19911      var destroy = function () {
19912        each(cache, function (cachedBlobInfo) {
19913          URL.revokeObjectURL(cachedBlobInfo.blobUri());
19914        });
19915        cache = [];
19916      };
19917      return {
19918        create: create,
19919        add: add,
19920        get: get,
19921        getByUri: getByUri,
19922        getByData: getByData,
19923        findFirst: findFirst,
19924        removeByUri: removeByUri,
19925        destroy: destroy
19926      };
19927    };
19928
19929    var EditorUpload = function (editor) {
19930      var blobCache = BlobCache();
19931      var uploader, imageScanner;
19932      var uploadStatus = UploadStatus();
19933      var urlFilters = [];
19934      var aliveGuard = function (callback) {
19935        return function (result) {
19936          if (editor.selection) {
19937            return callback(result);
19938          }
19939          return [];
19940        };
19941      };
19942      var cacheInvalidator = function (url) {
19943        return url + (url.indexOf('?') === -1 ? '?' : '&') + new Date().getTime();
19944      };
19945      var replaceString = function (content, search, replace) {
19946        var index = 0;
19947        do {
19948          index = content.indexOf(search, index);
19949          if (index !== -1) {
19950            content = content.substring(0, index) + replace + content.substr(index + search.length);
19951            index += replace.length - search.length + 1;
19952          }
19953        } while (index !== -1);
19954        return content;
19955      };
19956      var replaceImageUrl = function (content, targetUrl, replacementUrl) {
19957        var replacementString = 'src="' + replacementUrl + '"' + (replacementUrl === Env.transparentSrc ? ' data-mce-placeholder="1"' : '');
19958        content = replaceString(content, 'src="' + targetUrl + '"', replacementString);
19959        content = replaceString(content, 'data-mce-src="' + targetUrl + '"', 'data-mce-src="' + replacementUrl + '"');
19960        return content;
19961      };
19962      var replaceUrlInUndoStack = function (targetUrl, replacementUrl) {
19963        each(editor.undoManager.data, function (level) {
19964          if (level.type === 'fragmented') {
19965            level.fragments = map(level.fragments, function (fragment) {
19966              return replaceImageUrl(fragment, targetUrl, replacementUrl);
19967            });
19968          } else {
19969            level.content = replaceImageUrl(level.content, targetUrl, replacementUrl);
19970          }
19971        });
19972      };
19973      var openNotification = function () {
19974        return editor.notificationManager.open({
19975          text: editor.translate('Image uploading...'),
19976          type: 'info',
19977          timeout: -1,
19978          progressBar: true
19979        });
19980      };
19981      var replaceImageUriInView = function (image, resultUri) {
19982        var src = editor.convertURL(resultUri, 'src');
19983        replaceUrlInUndoStack(image.src, resultUri);
19984        editor.$(image).attr({
19985          'src': shouldReuseFileName(editor) ? cacheInvalidator(resultUri) : resultUri,
19986          'data-mce-src': src
19987        });
19988      };
19989      var uploadImages = function (callback) {
19990        if (!uploader) {
19991          uploader = Uploader(uploadStatus, {
19992            url: getImageUploadUrl(editor),
19993            basePath: getImageUploadBasePath(editor),
19994            credentials: getImagesUploadCredentials(editor),
19995            handler: getImagesUploadHandler(editor)
19996          });
19997        }
19998        return scanForImages().then(aliveGuard(function (imageInfos) {
19999          var blobInfos = map(imageInfos, function (imageInfo) {
20000            return imageInfo.blobInfo;
20001          });
20002          return uploader.upload(blobInfos, openNotification).then(aliveGuard(function (result) {
20003            var imagesToRemove = [];
20004            var filteredResult = map(result, function (uploadInfo, index) {
20005              var blobInfo = imageInfos[index].blobInfo;
20006              var image = imageInfos[index].image;
20007              if (uploadInfo.status && shouldReplaceBlobUris(editor)) {
20008                blobCache.removeByUri(image.src);
20009                replaceImageUriInView(image, uploadInfo.url);
20010              } else if (uploadInfo.error) {
20011                if (uploadInfo.error.options.remove) {
20012                  replaceUrlInUndoStack(image.getAttribute('src'), Env.transparentSrc);
20013                  imagesToRemove.push(image);
20014                }
20015                uploadError(editor, uploadInfo.error.message);
20016              }
20017              return {
20018                element: image,
20019                status: uploadInfo.status,
20020                uploadUri: uploadInfo.url,
20021                blobInfo: blobInfo
20022              };
20023            });
20024            if (imagesToRemove.length > 0) {
20025              if (isRtc(editor)) {
20026                console.error('Removing images on failed uploads is currently unsupported for RTC');
20027              } else {
20028                editor.undoManager.transact(function () {
20029                  each(imagesToRemove, function (element) {
20030                    editor.dom.remove(element);
20031                    blobCache.removeByUri(element.src);
20032                  });
20033                });
20034              }
20035            }
20036            if (callback) {
20037              callback(filteredResult);
20038            }
20039            return filteredResult;
20040          }));
20041        }));
20042      };
20043      var uploadImagesAuto = function (callback) {
20044        if (isAutomaticUploadsEnabled(editor)) {
20045          return uploadImages(callback);
20046        }
20047      };
20048      var isValidDataUriImage = function (imgElm) {
20049        if (forall(urlFilters, function (filter) {
20050            return filter(imgElm);
20051          }) === false) {
20052          return false;
20053        }
20054        if (imgElm.getAttribute('src').indexOf('data:') === 0) {
20055          var dataImgFilter = getImagesDataImgFilter(editor);
20056          return dataImgFilter(imgElm);
20057        }
20058        return true;
20059      };
20060      var addFilter = function (filter) {
20061        urlFilters.push(filter);
20062      };
20063      var scanForImages = function () {
20064        if (!imageScanner) {
20065          imageScanner = ImageScanner(uploadStatus, blobCache);
20066        }
20067        return imageScanner.findAll(editor.getBody(), isValidDataUriImage).then(aliveGuard(function (result) {
20068          result = filter(result, function (resultItem) {
20069            if (typeof resultItem === 'string') {
20070              displayError(editor, resultItem);
20071              return false;
20072            }
20073            return true;
20074          });
20075          each(result, function (resultItem) {
20076            replaceUrlInUndoStack(resultItem.image.src, resultItem.blobInfo.blobUri());
20077            resultItem.image.src = resultItem.blobInfo.blobUri();
20078            resultItem.image.removeAttribute('data-mce-src');
20079          });
20080          return result;
20081        }));
20082      };
20083      var destroy = function () {
20084        blobCache.destroy();
20085        uploadStatus.destroy();
20086        imageScanner = uploader = null;
20087      };
20088      var replaceBlobUris = function (content) {
20089        return content.replace(/src="(blob:[^"]+)"/g, function (match, blobUri) {
20090          var resultUri = uploadStatus.getResultUri(blobUri);
20091          if (resultUri) {
20092            return 'src="' + resultUri + '"';
20093          }
20094          var blobInfo = blobCache.getByUri(blobUri);
20095          if (!blobInfo) {
20096            blobInfo = foldl(editor.editorManager.get(), function (result, editor) {
20097              return result || editor.editorUpload && editor.editorUpload.blobCache.getByUri(blobUri);
20098            }, null);
20099          }
20100          if (blobInfo) {
20101            var blob = blobInfo.blob();
20102            return 'src="data:' + blob.type + ';base64,' + blobInfo.base64() + '"';
20103          }
20104          return match;
20105        });
20106      };
20107      editor.on('SetContent', function () {
20108        if (isAutomaticUploadsEnabled(editor)) {
20109          uploadImagesAuto();
20110        } else {
20111          scanForImages();
20112        }
20113      });
20114      editor.on('RawSaveContent', function (e) {
20115        e.content = replaceBlobUris(e.content);
20116      });
20117      editor.on('GetContent', function (e) {
20118        if (e.source_view || e.format === 'raw') {
20119          return;
20120        }
20121        e.content = replaceBlobUris(e.content);
20122      });
20123      editor.on('PostRender', function () {
20124        editor.parser.addNodeFilter('img', function (images) {
20125          each(images, function (img) {
20126            var src = img.attr('src');
20127            if (blobCache.getByUri(src)) {
20128              return;
20129            }
20130            var resultUri = uploadStatus.getResultUri(src);
20131            if (resultUri) {
20132              img.attr('src', resultUri);
20133            }
20134          });
20135        });
20136      });
20137      return {
20138        blobCache: blobCache,
20139        addFilter: addFilter,
20140        uploadImages: uploadImages,
20141        uploadImagesAuto: uploadImagesAuto,
20142        scanForImages: scanForImages,
20143        destroy: destroy
20144      };
20145    };
20146
20147    var setup$5 = function (registeredFormatListeners, editor) {
20148      var currentFormats = Cell({});
20149      registeredFormatListeners.set({});
20150      editor.on('NodeChange', function (e) {
20151        updateAndFireChangeCallbacks(editor, e.element, currentFormats, registeredFormatListeners.get());
20152      });
20153    };
20154    var updateAndFireChangeCallbacks = function (editor, elm, currentFormats, formatChangeData) {
20155      var formatsList = keys(currentFormats.get());
20156      var newFormats = {};
20157      var matchedFormats = {};
20158      var parents = filter(getParents$1(editor.dom, elm), function (node) {
20159        return node.nodeType === 1 && !node.getAttribute('data-mce-bogus');
20160      });
20161      each$1(formatChangeData, function (data, format) {
20162        Tools.each(parents, function (node) {
20163          if (editor.formatter.matchNode(node, format, {}, data.similar)) {
20164            if (formatsList.indexOf(format) === -1) {
20165              each(data.callbacks, function (callback) {
20166                callback(true, {
20167                  node: node,
20168                  format: format,
20169                  parents: parents
20170                });
20171              });
20172              newFormats[format] = data.callbacks;
20173            }
20174            matchedFormats[format] = data.callbacks;
20175            return false;
20176          }
20177          if (matchesUnInheritedFormatSelector(editor, node, format)) {
20178            return false;
20179          }
20180        });
20181      });
20182      var remainingFormats = filterRemainingFormats(currentFormats.get(), matchedFormats, elm, parents);
20183      currentFormats.set(__assign(__assign({}, newFormats), remainingFormats));
20184    };
20185    var filterRemainingFormats = function (currentFormats, matchedFormats, elm, parents) {
20186      return bifilter(currentFormats, function (callbacks, format) {
20187        if (!has(matchedFormats, format)) {
20188          each(callbacks, function (callback) {
20189            callback(false, {
20190              node: elm,
20191              format: format,
20192              parents: parents
20193            });
20194          });
20195          return false;
20196        } else {
20197          return true;
20198        }
20199      }).t;
20200    };
20201    var addListeners = function (registeredFormatListeners, formats, callback, similar) {
20202      var formatChangeItems = registeredFormatListeners.get();
20203      each(formats.split(','), function (format) {
20204        if (!formatChangeItems[format]) {
20205          formatChangeItems[format] = {
20206            similar: similar,
20207            callbacks: []
20208          };
20209        }
20210        formatChangeItems[format].callbacks.push(callback);
20211      });
20212      registeredFormatListeners.set(formatChangeItems);
20213    };
20214    var removeListeners = function (registeredFormatListeners, formats, callback) {
20215      var formatChangeItems = registeredFormatListeners.get();
20216      each(formats.split(','), function (format) {
20217        formatChangeItems[format].callbacks = filter(formatChangeItems[format].callbacks, function (c) {
20218          return c !== callback;
20219        });
20220        if (formatChangeItems[format].callbacks.length === 0) {
20221          delete formatChangeItems[format];
20222        }
20223      });
20224      registeredFormatListeners.set(formatChangeItems);
20225    };
20226    var formatChanged = function (editor, registeredFormatListeners, formats, callback, similar) {
20227      if (registeredFormatListeners.get() === null) {
20228        setup$5(registeredFormatListeners, editor);
20229      }
20230      addListeners(registeredFormatListeners, formats, callback, similar);
20231      return {
20232        unbind: function () {
20233          return removeListeners(registeredFormatListeners, formats, callback);
20234        }
20235      };
20236    };
20237
20238    var get$9 = function (dom) {
20239      var formats = {
20240        valigntop: [{
20241            selector: 'td,th',
20242            styles: { verticalAlign: 'top' }
20243          }],
20244        valignmiddle: [{
20245            selector: 'td,th',
20246            styles: { verticalAlign: 'middle' }
20247          }],
20248        valignbottom: [{
20249            selector: 'td,th',
20250            styles: { verticalAlign: 'bottom' }
20251          }],
20252        alignleft: [
20253          {
20254            selector: 'figure.image',
20255            collapsed: false,
20256            classes: 'align-left',
20257            ceFalseOverride: true,
20258            preview: 'font-family font-size'
20259          },
20260          {
20261            selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li',
20262            styles: { textAlign: 'left' },
20263            inherit: false,
20264            preview: false,
20265            defaultBlock: 'div'
20266          },
20267          {
20268            selector: 'img,table',
20269            collapsed: false,
20270            styles: { float: 'left' },
20271            preview: 'font-family font-size'
20272          }
20273        ],
20274        aligncenter: [
20275          {
20276            selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li',
20277            styles: { textAlign: 'center' },
20278            inherit: false,
20279            preview: 'font-family font-size',
20280            defaultBlock: 'div'
20281          },
20282          {
20283            selector: 'figure.image',
20284            collapsed: false,
20285            classes: 'align-center',
20286            ceFalseOverride: true,
20287            preview: 'font-family font-size'
20288          },
20289          {
20290            selector: 'img',
20291            collapsed: false,
20292            styles: {
20293              display: 'block',
20294              marginLeft: 'auto',
20295              marginRight: 'auto'
20296            },
20297            preview: false
20298          },
20299          {
20300            selector: 'table',
20301            collapsed: false,
20302            styles: {
20303              marginLeft: 'auto',
20304              marginRight: 'auto'
20305            },
20306            preview: 'font-family font-size'
20307          }
20308        ],
20309        alignright: [
20310          {
20311            selector: 'figure.image',
20312            collapsed: false,
20313            classes: 'align-right',
20314            ceFalseOverride: true,
20315            preview: 'font-family font-size'
20316          },
20317          {
20318            selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li',
20319            styles: { textAlign: 'right' },
20320            inherit: false,
20321            preview: 'font-family font-size',
20322            defaultBlock: 'div'
20323          },
20324          {
20325            selector: 'img,table',
20326            collapsed: false,
20327            styles: { float: 'right' },
20328            preview: 'font-family font-size'
20329          }
20330        ],
20331        alignjustify: [{
20332            selector: 'figure,p,h1,h2,h3,h4,h5,h6,td,th,tr,div,ul,ol,li',
20333            styles: { textAlign: 'justify' },
20334            inherit: false,
20335            defaultBlock: 'div',
20336            preview: 'font-family font-size'
20337          }],
20338        bold: [
20339          {
20340            inline: 'strong',
20341            remove: 'all',
20342            preserve_attributes: [
20343              'class',
20344              'style'
20345            ]
20346          },
20347          {
20348            inline: 'span',
20349            styles: { fontWeight: 'bold' }
20350          },
20351          {
20352            inline: 'b',
20353            remove: 'all',
20354            preserve_attributes: [
20355              'class',
20356              'style'
20357            ]
20358          }
20359        ],
20360        italic: [
20361          {
20362            inline: 'em',
20363            remove: 'all',
20364            preserve_attributes: [
20365              'class',
20366              'style'
20367            ]
20368          },
20369          {
20370            inline: 'span',
20371            styles: { fontStyle: 'italic' }
20372          },
20373          {
20374            inline: 'i',
20375            remove: 'all',
20376            preserve_attributes: [
20377              'class',
20378              'style'
20379            ]
20380          }
20381        ],
20382        underline: [
20383          {
20384            inline: 'span',
20385            styles: { textDecoration: 'underline' },
20386            exact: true
20387          },
20388          {
20389            inline: 'u',
20390            remove: 'all',
20391            preserve_attributes: [
20392              'class',
20393              'style'
20394            ]
20395          }
20396        ],
20397        strikethrough: [
20398          {
20399            inline: 'span',
20400            styles: { textDecoration: 'line-through' },
20401            exact: true
20402          },
20403          {
20404            inline: 'strike',
20405            remove: 'all',
20406            preserve_attributes: [
20407              'class',
20408              'style'
20409            ]
20410          }
20411        ],
20412        forecolor: {
20413          inline: 'span',
20414          styles: { color: '%value' },
20415          links: true,
20416          remove_similar: true,
20417          clear_child_styles: true
20418        },
20419        hilitecolor: {
20420          inline: 'span',
20421          styles: { backgroundColor: '%value' },
20422          links: true,
20423          remove_similar: true,
20424          clear_child_styles: true
20425        },
20426        fontname: {
20427          inline: 'span',
20428          toggle: false,
20429          styles: { fontFamily: '%value' },
20430          clear_child_styles: true
20431        },
20432        fontsize: {
20433          inline: 'span',
20434          toggle: false,
20435          styles: { fontSize: '%value' },
20436          clear_child_styles: true
20437        },
20438        lineheight: {
20439          selector: 'h1,h2,h3,h4,h5,h6,p,li,td,th,div',
20440          defaultBlock: 'p',
20441          styles: { lineHeight: '%value' }
20442        },
20443        fontsize_class: {
20444          inline: 'span',
20445          attributes: { class: '%value' }
20446        },
20447        blockquote: {
20448          block: 'blockquote',
20449          wrapper: true,
20450          remove: 'all'
20451        },
20452        subscript: { inline: 'sub' },
20453        superscript: { inline: 'sup' },
20454        code: { inline: 'code' },
20455        link: {
20456          inline: 'a',
20457          selector: 'a',
20458          remove: 'all',
20459          split: true,
20460          deep: true,
20461          onmatch: function (node, _fmt, _itemName) {
20462            return isElement$1(node) && node.hasAttribute('href');
20463          },
20464          onformat: function (elm, _fmt, vars) {
20465            Tools.each(vars, function (value, key) {
20466              dom.setAttrib(elm, key, value);
20467            });
20468          }
20469        },
20470        removeformat: [
20471          {
20472            selector: 'b,strong,em,i,font,u,strike,sub,sup,dfn,code,samp,kbd,var,cite,mark,q,del,ins',
20473            remove: 'all',
20474            split: true,
20475            expand: false,
20476            block_expand: true,
20477            deep: true
20478          },
20479          {
20480            selector: 'span',
20481            attributes: [
20482              'style',
20483              'class'
20484            ],
20485            remove: 'empty',
20486            split: true,
20487            expand: false,
20488            deep: true
20489          },
20490          {
20491            selector: '*',
20492            attributes: [
20493              'style',
20494              'class'
20495            ],
20496            split: false,
20497            expand: false,
20498            deep: true
20499          }
20500        ]
20501      };
20502      Tools.each('p h1 h2 h3 h4 h5 h6 div address pre div dt dd samp'.split(/\s/), function (name) {
20503        formats[name] = {
20504          block: name,
20505          remove: 'all'
20506        };
20507      });
20508      return formats;
20509    };
20510
20511    function FormatRegistry(editor) {
20512      var formats = {};
20513      var get = function (name) {
20514        return name ? formats[name] : formats;
20515      };
20516      var has$1 = function (name) {
20517        return has(formats, name);
20518      };
20519      var register = function (name, format) {
20520        if (name) {
20521          if (typeof name !== 'string') {
20522            Tools.each(name, function (format, name) {
20523              register(name, format);
20524            });
20525          } else {
20526            if (!isArray(format)) {
20527              format = [format];
20528            }
20529            Tools.each(format, function (format) {
20530              if (typeof format.deep === 'undefined') {
20531                format.deep = !format.selector;
20532              }
20533              if (typeof format.split === 'undefined') {
20534                format.split = !format.selector || format.inline;
20535              }
20536              if (typeof format.remove === 'undefined' && format.selector && !format.inline) {
20537                format.remove = 'none';
20538              }
20539              if (format.selector && format.inline) {
20540                format.mixed = true;
20541                format.block_expand = true;
20542              }
20543              if (typeof format.classes === 'string') {
20544                format.classes = format.classes.split(/\s+/);
20545              }
20546            });
20547            formats[name] = format;
20548          }
20549        }
20550      };
20551      var unregister = function (name) {
20552        if (name && formats[name]) {
20553          delete formats[name];
20554        }
20555        return formats;
20556      };
20557      register(get$9(editor.dom));
20558      register(getFormats(editor));
20559      return {
20560        get: get,
20561        has: has$1,
20562        register: register,
20563        unregister: unregister
20564      };
20565    }
20566
20567    var each$e = Tools.each;
20568    var dom = DOMUtils$1.DOM;
20569    var parsedSelectorToHtml = function (ancestry, editor) {
20570      var elm, item, fragment;
20571      var schema = editor && editor.schema || Schema({});
20572      var decorate = function (elm, item) {
20573        if (item.classes.length) {
20574          dom.addClass(elm, item.classes.join(' '));
20575        }
20576        dom.setAttribs(elm, item.attrs);
20577      };
20578      var createElement = function (sItem) {
20579        item = typeof sItem === 'string' ? {
20580          name: sItem,
20581          classes: [],
20582          attrs: {}
20583        } : sItem;
20584        var elm = dom.create(item.name);
20585        decorate(elm, item);
20586        return elm;
20587      };
20588      var getRequiredParent = function (elm, candidate) {
20589        var name = typeof elm !== 'string' ? elm.nodeName.toLowerCase() : elm;
20590        var elmRule = schema.getElementRule(name);
20591        var parentsRequired = elmRule && elmRule.parentsRequired;
20592        if (parentsRequired && parentsRequired.length) {
20593          return candidate && Tools.inArray(parentsRequired, candidate) !== -1 ? candidate : parentsRequired[0];
20594        } else {
20595          return false;
20596        }
20597      };
20598      var wrapInHtml = function (elm, ancestry, siblings) {
20599        var parent, parentCandidate;
20600        var ancestor = ancestry.length > 0 && ancestry[0];
20601        var ancestorName = ancestor && ancestor.name;
20602        var parentRequired = getRequiredParent(elm, ancestorName);
20603        if (parentRequired) {
20604          if (ancestorName === parentRequired) {
20605            parentCandidate = ancestry[0];
20606            ancestry = ancestry.slice(1);
20607          } else {
20608            parentCandidate = parentRequired;
20609          }
20610        } else if (ancestor) {
20611          parentCandidate = ancestry[0];
20612          ancestry = ancestry.slice(1);
20613        } else if (!siblings) {
20614          return elm;
20615        }
20616        if (parentCandidate) {
20617          parent = createElement(parentCandidate);
20618          parent.appendChild(elm);
20619        }
20620        if (siblings) {
20621          if (!parent) {
20622            parent = dom.create('div');
20623            parent.appendChild(elm);
20624          }
20625          Tools.each(siblings, function (sibling) {
20626            var siblingElm = createElement(sibling);
20627            parent.insertBefore(siblingElm, elm);
20628          });
20629        }
20630        return wrapInHtml(parent, ancestry, parentCandidate && parentCandidate.siblings);
20631      };
20632      if (ancestry && ancestry.length) {
20633        item = ancestry[0];
20634        elm = createElement(item);
20635        fragment = dom.create('div');
20636        fragment.appendChild(wrapInHtml(elm, ancestry.slice(1), item.siblings));
20637        return fragment;
20638      } else {
20639        return '';
20640      }
20641    };
20642    var parseSelectorItem = function (item) {
20643      var tagName;
20644      var obj = {
20645        classes: [],
20646        attrs: {}
20647      };
20648      item = obj.selector = Tools.trim(item);
20649      if (item !== '*') {
20650        tagName = item.replace(/(?:([#\.]|::?)([\w\-]+)|(\[)([^\]]+)\]?)/g, function ($0, $1, $2, $3, $4) {
20651          switch ($1) {
20652          case '#':
20653            obj.attrs.id = $2;
20654            break;
20655          case '.':
20656            obj.classes.push($2);
20657            break;
20658          case ':':
20659            if (Tools.inArray('checked disabled enabled read-only required'.split(' '), $2) !== -1) {
20660              obj.attrs[$2] = $2;
20661            }
20662            break;
20663          }
20664          if ($3 === '[') {
20665            var m = $4.match(/([\w\-]+)(?:\=\"([^\"]+))?/);
20666            if (m) {
20667              obj.attrs[m[1]] = m[2];
20668            }
20669          }
20670          return '';
20671        });
20672      }
20673      obj.name = tagName || 'div';
20674      return obj;
20675    };
20676    var parseSelector = function (selector) {
20677      if (!selector || typeof selector !== 'string') {
20678        return [];
20679      }
20680      selector = selector.split(/\s*,\s*/)[0];
20681      selector = selector.replace(/\s*(~\+|~|\+|>)\s*/g, '$1');
20682      return Tools.map(selector.split(/(?:>|\s+(?![^\[\]]+\]))/), function (item) {
20683        var siblings = Tools.map(item.split(/(?:~\+|~|\+)/), parseSelectorItem);
20684        var obj = siblings.pop();
20685        if (siblings.length) {
20686          obj.siblings = siblings;
20687        }
20688        return obj;
20689      }).reverse();
20690    };
20691    var getCssText = function (editor, format) {
20692      var name, previewFrag;
20693      var previewCss = '', parentFontSize;
20694      var previewStyles = getPreviewStyles(editor);
20695      if (previewStyles === '') {
20696        return '';
20697      }
20698      var removeVars = function (val) {
20699        return val.replace(/%(\w+)/g, '');
20700      };
20701      if (typeof format === 'string') {
20702        format = editor.formatter.get(format);
20703        if (!format) {
20704          return;
20705        }
20706        format = format[0];
20707      }
20708      if ('preview' in format) {
20709        var previewOpt = get(format, 'preview');
20710        if (previewOpt.is(false)) {
20711          return '';
20712        } else {
20713          previewStyles = previewOpt.getOr(previewStyles);
20714        }
20715      }
20716      name = format.block || format.inline || 'span';
20717      var items = parseSelector(format.selector);
20718      if (items.length) {
20719        if (!items[0].name) {
20720          items[0].name = name;
20721        }
20722        name = format.selector;
20723        previewFrag = parsedSelectorToHtml(items, editor);
20724      } else {
20725        previewFrag = parsedSelectorToHtml([name], editor);
20726      }
20727      var previewElm = dom.select(name, previewFrag)[0] || previewFrag.firstChild;
20728      each$e(format.styles, function (value, name) {
20729        var newValue = removeVars(value);
20730        if (newValue) {
20731          dom.setStyle(previewElm, name, newValue);
20732        }
20733      });
20734      each$e(format.attributes, function (value, name) {
20735        var newValue = removeVars(value);
20736        if (newValue) {
20737          dom.setAttrib(previewElm, name, newValue);
20738        }
20739      });
20740      each$e(format.classes, function (value) {
20741        var newValue = removeVars(value);
20742        if (!dom.hasClass(previewElm, newValue)) {
20743          dom.addClass(previewElm, newValue);
20744        }
20745      });
20746      editor.fire('PreviewFormats');
20747      dom.setStyles(previewFrag, {
20748        position: 'absolute',
20749        left: -65535
20750      });
20751      editor.getBody().appendChild(previewFrag);
20752      parentFontSize = dom.getStyle(editor.getBody(), 'fontSize', true);
20753      parentFontSize = /px$/.test(parentFontSize) ? parseInt(parentFontSize, 10) : 0;
20754      each$e(previewStyles.split(' '), function (name) {
20755        var value = dom.getStyle(previewElm, name, true);
20756        if (name === 'background-color' && /transparent|rgba\s*\([^)]+,\s*0\)/.test(value)) {
20757          value = dom.getStyle(editor.getBody(), name, true);
20758          if (dom.toHex(value).toLowerCase() === '#ffffff') {
20759            return;
20760          }
20761        }
20762        if (name === 'color') {
20763          if (dom.toHex(value).toLowerCase() === '#000000') {
20764            return;
20765          }
20766        }
20767        if (name === 'font-size') {
20768          if (/em|%$/.test(value)) {
20769            if (parentFontSize === 0) {
20770              return;
20771            }
20772            var numValue = parseFloat(value) / (/%$/.test(value) ? 100 : 1);
20773            value = numValue * parentFontSize + 'px';
20774          }
20775        }
20776        if (name === 'border' && value) {
20777          previewCss += 'padding:0 2px;';
20778        }
20779        previewCss += name + ':' + value + ';';
20780      });
20781      editor.fire('AfterPreviewFormats');
20782      dom.remove(previewFrag);
20783      return previewCss;
20784    };
20785
20786    var setup$6 = function (editor) {
20787      editor.addShortcut('meta+b', '', 'Bold');
20788      editor.addShortcut('meta+i', '', 'Italic');
20789      editor.addShortcut('meta+u', '', 'Underline');
20790      for (var i = 1; i <= 6; i++) {
20791        editor.addShortcut('access+' + i, '', [
20792          'FormatBlock',
20793          false,
20794          'h' + i
20795        ]);
20796      }
20797      editor.addShortcut('access+7', '', [
20798        'FormatBlock',
20799        false,
20800        'p'
20801      ]);
20802      editor.addShortcut('access+8', '', [
20803        'FormatBlock',
20804        false,
20805        'div'
20806      ]);
20807      editor.addShortcut('access+9', '', [
20808        'FormatBlock',
20809        false,
20810        'address'
20811      ]);
20812    };
20813
20814    var Formatter = function (editor) {
20815      var formats = FormatRegistry(editor);
20816      var formatChangeState = Cell(null);
20817      setup$6(editor);
20818      setup$3(editor);
20819      return {
20820        get: formats.get,
20821        has: formats.has,
20822        register: formats.register,
20823        unregister: formats.unregister,
20824        apply: function (name, vars, node) {
20825          applyFormat$1(editor, name, vars, node);
20826        },
20827        remove: function (name, vars, node, similar) {
20828          removeFormat$1(editor, name, vars, node, similar);
20829        },
20830        toggle: function (name, vars, node) {
20831          toggleFormat(editor, name, vars, node);
20832        },
20833        match: curry(match, editor),
20834        matchAll: curry(matchAll, editor),
20835        matchNode: curry(matchNode, editor),
20836        canApply: curry(canApply, editor),
20837        formatChanged: curry(formatChanged, editor, formatChangeState),
20838        getCssText: curry(getCssText, editor)
20839      };
20840    };
20841
20842    var registerEvents$1 = function (editor, undoManager, locks) {
20843      var isFirstTypedCharacter = Cell(false);
20844      var addNonTypingUndoLevel = function (e) {
20845        setTyping(undoManager, false, locks);
20846        undoManager.add({}, e);
20847      };
20848      editor.on('init', function () {
20849        undoManager.add();
20850      });
20851      editor.on('BeforeExecCommand', function (e) {
20852        var cmd = e.command.toLowerCase();
20853        if (cmd !== 'undo' && cmd !== 'redo' && cmd !== 'mcerepaint') {
20854          endTyping(undoManager, locks);
20855          undoManager.beforeChange();
20856        }
20857      });
20858      editor.on('ExecCommand', function (e) {
20859        var cmd = e.command.toLowerCase();
20860        if (cmd !== 'undo' && cmd !== 'redo' && cmd !== 'mcerepaint') {
20861          addNonTypingUndoLevel(e);
20862        }
20863      });
20864      editor.on('ObjectResizeStart cut', function () {
20865        undoManager.beforeChange();
20866      });
20867      editor.on('SaveContent ObjectResized blur', addNonTypingUndoLevel);
20868      editor.on('dragend', addNonTypingUndoLevel);
20869      editor.on('keyup', function (e) {
20870        var keyCode = e.keyCode;
20871        if (e.isDefaultPrevented()) {
20872          return;
20873        }
20874        if (keyCode >= 33 && keyCode <= 36 || keyCode >= 37 && keyCode <= 40 || keyCode === 45 || e.ctrlKey) {
20875          addNonTypingUndoLevel();
20876          editor.nodeChanged();
20877        }
20878        if (keyCode === 46 || keyCode === 8) {
20879          editor.nodeChanged();
20880        }
20881        if (isFirstTypedCharacter.get() && undoManager.typing && isEq$4(createFromEditor(editor), undoManager.data[0]) === false) {
20882          if (editor.isDirty() === false) {
20883            editor.setDirty(true);
20884            editor.fire('change', {
20885              level: undoManager.data[0],
20886              lastLevel: null
20887            });
20888          }
20889          editor.fire('TypingUndo');
20890          isFirstTypedCharacter.set(false);
20891          editor.nodeChanged();
20892        }
20893      });
20894      editor.on('keydown', function (e) {
20895        var keyCode = e.keyCode;
20896        if (e.isDefaultPrevented()) {
20897          return;
20898        }
20899        if (keyCode >= 33 && keyCode <= 36 || keyCode >= 37 && keyCode <= 40 || keyCode === 45) {
20900          if (undoManager.typing) {
20901            addNonTypingUndoLevel(e);
20902          }
20903          return;
20904        }
20905        var modKey = e.ctrlKey && !e.altKey || e.metaKey;
20906        if ((keyCode < 16 || keyCode > 20) && keyCode !== 224 && keyCode !== 91 && !undoManager.typing && !modKey) {
20907          undoManager.beforeChange();
20908          setTyping(undoManager, true, locks);
20909          undoManager.add({}, e);
20910          isFirstTypedCharacter.set(true);
20911        }
20912      });
20913      editor.on('mousedown', function (e) {
20914        if (undoManager.typing) {
20915          addNonTypingUndoLevel(e);
20916        }
20917      });
20918      var isInsertReplacementText = function (event) {
20919        return event.inputType === 'insertReplacementText';
20920      };
20921      var isInsertTextDataNull = function (event) {
20922        return event.inputType === 'insertText' && event.data === null;
20923      };
20924      var isInsertFromPasteOrDrop = function (event) {
20925        return event.inputType === 'insertFromPaste' || event.inputType === 'insertFromDrop';
20926      };
20927      editor.on('input', function (e) {
20928        if (e.inputType && (isInsertReplacementText(e) || isInsertTextDataNull(e) || isInsertFromPasteOrDrop(e))) {
20929          addNonTypingUndoLevel(e);
20930        }
20931      });
20932      editor.on('AddUndo Undo Redo ClearUndos', function (e) {
20933        if (!e.isDefaultPrevented()) {
20934          editor.nodeChanged();
20935        }
20936      });
20937    };
20938    var addKeyboardShortcuts = function (editor) {
20939      editor.addShortcut('meta+z', '', 'Undo');
20940      editor.addShortcut('meta+y,meta+shift+z', '', 'Redo');
20941    };
20942
20943    var UndoManager = function (editor) {
20944      var beforeBookmark = Cell(Optional.none());
20945      var locks = Cell(0);
20946      var index = Cell(0);
20947      var undoManager = {
20948        data: [],
20949        typing: false,
20950        beforeChange: function () {
20951          beforeChange$1(editor, locks, beforeBookmark);
20952        },
20953        add: function (level, event) {
20954          return addUndoLevel$1(editor, undoManager, index, locks, beforeBookmark, level, event);
20955        },
20956        undo: function () {
20957          return undo$1(editor, undoManager, locks, index);
20958        },
20959        redo: function () {
20960          return redo$1(editor, index, undoManager.data);
20961        },
20962        clear: function () {
20963          clear$1(editor, undoManager, index);
20964        },
20965        reset: function () {
20966          reset$1(editor, undoManager);
20967        },
20968        hasUndo: function () {
20969          return hasUndo$1(editor, undoManager, index);
20970        },
20971        hasRedo: function () {
20972          return hasRedo$1(editor, undoManager, index);
20973        },
20974        transact: function (callback) {
20975          return transact$1(editor, undoManager, locks, callback);
20976        },
20977        ignore: function (callback) {
20978          ignore$1(editor, locks, callback);
20979        },
20980        extra: function (callback1, callback2) {
20981          extra$1(editor, undoManager, index, callback1, callback2);
20982        }
20983      };
20984      if (!isRtc(editor)) {
20985        registerEvents$1(editor, undoManager, locks);
20986      }
20987      addKeyboardShortcuts(editor);
20988      return undoManager;
20989    };
20990
20991    var nonTypingKeycodes = [
20992      9,
20993      27,
20994      VK.HOME,
20995      VK.END,
20996      19,
20997      20,
20998      44,
20999      144,
21000      145,
21001      33,
21002      34,
21003      45,
21004      16,
21005      17,
21006      18,
21007      91,
21008      92,
21009      93,
21010      VK.DOWN,
21011      VK.UP,
21012      VK.LEFT,
21013      VK.RIGHT
21014    ].concat(Env.browser.isFirefox() ? [224] : []);
21015    var placeholderAttr = 'data-mce-placeholder';
21016    var isKeyboardEvent = function (e) {
21017      return e.type === 'keydown' || e.type === 'keyup';
21018    };
21019    var isDeleteEvent = function (e) {
21020      var keyCode = e.keyCode;
21021      return keyCode === VK.BACKSPACE || keyCode === VK.DELETE;
21022    };
21023    var isNonTypingKeyboardEvent = function (e) {
21024      if (isKeyboardEvent(e)) {
21025        var keyCode = e.keyCode;
21026        return !isDeleteEvent(e) && (VK.metaKeyPressed(e) || e.altKey || keyCode >= 112 && keyCode <= 123 || contains(nonTypingKeycodes, keyCode));
21027      } else {
21028        return false;
21029      }
21030    };
21031    var isTypingKeyboardEvent = function (e) {
21032      return isKeyboardEvent(e) && !(isDeleteEvent(e) || e.type === 'keyup' && e.keyCode === 229);
21033    };
21034    var isVisuallyEmpty = function (dom, rootElm, forcedRootBlock) {
21035      if (isEmpty(SugarElement.fromDom(rootElm), false)) {
21036        var isForcedRootBlockFalse = forcedRootBlock === '';
21037        var firstElement = rootElm.firstElementChild;
21038        if (!firstElement) {
21039          return true;
21040        } else if (dom.getStyle(rootElm.firstElementChild, 'padding-left') || dom.getStyle(rootElm.firstElementChild, 'padding-right')) {
21041          return false;
21042        } else {
21043          return isForcedRootBlockFalse ? !dom.isBlock(firstElement) : forcedRootBlock === firstElement.nodeName.toLowerCase();
21044        }
21045      } else {
21046        return false;
21047      }
21048    };
21049    var setup$7 = function (editor) {
21050      var dom = editor.dom;
21051      var rootBlock = getForcedRootBlock(editor);
21052      var placeholder = getPlaceholder(editor);
21053      var updatePlaceholder = function (e, initial) {
21054        if (isNonTypingKeyboardEvent(e)) {
21055          return;
21056        }
21057        var body = editor.getBody();
21058        var showPlaceholder = isTypingKeyboardEvent(e) ? false : isVisuallyEmpty(dom, body, rootBlock);
21059        var isPlaceholderShown = dom.getAttrib(body, placeholderAttr) !== '';
21060        if (isPlaceholderShown !== showPlaceholder || initial) {
21061          dom.setAttrib(body, placeholderAttr, showPlaceholder ? placeholder : null);
21062          dom.setAttrib(body, 'aria-placeholder', showPlaceholder ? placeholder : null);
21063          firePlaceholderToggle(editor, showPlaceholder);
21064          editor.on(showPlaceholder ? 'keydown' : 'keyup', updatePlaceholder);
21065          editor.off(showPlaceholder ? 'keyup' : 'keydown', updatePlaceholder);
21066        }
21067      };
21068      if (placeholder) {
21069        editor.on('init', function (e) {
21070          updatePlaceholder(e, true);
21071          editor.on('change SetContent ExecCommand', updatePlaceholder);
21072          editor.on('paste', function (e) {
21073            return Delay.setEditorTimeout(editor, function () {
21074              return updatePlaceholder(e);
21075            });
21076          });
21077        });
21078      }
21079    };
21080
21081    var strongRtl = /[\u0591-\u07FF\uFB1D-\uFDFF\uFE70-\uFEFC]/;
21082    var hasStrongRtl = function (text) {
21083      return strongRtl.test(text);
21084    };
21085
21086    var isInlineTarget = function (editor, elm) {
21087      return is$1(SugarElement.fromDom(elm), getInlineBoundarySelector(editor));
21088    };
21089    var isRtl$1 = function (element) {
21090      return DOMUtils$1.DOM.getStyle(element, 'direction', true) === 'rtl' || hasStrongRtl(element.textContent);
21091    };
21092    var findInlineParents = function (isInlineTarget, rootNode, pos) {
21093      return filter(DOMUtils$1.DOM.getParents(pos.container(), '*', rootNode), isInlineTarget);
21094    };
21095    var findRootInline = function (isInlineTarget, rootNode, pos) {
21096      var parents = findInlineParents(isInlineTarget, rootNode, pos);
21097      return Optional.from(parents[parents.length - 1]);
21098    };
21099    var hasSameParentBlock = function (rootNode, node1, node2) {
21100      var block1 = getParentBlock(node1, rootNode);
21101      var block2 = getParentBlock(node2, rootNode);
21102      return block1 && block1 === block2;
21103    };
21104    var isAtZwsp = function (pos) {
21105      return isBeforeInline(pos) || isAfterInline(pos);
21106    };
21107    var normalizePosition = function (forward, pos) {
21108      if (!pos) {
21109        return pos;
21110      }
21111      var container = pos.container(), offset = pos.offset();
21112      if (forward) {
21113        if (isCaretContainerInline(container)) {
21114          if (isText$1(container.nextSibling)) {
21115            return CaretPosition$1(container.nextSibling, 0);
21116          } else {
21117            return CaretPosition$1.after(container);
21118          }
21119        } else {
21120          return isBeforeInline(pos) ? CaretPosition$1(container, offset + 1) : pos;
21121        }
21122      } else {
21123        if (isCaretContainerInline(container)) {
21124          if (isText$1(container.previousSibling)) {
21125            return CaretPosition$1(container.previousSibling, container.previousSibling.data.length);
21126          } else {
21127            return CaretPosition$1.before(container);
21128          }
21129        } else {
21130          return isAfterInline(pos) ? CaretPosition$1(container, offset - 1) : pos;
21131        }
21132      }
21133    };
21134    var normalizeForwards = curry(normalizePosition, true);
21135    var normalizeBackwards = curry(normalizePosition, false);
21136
21137    var isBeforeRoot = function (rootNode) {
21138      return function (elm) {
21139        return eq$2(rootNode, SugarElement.fromDom(elm.dom.parentNode));
21140      };
21141    };
21142    var getParentBlock$1 = function (rootNode, elm) {
21143      return contains$2(rootNode, elm) ? closest(elm, function (element) {
21144        return isTextBlock(element) || isListItem(element);
21145      }, isBeforeRoot(rootNode)) : Optional.none();
21146    };
21147    var placeCaretInEmptyBody = function (editor) {
21148      var body = editor.getBody();
21149      var node = body.firstChild && editor.dom.isBlock(body.firstChild) ? body.firstChild : body;
21150      editor.selection.setCursorLocation(node, 0);
21151    };
21152    var paddEmptyBody = function (editor) {
21153      if (editor.dom.isEmpty(editor.getBody())) {
21154        editor.setContent('');
21155        placeCaretInEmptyBody(editor);
21156      }
21157    };
21158    var willDeleteLastPositionInElement = function (forward, fromPos, elm) {
21159      return lift2(firstPositionIn(elm), lastPositionIn(elm), function (firstPos, lastPos) {
21160        var normalizedFirstPos = normalizePosition(true, firstPos);
21161        var normalizedLastPos = normalizePosition(false, lastPos);
21162        var normalizedFromPos = normalizePosition(false, fromPos);
21163        if (forward) {
21164          return nextPosition(elm, normalizedFromPos).exists(function (nextPos) {
21165            return nextPos.isEqual(normalizedLastPos) && fromPos.isEqual(normalizedFirstPos);
21166          });
21167        } else {
21168          return prevPosition(elm, normalizedFromPos).exists(function (prevPos) {
21169            return prevPos.isEqual(normalizedFirstPos) && fromPos.isEqual(normalizedLastPos);
21170          });
21171        }
21172      }).getOr(true);
21173    };
21174
21175    var blockPosition = function (block, position) {
21176      return {
21177        block: block,
21178        position: position
21179      };
21180    };
21181    var blockBoundary = function (from, to) {
21182      return {
21183        from: from,
21184        to: to
21185      };
21186    };
21187    var getBlockPosition = function (rootNode, pos) {
21188      var rootElm = SugarElement.fromDom(rootNode);
21189      var containerElm = SugarElement.fromDom(pos.container());
21190      return getParentBlock$1(rootElm, containerElm).map(function (block) {
21191        return blockPosition(block, pos);
21192      });
21193    };
21194    var isDifferentBlocks = function (blockBoundary) {
21195      return eq$2(blockBoundary.from.block, blockBoundary.to.block) === false;
21196    };
21197    var hasSameParent = function (blockBoundary) {
21198      return parent(blockBoundary.from.block).bind(function (parent1) {
21199        return parent(blockBoundary.to.block).filter(function (parent2) {
21200          return eq$2(parent1, parent2);
21201        });
21202      }).isSome();
21203    };
21204    var isEditable = function (blockBoundary) {
21205      return isContentEditableFalse(blockBoundary.from.block.dom) === false && isContentEditableFalse(blockBoundary.to.block.dom) === false;
21206    };
21207    var skipLastBr = function (rootNode, forward, blockPosition) {
21208      if (isBr(blockPosition.position.getNode()) && isEmpty(blockPosition.block) === false) {
21209        return positionIn(false, blockPosition.block.dom).bind(function (lastPositionInBlock) {
21210          if (lastPositionInBlock.isEqual(blockPosition.position)) {
21211            return fromPosition(forward, rootNode, lastPositionInBlock).bind(function (to) {
21212              return getBlockPosition(rootNode, to);
21213            });
21214          } else {
21215            return Optional.some(blockPosition);
21216          }
21217        }).getOr(blockPosition);
21218      } else {
21219        return blockPosition;
21220      }
21221    };
21222    var readFromRange = function (rootNode, forward, rng) {
21223      var fromBlockPos = getBlockPosition(rootNode, CaretPosition$1.fromRangeStart(rng));
21224      var toBlockPos = fromBlockPos.bind(function (blockPos) {
21225        return fromPosition(forward, rootNode, blockPos.position).bind(function (to) {
21226          return getBlockPosition(rootNode, to).map(function (blockPos) {
21227            return skipLastBr(rootNode, forward, blockPos);
21228          });
21229        });
21230      });
21231      return lift2(fromBlockPos, toBlockPos, blockBoundary).filter(function (blockBoundary) {
21232        return isDifferentBlocks(blockBoundary) && hasSameParent(blockBoundary) && isEditable(blockBoundary);
21233      });
21234    };
21235    var read$3 = function (rootNode, forward, rng) {
21236      return rng.collapsed ? readFromRange(rootNode, forward, rng) : Optional.none();
21237    };
21238
21239    var getChildrenUntilBlockBoundary = function (block) {
21240      var children$1 = children(block);
21241      return findIndex(children$1, isBlock).fold(function () {
21242        return children$1;
21243      }, function (index) {
21244        return children$1.slice(0, index);
21245      });
21246    };
21247    var extractChildren = function (block) {
21248      var children = getChildrenUntilBlockBoundary(block);
21249      each(children, remove);
21250      return children;
21251    };
21252    var removeEmptyRoot = function (rootNode, block) {
21253      var parents = parentsAndSelf(block, rootNode);
21254      return find(parents.reverse(), function (element) {
21255        return isEmpty(element);
21256      }).each(remove);
21257    };
21258    var isEmptyBefore = function (el) {
21259      return filter(prevSiblings(el), function (el) {
21260        return !isEmpty(el);
21261      }).length === 0;
21262    };
21263    var nestedBlockMerge = function (rootNode, fromBlock, toBlock, insertionPoint) {
21264      if (isEmpty(toBlock)) {
21265        fillWithPaddingBr(toBlock);
21266        return firstPositionIn(toBlock.dom);
21267      }
21268      if (isEmptyBefore(insertionPoint) && isEmpty(fromBlock)) {
21269        before(insertionPoint, SugarElement.fromTag('br'));
21270      }
21271      var position = prevPosition(toBlock.dom, CaretPosition$1.before(insertionPoint.dom));
21272      each(extractChildren(fromBlock), function (child) {
21273        before(insertionPoint, child);
21274      });
21275      removeEmptyRoot(rootNode, fromBlock);
21276      return position;
21277    };
21278    var sidelongBlockMerge = function (rootNode, fromBlock, toBlock) {
21279      if (isEmpty(toBlock)) {
21280        remove(toBlock);
21281        if (isEmpty(fromBlock)) {
21282          fillWithPaddingBr(fromBlock);
21283        }
21284        return firstPositionIn(fromBlock.dom);
21285      }
21286      var position = lastPositionIn(toBlock.dom);
21287      each(extractChildren(fromBlock), function (child) {
21288        append(toBlock, child);
21289      });
21290      removeEmptyRoot(rootNode, fromBlock);
21291      return position;
21292    };
21293    var findInsertionPoint = function (toBlock, block) {
21294      var parentsAndSelf$1 = parentsAndSelf(block, toBlock);
21295      return Optional.from(parentsAndSelf$1[parentsAndSelf$1.length - 1]);
21296    };
21297    var getInsertionPoint = function (fromBlock, toBlock) {
21298      return contains$2(toBlock, fromBlock) ? findInsertionPoint(toBlock, fromBlock) : Optional.none();
21299    };
21300    var trimBr = function (first, block) {
21301      positionIn(first, block.dom).map(function (position) {
21302        return position.getNode();
21303      }).map(SugarElement.fromDom).filter(isBr$1).each(remove);
21304    };
21305    var mergeBlockInto = function (rootNode, fromBlock, toBlock) {
21306      trimBr(true, fromBlock);
21307      trimBr(false, toBlock);
21308      return getInsertionPoint(fromBlock, toBlock).fold(curry(sidelongBlockMerge, rootNode, fromBlock, toBlock), curry(nestedBlockMerge, rootNode, fromBlock, toBlock));
21309    };
21310    var mergeBlocks = function (rootNode, forward, block1, block2) {
21311      return forward ? mergeBlockInto(rootNode, block2, block1) : mergeBlockInto(rootNode, block1, block2);
21312    };
21313
21314    var backspaceDelete$1 = function (editor, forward) {
21315      var rootNode = SugarElement.fromDom(editor.getBody());
21316      var position = read$3(rootNode.dom, forward, editor.selection.getRng()).bind(function (blockBoundary) {
21317        return mergeBlocks(rootNode, forward, blockBoundary.from.block, blockBoundary.to.block);
21318      });
21319      position.each(function (pos) {
21320        editor.selection.setRng(pos.toRange());
21321      });
21322      return position.isSome();
21323    };
21324
21325    var deleteRangeMergeBlocks = function (rootNode, selection) {
21326      var rng = selection.getRng();
21327      return lift2(getParentBlock$1(rootNode, SugarElement.fromDom(rng.startContainer)), getParentBlock$1(rootNode, SugarElement.fromDom(rng.endContainer)), function (block1, block2) {
21328        if (eq$2(block1, block2) === false) {
21329          rng.deleteContents();
21330          mergeBlocks(rootNode, true, block1, block2).each(function (pos) {
21331            selection.setRng(pos.toRange());
21332          });
21333          return true;
21334        } else {
21335          return false;
21336        }
21337      }).getOr(false);
21338    };
21339    var isRawNodeInTable = function (root, rawNode) {
21340      var node = SugarElement.fromDom(rawNode);
21341      var isRoot = curry(eq$2, root);
21342      return ancestor(node, isTableCell$1, isRoot).isSome();
21343    };
21344    var isSelectionInTable = function (root, rng) {
21345      return isRawNodeInTable(root, rng.startContainer) || isRawNodeInTable(root, rng.endContainer);
21346    };
21347    var isEverythingSelected = function (root, rng) {
21348      var noPrevious = prevPosition(root.dom, CaretPosition$1.fromRangeStart(rng)).isNone();
21349      var noNext = nextPosition(root.dom, CaretPosition$1.fromRangeEnd(rng)).isNone();
21350      return !isSelectionInTable(root, rng) && noPrevious && noNext;
21351    };
21352    var emptyEditor = function (editor) {
21353      editor.setContent('');
21354      editor.selection.setCursorLocation();
21355      return true;
21356    };
21357    var deleteRange$1 = function (editor) {
21358      var rootNode = SugarElement.fromDom(editor.getBody());
21359      var rng = editor.selection.getRng();
21360      return isEverythingSelected(rootNode, rng) ? emptyEditor(editor) : deleteRangeMergeBlocks(rootNode, editor.selection);
21361    };
21362    var backspaceDelete$2 = function (editor, _forward) {
21363      return editor.selection.isCollapsed() ? false : deleteRange$1(editor);
21364    };
21365
21366    var isContentEditableTrue$2 = isContentEditableTrue;
21367    var isContentEditableFalse$7 = isContentEditableFalse;
21368    var showCaret = function (direction, editor, node, before, scrollIntoView) {
21369      return Optional.from(editor._selectionOverrides.showCaret(direction, node, before, scrollIntoView));
21370    };
21371    var getNodeRange = function (node) {
21372      var rng = node.ownerDocument.createRange();
21373      rng.selectNode(node);
21374      return rng;
21375    };
21376    var selectNode = function (editor, node) {
21377      var e = editor.fire('BeforeObjectSelected', { target: node });
21378      if (e.isDefaultPrevented()) {
21379        return Optional.none();
21380      }
21381      return Optional.some(getNodeRange(node));
21382    };
21383    var renderCaretAtRange = function (editor, range, scrollIntoView) {
21384      var normalizedRange = normalizeRange(1, editor.getBody(), range);
21385      var caretPosition = CaretPosition$1.fromRangeStart(normalizedRange);
21386      var caretPositionNode = caretPosition.getNode();
21387      if (isInlineFakeCaretTarget(caretPositionNode)) {
21388        return showCaret(1, editor, caretPositionNode, !caretPosition.isAtEnd(), false);
21389      }
21390      var caretPositionBeforeNode = caretPosition.getNode(true);
21391      if (isInlineFakeCaretTarget(caretPositionBeforeNode)) {
21392        return showCaret(1, editor, caretPositionBeforeNode, false, false);
21393      }
21394      var ceRoot = editor.dom.getParent(caretPosition.getNode(), function (node) {
21395        return isContentEditableFalse$7(node) || isContentEditableTrue$2(node);
21396      });
21397      if (isInlineFakeCaretTarget(ceRoot)) {
21398        return showCaret(1, editor, ceRoot, false, scrollIntoView);
21399      }
21400      return Optional.none();
21401    };
21402    var renderRangeCaret = function (editor, range, scrollIntoView) {
21403      return range.collapsed ? renderCaretAtRange(editor, range, scrollIntoView).getOr(range) : range;
21404    };
21405
21406    var isBeforeBoundary = function (pos) {
21407      return isBeforeContentEditableFalse(pos) || isBeforeMedia(pos);
21408    };
21409    var isAfterBoundary = function (pos) {
21410      return isAfterContentEditableFalse(pos) || isAfterMedia(pos);
21411    };
21412    var trimEmptyTextNode$1 = function (dom, node) {
21413      if (isText$1(node) && node.data.length === 0) {
21414        dom.remove(node);
21415      }
21416    };
21417    var deleteContentAndShowCaret = function (editor, range, node, direction, forward, peekCaretPosition) {
21418      showCaret(direction, editor, peekCaretPosition.getNode(!forward), forward, true).each(function (caretRange) {
21419        if (range.collapsed) {
21420          var deleteRange = range.cloneRange();
21421          if (forward) {
21422            deleteRange.setEnd(caretRange.startContainer, caretRange.startOffset);
21423          } else {
21424            deleteRange.setStart(caretRange.endContainer, caretRange.endOffset);
21425          }
21426          deleteRange.deleteContents();
21427        } else {
21428          range.deleteContents();
21429        }
21430        editor.selection.setRng(caretRange);
21431      });
21432      trimEmptyTextNode$1(editor.dom, node);
21433      return true;
21434    };
21435    var deleteBoundaryText = function (editor, forward) {
21436      var range = editor.selection.getRng();
21437      if (!isText$1(range.commonAncestorContainer)) {
21438        return false;
21439      }
21440      var direction = forward ? HDirection.Forwards : HDirection.Backwards;
21441      var caretWalker = CaretWalker(editor.getBody());
21442      var getNextPosFn = curry(getVisualCaretPosition, forward ? caretWalker.next : caretWalker.prev);
21443      var isBeforeFn = forward ? isBeforeBoundary : isAfterBoundary;
21444      var caretPosition = getNormalizedRangeEndPoint(direction, editor.getBody(), range);
21445      var nextCaretPosition = normalizePosition(forward, getNextPosFn(caretPosition));
21446      if (!nextCaretPosition || !isMoveInsideSameBlock(caretPosition, nextCaretPosition)) {
21447        return false;
21448      } else if (isBeforeFn(nextCaretPosition)) {
21449        return deleteContentAndShowCaret(editor, range, caretPosition.getNode(), direction, forward, nextCaretPosition);
21450      }
21451      var peekCaretPosition = getNextPosFn(nextCaretPosition);
21452      if (peekCaretPosition && isBeforeFn(peekCaretPosition)) {
21453        if (isMoveInsideSameBlock(nextCaretPosition, peekCaretPosition)) {
21454          return deleteContentAndShowCaret(editor, range, caretPosition.getNode(), direction, forward, peekCaretPosition);
21455        }
21456      }
21457      return false;
21458    };
21459    var backspaceDelete$3 = function (editor, forward) {
21460      return deleteBoundaryText(editor, forward);
21461    };
21462
21463    var isCompoundElement = function (node) {
21464      return isTableCell$1(SugarElement.fromDom(node)) || isListItem(SugarElement.fromDom(node));
21465    };
21466    var DeleteAction = Adt.generate([
21467      { remove: ['element'] },
21468      { moveToElement: ['element'] },
21469      { moveToPosition: ['position'] }
21470    ]);
21471    var isAtContentEditableBlockCaret = function (forward, from) {
21472      var elm = from.getNode(forward === false);
21473      var caretLocation = forward ? 'after' : 'before';
21474      return isElement$1(elm) && elm.getAttribute('data-mce-caret') === caretLocation;
21475    };
21476    var isDeleteFromCefDifferentBlocks = function (root, forward, from, to) {
21477      var inSameBlock = function (elm) {
21478        return isInline(SugarElement.fromDom(elm)) && !isInSameBlock(from, to, root);
21479      };
21480      return getRelativeCefElm(!forward, from).fold(function () {
21481        return getRelativeCefElm(forward, to).fold(never, inSameBlock);
21482      }, inSameBlock);
21483    };
21484    var deleteEmptyBlockOrMoveToCef = function (root, forward, from, to) {
21485      var toCefElm = to.getNode(forward === false);
21486      return getParentBlock$1(SugarElement.fromDom(root), SugarElement.fromDom(from.getNode())).map(function (blockElm) {
21487        return isEmpty(blockElm) ? DeleteAction.remove(blockElm.dom) : DeleteAction.moveToElement(toCefElm);
21488      }).orThunk(function () {
21489        return Optional.some(DeleteAction.moveToElement(toCefElm));
21490      });
21491    };
21492    var findCefPosition = function (root, forward, from) {
21493      return fromPosition(forward, root, from).bind(function (to) {
21494        if (isCompoundElement(to.getNode())) {
21495          return Optional.none();
21496        } else if (isDeleteFromCefDifferentBlocks(root, forward, from, to)) {
21497          return Optional.none();
21498        } else if (forward && isContentEditableFalse(to.getNode())) {
21499          return deleteEmptyBlockOrMoveToCef(root, forward, from, to);
21500        } else if (forward === false && isContentEditableFalse(to.getNode(true))) {
21501          return deleteEmptyBlockOrMoveToCef(root, forward, from, to);
21502        } else if (forward && isAfterContentEditableFalse(from)) {
21503          return Optional.some(DeleteAction.moveToPosition(to));
21504        } else if (forward === false && isBeforeContentEditableFalse(from)) {
21505          return Optional.some(DeleteAction.moveToPosition(to));
21506        } else {
21507          return Optional.none();
21508        }
21509      });
21510    };
21511    var getContentEditableBlockAction = function (forward, elm) {
21512      if (forward && isContentEditableFalse(elm.nextSibling)) {
21513        return Optional.some(DeleteAction.moveToElement(elm.nextSibling));
21514      } else if (forward === false && isContentEditableFalse(elm.previousSibling)) {
21515        return Optional.some(DeleteAction.moveToElement(elm.previousSibling));
21516      } else {
21517        return Optional.none();
21518      }
21519    };
21520    var skipMoveToActionFromInlineCefToContent = function (root, from, deleteAction) {
21521      return deleteAction.fold(function (elm) {
21522        return Optional.some(DeleteAction.remove(elm));
21523      }, function (elm) {
21524        return Optional.some(DeleteAction.moveToElement(elm));
21525      }, function (to) {
21526        if (isInSameBlock(from, to, root)) {
21527          return Optional.none();
21528        } else {
21529          return Optional.some(DeleteAction.moveToPosition(to));
21530        }
21531      });
21532    };
21533    var getContentEditableAction = function (root, forward, from) {
21534      if (isAtContentEditableBlockCaret(forward, from)) {
21535        return getContentEditableBlockAction(forward, from.getNode(forward === false)).fold(function () {
21536          return findCefPosition(root, forward, from);
21537        }, Optional.some);
21538      } else {
21539        return findCefPosition(root, forward, from).bind(function (deleteAction) {
21540          return skipMoveToActionFromInlineCefToContent(root, from, deleteAction);
21541        });
21542      }
21543    };
21544    var read$4 = function (root, forward, rng) {
21545      var normalizedRange = normalizeRange(forward ? 1 : -1, root, rng);
21546      var from = CaretPosition$1.fromRangeStart(normalizedRange);
21547      var rootElement = SugarElement.fromDom(root);
21548      if (forward === false && isAfterContentEditableFalse(from)) {
21549        return Optional.some(DeleteAction.remove(from.getNode(true)));
21550      } else if (forward && isBeforeContentEditableFalse(from)) {
21551        return Optional.some(DeleteAction.remove(from.getNode()));
21552      } else if (forward === false && isBeforeContentEditableFalse(from) && isAfterBr(rootElement, from)) {
21553        return findPreviousBr(rootElement, from).map(function (br) {
21554          return DeleteAction.remove(br.getNode());
21555        });
21556      } else if (forward && isAfterContentEditableFalse(from) && isBeforeBr(rootElement, from)) {
21557        return findNextBr(rootElement, from).map(function (br) {
21558          return DeleteAction.remove(br.getNode());
21559        });
21560      } else {
21561        return getContentEditableAction(root, forward, from);
21562      }
21563    };
21564
21565    var deleteElement$1 = function (editor, forward) {
21566      return function (element) {
21567        editor._selectionOverrides.hideFakeCaret();
21568        deleteElement(editor, forward, SugarElement.fromDom(element));
21569        return true;
21570      };
21571    };
21572    var moveToElement = function (editor, forward) {
21573      return function (element) {
21574        var pos = forward ? CaretPosition$1.before(element) : CaretPosition$1.after(element);
21575        editor.selection.setRng(pos.toRange());
21576        return true;
21577      };
21578    };
21579    var moveToPosition = function (editor) {
21580      return function (pos) {
21581        editor.selection.setRng(pos.toRange());
21582        return true;
21583      };
21584    };
21585    var getAncestorCe = function (editor, node) {
21586      return Optional.from(getContentEditableRoot(editor.getBody(), node));
21587    };
21588    var backspaceDeleteCaret = function (editor, forward) {
21589      var selectedNode = editor.selection.getNode();
21590      return getAncestorCe(editor, selectedNode).filter(isContentEditableFalse).fold(function () {
21591        return read$4(editor.getBody(), forward, editor.selection.getRng()).exists(function (deleteAction) {
21592          return deleteAction.fold(deleteElement$1(editor, forward), moveToElement(editor, forward), moveToPosition(editor));
21593        });
21594      }, always);
21595    };
21596    var deleteOffscreenSelection = function (rootElement) {
21597      each(descendants$1(rootElement, '.mce-offscreen-selection'), remove);
21598    };
21599    var backspaceDeleteRange = function (editor, forward) {
21600      var selectedNode = editor.selection.getNode();
21601      if (isContentEditableFalse(selectedNode)) {
21602        var hasCefAncestor = getAncestorCe(editor, selectedNode.parentNode).filter(isContentEditableFalse);
21603        return hasCefAncestor.fold(function () {
21604          deleteOffscreenSelection(SugarElement.fromDom(editor.getBody()));
21605          deleteElement(editor, forward, SugarElement.fromDom(editor.selection.getNode()));
21606          paddEmptyBody(editor);
21607          return true;
21608        }, function () {
21609          return true;
21610        });
21611      }
21612      return false;
21613    };
21614    var paddEmptyElement = function (editor) {
21615      var dom = editor.dom, selection = editor.selection;
21616      var ceRoot = getContentEditableRoot(editor.getBody(), selection.getNode());
21617      if (isContentEditableTrue(ceRoot) && dom.isBlock(ceRoot) && dom.isEmpty(ceRoot)) {
21618        var br = dom.create('br', { 'data-mce-bogus': '1' });
21619        dom.setHTML(ceRoot, '');
21620        ceRoot.appendChild(br);
21621        selection.setRng(CaretPosition$1.before(br).toRange());
21622      }
21623      return true;
21624    };
21625    var backspaceDelete$4 = function (editor, forward) {
21626      if (editor.selection.isCollapsed()) {
21627        return backspaceDeleteCaret(editor, forward);
21628      } else {
21629        return backspaceDeleteRange(editor, forward);
21630      }
21631    };
21632
21633    var deleteCaret$1 = function (editor, forward) {
21634      var fromPos = CaretPosition$1.fromRangeStart(editor.selection.getRng());
21635      return fromPosition(forward, editor.getBody(), fromPos).filter(function (pos) {
21636        return forward ? isBeforeImageBlock(pos) : isAfterImageBlock(pos);
21637      }).bind(function (pos) {
21638        return Optional.from(getChildNodeAtRelativeOffset(forward ? 0 : -1, pos));
21639      }).exists(function (elm) {
21640        editor.selection.select(elm);
21641        return true;
21642      });
21643    };
21644    var backspaceDelete$5 = function (editor, forward) {
21645      return editor.selection.isCollapsed() ? deleteCaret$1(editor, forward) : false;
21646    };
21647
21648    var isText$8 = isText$1;
21649    var startsWithCaretContainer$1 = function (node) {
21650      return isText$8(node) && node.data[0] === ZWSP;
21651    };
21652    var endsWithCaretContainer$1 = function (node) {
21653      return isText$8(node) && node.data[node.data.length - 1] === ZWSP;
21654    };
21655    var createZwsp = function (node) {
21656      return node.ownerDocument.createTextNode(ZWSP);
21657    };
21658    var insertBefore$1 = function (node) {
21659      if (isText$8(node.previousSibling)) {
21660        if (endsWithCaretContainer$1(node.previousSibling)) {
21661          return node.previousSibling;
21662        } else {
21663          node.previousSibling.appendData(ZWSP);
21664          return node.previousSibling;
21665        }
21666      } else if (isText$8(node)) {
21667        if (startsWithCaretContainer$1(node)) {
21668          return node;
21669        } else {
21670          node.insertData(0, ZWSP);
21671          return node;
21672        }
21673      } else {
21674        var newNode = createZwsp(node);
21675        node.parentNode.insertBefore(newNode, node);
21676        return newNode;
21677      }
21678    };
21679    var insertAfter$1 = function (node) {
21680      if (isText$8(node.nextSibling)) {
21681        if (startsWithCaretContainer$1(node.nextSibling)) {
21682          return node.nextSibling;
21683        } else {
21684          node.nextSibling.insertData(0, ZWSP);
21685          return node.nextSibling;
21686        }
21687      } else if (isText$8(node)) {
21688        if (endsWithCaretContainer$1(node)) {
21689          return node;
21690        } else {
21691          node.appendData(ZWSP);
21692          return node;
21693        }
21694      } else {
21695        var newNode = createZwsp(node);
21696        if (node.nextSibling) {
21697          node.parentNode.insertBefore(newNode, node.nextSibling);
21698        } else {
21699          node.parentNode.appendChild(newNode);
21700        }
21701        return newNode;
21702      }
21703    };
21704    var insertInline$1 = function (before, node) {
21705      return before ? insertBefore$1(node) : insertAfter$1(node);
21706    };
21707    var insertInlineBefore = curry(insertInline$1, true);
21708    var insertInlineAfter = curry(insertInline$1, false);
21709
21710    var insertInlinePos = function (pos, before) {
21711      if (isText$1(pos.container())) {
21712        return insertInline$1(before, pos.container());
21713      } else {
21714        return insertInline$1(before, pos.getNode());
21715      }
21716    };
21717    var isPosCaretContainer = function (pos, caret) {
21718      var caretNode = caret.get();
21719      return caretNode && pos.container() === caretNode && isCaretContainerInline(caretNode);
21720    };
21721    var renderCaret = function (caret, location) {
21722      return location.fold(function (element) {
21723        remove$5(caret.get());
21724        var text = insertInlineBefore(element);
21725        caret.set(text);
21726        return Optional.some(CaretPosition$1(text, text.length - 1));
21727      }, function (element) {
21728        return firstPositionIn(element).map(function (pos) {
21729          if (!isPosCaretContainer(pos, caret)) {
21730            remove$5(caret.get());
21731            var text = insertInlinePos(pos, true);
21732            caret.set(text);
21733            return CaretPosition$1(text, 1);
21734          } else {
21735            return CaretPosition$1(caret.get(), 1);
21736          }
21737        });
21738      }, function (element) {
21739        return lastPositionIn(element).map(function (pos) {
21740          if (!isPosCaretContainer(pos, caret)) {
21741            remove$5(caret.get());
21742            var text = insertInlinePos(pos, false);
21743            caret.set(text);
21744            return CaretPosition$1(text, text.length - 1);
21745          } else {
21746            return CaretPosition$1(caret.get(), caret.get().length - 1);
21747          }
21748        });
21749      }, function (element) {
21750        remove$5(caret.get());
21751        var text = insertInlineAfter(element);
21752        caret.set(text);
21753        return Optional.some(CaretPosition$1(text, 1));
21754      });
21755    };
21756
21757    var evaluateUntil = function (fns, args) {
21758      for (var i = 0; i < fns.length; i++) {
21759        var result = fns[i].apply(null, args);
21760        if (result.isSome()) {
21761          return result;
21762        }
21763      }
21764      return Optional.none();
21765    };
21766
21767    var Location = Adt.generate([
21768      { before: ['element'] },
21769      { start: ['element'] },
21770      { end: ['element'] },
21771      { after: ['element'] }
21772    ]);
21773    var rescope = function (rootNode, node) {
21774      var parentBlock = getParentBlock(node, rootNode);
21775      return parentBlock ? parentBlock : rootNode;
21776    };
21777    var before$4 = function (isInlineTarget, rootNode, pos) {
21778      var nPos = normalizeForwards(pos);
21779      var scope = rescope(rootNode, nPos.container());
21780      return findRootInline(isInlineTarget, scope, nPos).fold(function () {
21781        return nextPosition(scope, nPos).bind(curry(findRootInline, isInlineTarget, scope)).map(function (inline) {
21782          return Location.before(inline);
21783        });
21784      }, Optional.none);
21785    };
21786    var isNotInsideFormatCaretContainer = function (rootNode, elm) {
21787      return getParentCaretContainer(rootNode, elm) === null;
21788    };
21789    var findInsideRootInline = function (isInlineTarget, rootNode, pos) {
21790      return findRootInline(isInlineTarget, rootNode, pos).filter(curry(isNotInsideFormatCaretContainer, rootNode));
21791    };
21792    var start = function (isInlineTarget, rootNode, pos) {
21793      var nPos = normalizeBackwards(pos);
21794      return findInsideRootInline(isInlineTarget, rootNode, nPos).bind(function (inline) {
21795        var prevPos = prevPosition(inline, nPos);
21796        return prevPos.isNone() ? Optional.some(Location.start(inline)) : Optional.none();
21797      });
21798    };
21799    var end = function (isInlineTarget, rootNode, pos) {
21800      var nPos = normalizeForwards(pos);
21801      return findInsideRootInline(isInlineTarget, rootNode, nPos).bind(function (inline) {
21802        var nextPos = nextPosition(inline, nPos);
21803        return nextPos.isNone() ? Optional.some(Location.end(inline)) : Optional.none();
21804      });
21805    };
21806    var after$3 = function (isInlineTarget, rootNode, pos) {
21807      var nPos = normalizeBackwards(pos);
21808      var scope = rescope(rootNode, nPos.container());
21809      return findRootInline(isInlineTarget, scope, nPos).fold(function () {
21810        return prevPosition(scope, nPos).bind(curry(findRootInline, isInlineTarget, scope)).map(function (inline) {
21811          return Location.after(inline);
21812        });
21813      }, Optional.none);
21814    };
21815    var isValidLocation = function (location) {
21816      return isRtl$1(getElement(location)) === false;
21817    };
21818    var readLocation = function (isInlineTarget, rootNode, pos) {
21819      var location = evaluateUntil([
21820        before$4,
21821        start,
21822        end,
21823        after$3
21824      ], [
21825        isInlineTarget,
21826        rootNode,
21827        pos
21828      ]);
21829      return location.filter(isValidLocation);
21830    };
21831    var getElement = function (location) {
21832      return location.fold(identity, identity, identity, identity);
21833    };
21834    var getName = function (location) {
21835      return location.fold(constant('before'), constant('start'), constant('end'), constant('after'));
21836    };
21837    var outside = function (location) {
21838      return location.fold(Location.before, Location.before, Location.after, Location.after);
21839    };
21840    var inside = function (location) {
21841      return location.fold(Location.start, Location.start, Location.end, Location.end);
21842    };
21843    var isEq$5 = function (location1, location2) {
21844      return getName(location1) === getName(location2) && getElement(location1) === getElement(location2);
21845    };
21846    var betweenInlines = function (forward, isInlineTarget, rootNode, from, to, location) {
21847      return lift2(findRootInline(isInlineTarget, rootNode, from), findRootInline(isInlineTarget, rootNode, to), function (fromInline, toInline) {
21848        if (fromInline !== toInline && hasSameParentBlock(rootNode, fromInline, toInline)) {
21849          return Location.after(forward ? fromInline : toInline);
21850        } else {
21851          return location;
21852        }
21853      }).getOr(location);
21854    };
21855    var skipNoMovement = function (fromLocation, toLocation) {
21856      return fromLocation.fold(always, function (fromLocation) {
21857        return !isEq$5(fromLocation, toLocation);
21858      });
21859    };
21860    var findLocationTraverse = function (forward, isInlineTarget, rootNode, fromLocation, pos) {
21861      var from = normalizePosition(forward, pos);
21862      var to = fromPosition(forward, rootNode, from).map(curry(normalizePosition, forward));
21863      var location = to.fold(function () {
21864        return fromLocation.map(outside);
21865      }, function (to) {
21866        return readLocation(isInlineTarget, rootNode, to).map(curry(betweenInlines, forward, isInlineTarget, rootNode, from, to)).filter(curry(skipNoMovement, fromLocation));
21867      });
21868      return location.filter(isValidLocation);
21869    };
21870    var findLocationSimple = function (forward, location) {
21871      if (forward) {
21872        return location.fold(compose(Optional.some, Location.start), Optional.none, compose(Optional.some, Location.after), Optional.none);
21873      } else {
21874        return location.fold(Optional.none, compose(Optional.some, Location.before), Optional.none, compose(Optional.some, Location.end));
21875      }
21876    };
21877    var findLocation = function (forward, isInlineTarget, rootNode, pos) {
21878      var from = normalizePosition(forward, pos);
21879      var fromLocation = readLocation(isInlineTarget, rootNode, from);
21880      return readLocation(isInlineTarget, rootNode, from).bind(curry(findLocationSimple, forward)).orThunk(function () {
21881        return findLocationTraverse(forward, isInlineTarget, rootNode, fromLocation, pos);
21882      });
21883    };
21884    var prevLocation = curry(findLocation, false);
21885    var nextLocation = curry(findLocation, true);
21886
21887    var hasSelectionModifyApi = function (editor) {
21888      return isFunction(editor.selection.getSel().modify);
21889    };
21890    var moveRel = function (forward, selection, pos) {
21891      var delta = forward ? 1 : -1;
21892      selection.setRng(CaretPosition$1(pos.container(), pos.offset() + delta).toRange());
21893      selection.getSel().modify('move', forward ? 'forward' : 'backward', 'word');
21894      return true;
21895    };
21896    var moveByWord = function (forward, editor) {
21897      var rng = editor.selection.getRng();
21898      var pos = forward ? CaretPosition$1.fromRangeEnd(rng) : CaretPosition$1.fromRangeStart(rng);
21899      if (!hasSelectionModifyApi(editor)) {
21900        return false;
21901      } else if (forward && isBeforeInline(pos)) {
21902        return moveRel(true, editor.selection, pos);
21903      } else if (!forward && isAfterInline(pos)) {
21904        return moveRel(false, editor.selection, pos);
21905      } else {
21906        return false;
21907      }
21908    };
21909
21910    var setCaretPosition = function (editor, pos) {
21911      var rng = editor.dom.createRng();
21912      rng.setStart(pos.container(), pos.offset());
21913      rng.setEnd(pos.container(), pos.offset());
21914      editor.selection.setRng(rng);
21915    };
21916    var setSelected = function (state, elm) {
21917      if (state) {
21918        elm.setAttribute('data-mce-selected', 'inline-boundary');
21919      } else {
21920        elm.removeAttribute('data-mce-selected');
21921      }
21922    };
21923    var renderCaretLocation = function (editor, caret, location) {
21924      return renderCaret(caret, location).map(function (pos) {
21925        setCaretPosition(editor, pos);
21926        return location;
21927      });
21928    };
21929    var findLocation$1 = function (editor, caret, forward) {
21930      var rootNode = editor.getBody();
21931      var from = CaretPosition$1.fromRangeStart(editor.selection.getRng());
21932      var isInlineTarget$1 = curry(isInlineTarget, editor);
21933      var location = findLocation(forward, isInlineTarget$1, rootNode, from);
21934      return location.bind(function (location) {
21935        return renderCaretLocation(editor, caret, location);
21936      });
21937    };
21938    var toggleInlines = function (isInlineTarget, dom, elms) {
21939      var inlineBoundaries = map(descendants$1(SugarElement.fromDom(dom.getRoot()), '*[data-mce-selected="inline-boundary"]'), function (e) {
21940        return e.dom;
21941      });
21942      var selectedInlines = filter(inlineBoundaries, isInlineTarget);
21943      var targetInlines = filter(elms, isInlineTarget);
21944      each(difference(selectedInlines, targetInlines), curry(setSelected, false));
21945      each(difference(targetInlines, selectedInlines), curry(setSelected, true));
21946    };
21947    var safeRemoveCaretContainer = function (editor, caret) {
21948      if (editor.selection.isCollapsed() && editor.composing !== true && caret.get()) {
21949        var pos = CaretPosition$1.fromRangeStart(editor.selection.getRng());
21950        if (CaretPosition$1.isTextPosition(pos) && isAtZwsp(pos) === false) {
21951          setCaretPosition(editor, removeAndReposition(caret.get(), pos));
21952          caret.set(null);
21953        }
21954      }
21955    };
21956    var renderInsideInlineCaret = function (isInlineTarget, editor, caret, elms) {
21957      if (editor.selection.isCollapsed()) {
21958        var inlines = filter(elms, isInlineTarget);
21959        each(inlines, function (_inline) {
21960          var pos = CaretPosition$1.fromRangeStart(editor.selection.getRng());
21961          readLocation(isInlineTarget, editor.getBody(), pos).bind(function (location) {
21962            return renderCaretLocation(editor, caret, location);
21963          });
21964        });
21965      }
21966    };
21967    var move = function (editor, caret, forward) {
21968      return isInlineBoundariesEnabled(editor) ? findLocation$1(editor, caret, forward).isSome() : false;
21969    };
21970    var moveWord = function (forward, editor, _caret) {
21971      return isInlineBoundariesEnabled(editor) ? moveByWord(forward, editor) : false;
21972    };
21973    var setupSelectedState = function (editor) {
21974      var caret = Cell(null);
21975      var isInlineTarget$1 = curry(isInlineTarget, editor);
21976      editor.on('NodeChange', function (e) {
21977        if (isInlineBoundariesEnabled(editor) && !(Env.browser.isIE() && e.initial)) {
21978          toggleInlines(isInlineTarget$1, editor.dom, e.parents);
21979          safeRemoveCaretContainer(editor, caret);
21980          renderInsideInlineCaret(isInlineTarget$1, editor, caret, e.parents);
21981        }
21982      });
21983      return caret;
21984    };
21985    var moveNextWord = curry(moveWord, true);
21986    var movePrevWord = curry(moveWord, false);
21987
21988    var rangeFromPositions = function (from, to) {
21989      var range = document.createRange();
21990      range.setStart(from.container(), from.offset());
21991      range.setEnd(to.container(), to.offset());
21992      return range;
21993    };
21994    var hasOnlyTwoOrLessPositionsLeft = function (elm) {
21995      return lift2(firstPositionIn(elm), lastPositionIn(elm), function (firstPos, lastPos) {
21996        var normalizedFirstPos = normalizePosition(true, firstPos);
21997        var normalizedLastPos = normalizePosition(false, lastPos);
21998        return nextPosition(elm, normalizedFirstPos).forall(function (pos) {
21999          return pos.isEqual(normalizedLastPos);
22000        });
22001      }).getOr(true);
22002    };
22003    var setCaretLocation = function (editor, caret) {
22004      return function (location) {
22005        return renderCaret(caret, location).exists(function (pos) {
22006          setCaretPosition(editor, pos);
22007          return true;
22008        });
22009      };
22010    };
22011    var deleteFromTo = function (editor, caret, from, to) {
22012      var rootNode = editor.getBody();
22013      var isInlineTarget$1 = curry(isInlineTarget, editor);
22014      editor.undoManager.ignore(function () {
22015        editor.selection.setRng(rangeFromPositions(from, to));
22016        editor.execCommand('Delete');
22017        readLocation(isInlineTarget$1, rootNode, CaretPosition$1.fromRangeStart(editor.selection.getRng())).map(inside).map(setCaretLocation(editor, caret));
22018      });
22019      editor.nodeChanged();
22020    };
22021    var rescope$1 = function (rootNode, node) {
22022      var parentBlock = getParentBlock(node, rootNode);
22023      return parentBlock ? parentBlock : rootNode;
22024    };
22025    var backspaceDeleteCollapsed = function (editor, caret, forward, from) {
22026      var rootNode = rescope$1(editor.getBody(), from.container());
22027      var isInlineTarget$1 = curry(isInlineTarget, editor);
22028      var fromLocation = readLocation(isInlineTarget$1, rootNode, from);
22029      return fromLocation.bind(function (location) {
22030        if (forward) {
22031          return location.fold(constant(Optional.some(inside(location))), Optional.none, constant(Optional.some(outside(location))), Optional.none);
22032        } else {
22033          return location.fold(Optional.none, constant(Optional.some(outside(location))), Optional.none, constant(Optional.some(inside(location))));
22034        }
22035      }).map(setCaretLocation(editor, caret)).getOrThunk(function () {
22036        var toPosition = navigate(forward, rootNode, from);
22037        var toLocation = toPosition.bind(function (pos) {
22038          return readLocation(isInlineTarget$1, rootNode, pos);
22039        });
22040        return lift2(fromLocation, toLocation, function () {
22041          return findRootInline(isInlineTarget$1, rootNode, from).exists(function (elm) {
22042            if (hasOnlyTwoOrLessPositionsLeft(elm)) {
22043              deleteElement(editor, forward, SugarElement.fromDom(elm));
22044              return true;
22045            } else {
22046              return false;
22047            }
22048          });
22049        }).orThunk(function () {
22050          return toLocation.bind(function (_) {
22051            return toPosition.map(function (to) {
22052              if (forward) {
22053                deleteFromTo(editor, caret, from, to);
22054              } else {
22055                deleteFromTo(editor, caret, to, from);
22056              }
22057              return true;
22058            });
22059          });
22060        }).getOr(false);
22061      });
22062    };
22063    var backspaceDelete$6 = function (editor, caret, forward) {
22064      if (editor.selection.isCollapsed() && isInlineBoundariesEnabled(editor)) {
22065        var from = CaretPosition$1.fromRangeStart(editor.selection.getRng());
22066        return backspaceDeleteCollapsed(editor, caret, forward, from);
22067      }
22068      return false;
22069    };
22070
22071    var getParentInlines = function (rootElm, startElm) {
22072      var parents = parentsAndSelf(startElm, rootElm);
22073      return findIndex(parents, isBlock).fold(constant(parents), function (index) {
22074        return parents.slice(0, index);
22075      });
22076    };
22077    var hasOnlyOneChild$1 = function (elm) {
22078      return children(elm).length === 1;
22079    };
22080    var deleteLastPosition = function (forward, editor, target, parentInlines) {
22081      var isFormatElement$1 = curry(isFormatElement, editor);
22082      var formatNodes = map(filter(parentInlines, isFormatElement$1), function (elm) {
22083        return elm.dom;
22084      });
22085      if (formatNodes.length === 0) {
22086        deleteElement(editor, forward, target);
22087      } else {
22088        var pos = replaceWithCaretFormat(target.dom, formatNodes);
22089        editor.selection.setRng(pos.toRange());
22090      }
22091    };
22092    var deleteCaret$2 = function (editor, forward) {
22093      var rootElm = SugarElement.fromDom(editor.getBody());
22094      var startElm = SugarElement.fromDom(editor.selection.getStart());
22095      var parentInlines = filter(getParentInlines(rootElm, startElm), hasOnlyOneChild$1);
22096      return last(parentInlines).exists(function (target) {
22097        var fromPos = CaretPosition$1.fromRangeStart(editor.selection.getRng());
22098        if (willDeleteLastPositionInElement(forward, fromPos, target.dom) && !isEmptyCaretFormatElement(target)) {
22099          deleteLastPosition(forward, editor, target, parentInlines);
22100          return true;
22101        } else {
22102          return false;
22103        }
22104      });
22105    };
22106    var backspaceDelete$7 = function (editor, forward) {
22107      return editor.selection.isCollapsed() ? deleteCaret$2(editor, forward) : false;
22108    };
22109
22110    var deleteElement$2 = function (editor, forward, element) {
22111      editor._selectionOverrides.hideFakeCaret();
22112      deleteElement(editor, forward, SugarElement.fromDom(element));
22113      return true;
22114    };
22115    var deleteCaret$3 = function (editor, forward) {
22116      var isNearMedia = forward ? isBeforeMedia : isAfterMedia;
22117      var direction = forward ? HDirection.Forwards : HDirection.Backwards;
22118      var fromPos = getNormalizedRangeEndPoint(direction, editor.getBody(), editor.selection.getRng());
22119      if (isNearMedia(fromPos)) {
22120        return deleteElement$2(editor, forward, fromPos.getNode(!forward));
22121      } else {
22122        return Optional.from(normalizePosition(forward, fromPos)).filter(function (pos) {
22123          return isNearMedia(pos) && isMoveInsideSameBlock(fromPos, pos);
22124        }).exists(function (pos) {
22125          return deleteElement$2(editor, forward, pos.getNode(!forward));
22126        });
22127      }
22128    };
22129    var deleteRange$2 = function (editor, forward) {
22130      var selectedNode = editor.selection.getNode();
22131      return isMedia(selectedNode) ? deleteElement$2(editor, forward, selectedNode) : false;
22132    };
22133    var backspaceDelete$8 = function (editor, forward) {
22134      return editor.selection.isCollapsed() ? deleteCaret$3(editor, forward) : deleteRange$2(editor, forward);
22135    };
22136
22137    var isEditable$1 = function (target) {
22138      return closest(target, function (elm) {
22139        return isContentEditableTrue(elm.dom) || isContentEditableFalse(elm.dom);
22140      }).exists(function (elm) {
22141        return isContentEditableTrue(elm.dom);
22142      });
22143    };
22144    var parseIndentValue = function (value) {
22145      var number = parseInt(value, 10);
22146      return isNaN(number) ? 0 : number;
22147    };
22148    var getIndentStyleName = function (useMargin, element) {
22149      var indentStyleName = useMargin || isTable$1(element) ? 'margin' : 'padding';
22150      var suffix = get$4(element, 'direction') === 'rtl' ? '-right' : '-left';
22151      return indentStyleName + suffix;
22152    };
22153    var indentElement = function (dom, command, useMargin, value, unit, element) {
22154      var indentStyleName = getIndentStyleName(useMargin, SugarElement.fromDom(element));
22155      if (command === 'outdent') {
22156        var styleValue = Math.max(0, parseIndentValue(element.style[indentStyleName]) - value);
22157        dom.setStyle(element, indentStyleName, styleValue ? styleValue + unit : '');
22158      } else {
22159        var styleValue = parseIndentValue(element.style[indentStyleName]) + value + unit;
22160        dom.setStyle(element, indentStyleName, styleValue);
22161      }
22162    };
22163    var validateBlocks = function (editor, blocks) {
22164      return forall(blocks, function (block) {
22165        var indentStyleName = getIndentStyleName(shouldIndentUseMargin(editor), block);
22166        var intentValue = getRaw(block, indentStyleName).map(parseIndentValue).getOr(0);
22167        var contentEditable = editor.dom.getContentEditable(block.dom);
22168        return contentEditable !== 'false' && intentValue > 0;
22169      });
22170    };
22171    var canOutdent = function (editor) {
22172      var blocks = getBlocksToIndent(editor);
22173      return !editor.mode.isReadOnly() && (blocks.length > 1 || validateBlocks(editor, blocks));
22174    };
22175    var isListComponent = function (el) {
22176      return isList(el) || isListItem(el);
22177    };
22178    var parentIsListComponent = function (el) {
22179      return parent(el).map(isListComponent).getOr(false);
22180    };
22181    var getBlocksToIndent = function (editor) {
22182      return filter(map(editor.selection.getSelectedBlocks(), SugarElement.fromDom), function (el) {
22183        return !isListComponent(el) && !parentIsListComponent(el) && isEditable$1(el);
22184      });
22185    };
22186    var handle = function (editor, command) {
22187      var dom = editor.dom, selection = editor.selection, formatter = editor.formatter;
22188      var indentation = getIndentation(editor);
22189      var indentUnit = /[a-z%]+$/i.exec(indentation)[0];
22190      var indentValue = parseInt(indentation, 10);
22191      var useMargin = shouldIndentUseMargin(editor);
22192      var forcedRootBlock = getForcedRootBlock(editor);
22193      if (!editor.queryCommandState('InsertUnorderedList') && !editor.queryCommandState('InsertOrderedList')) {
22194        if (forcedRootBlock === '' && !dom.getParent(selection.getNode(), dom.isBlock)) {
22195          formatter.apply('div');
22196        }
22197      }
22198      each(getBlocksToIndent(editor), function (block) {
22199        indentElement(dom, command, useMargin, indentValue, indentUnit, block.dom);
22200      });
22201    };
22202
22203    var backspaceDelete$9 = function (editor, _forward) {
22204      if (editor.selection.isCollapsed() && canOutdent(editor)) {
22205        var dom = editor.dom;
22206        var rng = editor.selection.getRng();
22207        var pos = CaretPosition$1.fromRangeStart(rng);
22208        var block = dom.getParent(rng.startContainer, dom.isBlock);
22209        if (block !== null && isAtStartOfBlock(SugarElement.fromDom(block), pos)) {
22210          handle(editor, 'outdent');
22211          return true;
22212        }
22213      }
22214      return false;
22215    };
22216
22217    var nativeCommand = function (editor, command) {
22218      editor.getDoc().execCommand(command, false, null);
22219    };
22220    var deleteCommand = function (editor, caret) {
22221      if (backspaceDelete$9(editor)) {
22222        return;
22223      } else if (backspaceDelete$4(editor, false)) {
22224        return;
22225      } else if (backspaceDelete$3(editor, false)) {
22226        return;
22227      } else if (backspaceDelete$6(editor, caret, false)) {
22228        return;
22229      } else if (backspaceDelete$1(editor, false)) {
22230        return;
22231      } else if (backspaceDelete(editor)) {
22232        return;
22233      } else if (backspaceDelete$5(editor, false)) {
22234        return;
22235      } else if (backspaceDelete$8(editor, false)) {
22236        return;
22237      } else if (backspaceDelete$2(editor)) {
22238        return;
22239      } else if (backspaceDelete$7(editor, false)) {
22240        return;
22241      } else {
22242        nativeCommand(editor, 'Delete');
22243        paddEmptyBody(editor);
22244      }
22245    };
22246    var forwardDeleteCommand = function (editor, caret) {
22247      if (backspaceDelete$4(editor, true)) {
22248        return;
22249      } else if (backspaceDelete$3(editor, true)) {
22250        return;
22251      } else if (backspaceDelete$6(editor, caret, true)) {
22252        return;
22253      } else if (backspaceDelete$1(editor, true)) {
22254        return;
22255      } else if (backspaceDelete(editor)) {
22256        return;
22257      } else if (backspaceDelete$5(editor, true)) {
22258        return;
22259      } else if (backspaceDelete$8(editor, true)) {
22260        return;
22261      } else if (backspaceDelete$2(editor)) {
22262        return;
22263      } else if (backspaceDelete$7(editor, true)) {
22264        return;
22265      } else {
22266        nativeCommand(editor, 'ForwardDelete');
22267      }
22268    };
22269    var setup$8 = function (editor, caret) {
22270      editor.addCommand('delete', function () {
22271        deleteCommand(editor, caret);
22272      });
22273      editor.addCommand('forwardDelete', function () {
22274        forwardDeleteCommand(editor, caret);
22275      });
22276    };
22277
22278    var SIGNIFICANT_MOVE = 5;
22279    var LONGPRESS_DELAY = 400;
22280    var getTouch = function (event) {
22281      if (event.touches === undefined || event.touches.length !== 1) {
22282        return Optional.none();
22283      }
22284      return Optional.some(event.touches[0]);
22285    };
22286    var isFarEnough = function (touch, data) {
22287      var distX = Math.abs(touch.clientX - data.x);
22288      var distY = Math.abs(touch.clientY - data.y);
22289      return distX > SIGNIFICANT_MOVE || distY > SIGNIFICANT_MOVE;
22290    };
22291    var setup$9 = function (editor) {
22292      var startData = Cell(Optional.none());
22293      var longpressFired = Cell(false);
22294      var debounceLongpress = last$2(function (e) {
22295        editor.fire('longpress', __assign(__assign({}, e), { type: 'longpress' }));
22296        longpressFired.set(true);
22297      }, LONGPRESS_DELAY);
22298      editor.on('touchstart', function (e) {
22299        getTouch(e).each(function (touch) {
22300          debounceLongpress.cancel();
22301          var data = {
22302            x: touch.clientX,
22303            y: touch.clientY,
22304            target: e.target
22305          };
22306          debounceLongpress.throttle(e);
22307          longpressFired.set(false);
22308          startData.set(Optional.some(data));
22309        });
22310      }, true);
22311      editor.on('touchmove', function (e) {
22312        debounceLongpress.cancel();
22313        getTouch(e).each(function (touch) {
22314          startData.get().each(function (data) {
22315            if (isFarEnough(touch, data)) {
22316              startData.set(Optional.none());
22317              longpressFired.set(false);
22318              editor.fire('longpresscancel');
22319            }
22320          });
22321        });
22322      }, true);
22323      editor.on('touchend touchcancel', function (e) {
22324        debounceLongpress.cancel();
22325        if (e.type === 'touchcancel') {
22326          return;
22327        }
22328        startData.get().filter(function (data) {
22329          return data.target.isEqualNode(e.target);
22330        }).each(function () {
22331          if (longpressFired.get()) {
22332            e.preventDefault();
22333          } else {
22334            editor.fire('tap', __assign(__assign({}, e), { type: 'tap' }));
22335          }
22336        });
22337      }, true);
22338    };
22339
22340    var isBlockElement = function (blockElements, node) {
22341      return blockElements.hasOwnProperty(node.nodeName);
22342    };
22343    var isValidTarget = function (blockElements, node) {
22344      if (isText$1(node)) {
22345        return true;
22346      } else if (isElement$1(node)) {
22347        return !isBlockElement(blockElements, node) && !isBookmarkNode$1(node);
22348      } else {
22349        return false;
22350      }
22351    };
22352    var hasBlockParent = function (blockElements, root, node) {
22353      return exists(parents$1(SugarElement.fromDom(node), SugarElement.fromDom(root)), function (elm) {
22354        return isBlockElement(blockElements, elm.dom);
22355      });
22356    };
22357    var shouldRemoveTextNode = function (blockElements, node) {
22358      if (isText$1(node)) {
22359        if (node.nodeValue.length === 0) {
22360          return true;
22361        } else if (/^\s+$/.test(node.nodeValue) && (!node.nextSibling || isBlockElement(blockElements, node.nextSibling))) {
22362          return true;
22363        }
22364      }
22365      return false;
22366    };
22367    var addRootBlocks = function (editor) {
22368      var dom = editor.dom, selection = editor.selection;
22369      var schema = editor.schema, blockElements = schema.getBlockElements();
22370      var node = selection.getStart();
22371      var rootNode = editor.getBody();
22372      var rootBlockNode, tempNode, wrapped;
22373      var forcedRootBlock = getForcedRootBlock(editor);
22374      if (!node || !isElement$1(node) || !forcedRootBlock) {
22375        return;
22376      }
22377      var rootNodeName = rootNode.nodeName.toLowerCase();
22378      if (!schema.isValidChild(rootNodeName, forcedRootBlock.toLowerCase()) || hasBlockParent(blockElements, rootNode, node)) {
22379        return;
22380      }
22381      var rng = selection.getRng();
22382      var startContainer = rng.startContainer;
22383      var startOffset = rng.startOffset;
22384      var endContainer = rng.endContainer;
22385      var endOffset = rng.endOffset;
22386      var restoreSelection = hasFocus$1(editor);
22387      node = rootNode.firstChild;
22388      while (node) {
22389        if (isValidTarget(blockElements, node)) {
22390          if (shouldRemoveTextNode(blockElements, node)) {
22391            tempNode = node;
22392            node = node.nextSibling;
22393            dom.remove(tempNode);
22394            continue;
22395          }
22396          if (!rootBlockNode) {
22397            rootBlockNode = dom.create(forcedRootBlock, getForcedRootBlockAttrs(editor));
22398            node.parentNode.insertBefore(rootBlockNode, node);
22399            wrapped = true;
22400          }
22401          tempNode = node;
22402          node = node.nextSibling;
22403          rootBlockNode.appendChild(tempNode);
22404        } else {
22405          rootBlockNode = null;
22406          node = node.nextSibling;
22407        }
22408      }
22409      if (wrapped && restoreSelection) {
22410        rng.setStart(startContainer, startOffset);
22411        rng.setEnd(endContainer, endOffset);
22412        selection.setRng(rng);
22413        editor.nodeChanged();
22414      }
22415    };
22416    var setup$a = function (editor) {
22417      if (getForcedRootBlock(editor)) {
22418        editor.on('NodeChange', curry(addRootBlocks, editor));
22419      }
22420    };
22421
22422    var findBlockCaretContainer = function (editor) {
22423      return descendant(SugarElement.fromDom(editor.getBody()), '*[data-mce-caret]').fold(constant(null), function (elm) {
22424        return elm.dom;
22425      });
22426    };
22427    var removeIeControlRect = function (editor) {
22428      editor.selection.setRng(editor.selection.getRng());
22429    };
22430    var showBlockCaretContainer = function (editor, blockCaretContainer) {
22431      if (blockCaretContainer.hasAttribute('data-mce-caret')) {
22432        showCaretContainerBlock(blockCaretContainer);
22433        removeIeControlRect(editor);
22434        editor.selection.scrollIntoView(blockCaretContainer);
22435      }
22436    };
22437    var handleBlockContainer = function (editor, e) {
22438      var blockCaretContainer = findBlockCaretContainer(editor);
22439      if (!blockCaretContainer) {
22440        return;
22441      }
22442      if (e.type === 'compositionstart') {
22443        e.preventDefault();
22444        e.stopPropagation();
22445        showBlockCaretContainer(editor, blockCaretContainer);
22446        return;
22447      }
22448      if (hasContent(blockCaretContainer)) {
22449        showBlockCaretContainer(editor, blockCaretContainer);
22450        editor.undoManager.add();
22451      }
22452    };
22453    var setup$b = function (editor) {
22454      editor.on('keyup compositionstart', curry(handleBlockContainer, editor));
22455    };
22456
22457    var BreakType;
22458    (function (BreakType) {
22459      BreakType[BreakType['Br'] = 0] = 'Br';
22460      BreakType[BreakType['Block'] = 1] = 'Block';
22461      BreakType[BreakType['Wrap'] = 2] = 'Wrap';
22462      BreakType[BreakType['Eol'] = 3] = 'Eol';
22463    }(BreakType || (BreakType = {})));
22464    var flip = function (direction, positions) {
22465      return direction === HDirection.Backwards ? reverse(positions) : positions;
22466    };
22467    var walk$3 = function (direction, caretWalker, pos) {
22468      return direction === HDirection.Forwards ? caretWalker.next(pos) : caretWalker.prev(pos);
22469    };
22470    var getBreakType = function (scope, direction, currentPos, nextPos) {
22471      if (isBr(nextPos.getNode(direction === HDirection.Forwards))
22471) {
22472        return BreakType.Br;
22473      } else if (isInSameBlock(currentPos, nextPos) === false) {
22474        return BreakType.Block;
22475      } else {
22476        return BreakType.Wrap;
22477      }
22478    };
22479    var getPositionsUntil = function (predicate, direction, scope, start) {
22480      var caretWalker = CaretWalker(scope);
22481      var currentPos = start, nextPos;
22482      var positions = [];
22483      while (currentPos) {
22484        nextPos = walk$3(direction, caretWalker, currentPos);
22485        if (!nextPos) {
22486          break;
22487        }
22488        if (isBr(nextPos.getNode(false))) {
22489          if (direction === HDirection.Forwards) {
22490            return {
22491              positions: flip(direction, positions).concat([nextPos]),
22492              breakType: BreakType.Br,
22493              breakAt: Optional.some(nextPos)
22494            };
22495          } else {
22496            return {
22497              positions: flip(direction, positions),
22498              breakType: BreakType.Br,
22499              breakAt: Optional.some(nextPos)
22500            };
22501          }
22502        }
22503        if (!nextPos.isVisible()) {
22504          currentPos = nextPos;
22505          continue;
22506        }
22507        if (predicate(currentPos, nextPos)) {
22508          var breakType = getBreakType(scope, direction, currentPos, nextPos);
22509          return {
22510            positions: flip(direction, positions),
22511            breakType: breakType,
22512            breakAt: Optional.some(nextPos)
22513          };
22514        }
22515        positions.push(nextPos);
22516        currentPos = nextPos;
22517      }
22518      return {
22519        positions: flip(direction, positions),
22520        breakType: BreakType.Eol,
22521        breakAt: Optional.none()
22522      };
22523    };
22524    var getAdjacentLinePositions = function (direction, getPositionsUntilBreak, scope, start) {
22525      return getPositionsUntilBreak(scope, start).breakAt.map(function (pos) {
22526        var positions = getPositionsUntilBreak(scope, pos).positions;
22527        return direction === HDirection.Backwards ? positions.concat(pos) : [pos].concat(positions);
22528      }).getOr([]);
22529    };
22530    var findClosestHorizontalPositionFromPoint = function (positions, x) {
22531      return foldl(positions, function (acc, newPos) {
22532        return acc.fold(function () {
22533          return Optional.some(newPos);
22534        }, function (lastPos) {
22535          return lift2(head(lastPos.getClientRects()), head(newPos.getClientRects()), function (lastRect, newRect) {
22536            var lastDist = Math.abs(x - lastRect.left);
22537            var newDist = Math.abs(x - newRect.left);
22538            return newDist <= lastDist ? newPos : lastPos;
22539          }).or(acc);
22540        });
22541      }, Optional.none());
22542    };
22543    var findClosestHorizontalPosition = function (positions, pos) {
22544      return head(pos.getClientRects()).bind(function (targetRect) {
22545        return findClosestHorizontalPositionFromPoint(positions, targetRect.left);
22546      });
22547    };
22548    var getPositionsUntilPreviousLine = curry(getPositionsUntil, CaretPosition.isAbove, -1);
22549    var getPositionsUntilNextLine = curry(getPositionsUntil, CaretPosition.isBelow, 1);
22550    var isAtFirstLine = function (scope, pos) {
22551      return getPositionsUntilPreviousLine(scope, pos).breakAt.isNone();
22552    };
22553    var isAtLastLine = function (scope, pos) {
22554      return getPositionsUntilNextLine(scope, pos).breakAt.isNone();
22555    };
22556    var getPositionsAbove = curry(getAdjacentLinePositions, -1, getPositionsUntilPreviousLine);
22557    var getPositionsBelow = curry(getAdjacentLinePositions, 1, getPositionsUntilNextLine);
22558    var getFirstLinePositions = function (scope) {
22559      return firstPositionIn(scope).map(function (pos) {
22560        return [pos].concat(getPositionsUntilNextLine(scope, pos).positions);
22561      }).getOr([]);
22562    };
22563    var getLastLinePositions = function (scope) {
22564      return lastPositionIn(scope).map(function (pos) {
22565        return getPositionsUntilPreviousLine(scope, pos).positions.concat(pos);
22566      }).getOr([]);
22567    };
22568
22569    var getNodeClientRects = function (node) {
22570      var toArrayWithNode = function (clientRects) {
22571        return map(clientRects, function (clientRect) {
22572          clientRect = clone$2(clientRect);
22573          clientRect.node = node;
22574          return clientRect;
22575        });
22576      };
22577      if (isElement$1(node)) {
22578        return toArrayWithNode(node.getClientRects());
22579      }
22580      if (isText$1(node)) {
22581        var rng = node.ownerDocument.createRange();
22582        rng.setStart(node, 0);
22583        rng.setEnd(node, node.data.length);
22584        return toArrayWithNode(rng.getClientRects());
22585      }
22586    };
22587    var getClientRects = function (nodes) {
22588      return bind(nodes, getNodeClientRects);
22589    };
22590
22591    var VDirection;
22592    (function (VDirection) {
22593      VDirection[VDirection['Up'] = -1] = 'Up';
22594      VDirection[VDirection['Down'] = 1] = 'Down';
22595    }(VDirection || (VDirection = {})));
22596    var findUntil$1 = function (direction, root, predicateFn, node) {
22597      while (node = findNode(node, direction, isEditableCaretCandidate, root)) {
22598        if (predicateFn(node)) {
22599          return;
22600        }
22601      }
22602    };
22603    var walkUntil = function (direction, isAboveFn, isBeflowFn, root, predicateFn, caretPosition) {
22604      var line = 0;
22605      var result = [];
22606      var add = function (node) {
22607        var i, clientRect, clientRects;
22608        clientRects = getClientRects([node]);
22609        if (direction === -1) {
22610          clientRects = clientRects.reverse();
22611        }
22612        for (i = 0; i < clientRects.length; i++) {
22613          clientRect = clientRects[i];
22614          if (isBeflowFn(clientRect, targetClientRect)) {
22615            continue;
22616          }
22617          if (result.length > 0 && isAboveFn(clientRect, last$1(result))) {
22618            line++;
22619          }
22620          clientRect.line = line;
22621          if (predicateFn(clientRect)) {
22622            return true;
22623          }
22624          result.push(clientRect);
22625        }
22626      };
22627      var targetClientRect = last$1(caretPosition.getClientRects());
22628      if (!targetClientRect) {
22629        return result;
22630      }
22631      var node = caretPosition.getNode();
22632      add(node);
22633      findUntil$1(direction, root, add, node);
22634      return result;
22635    };
22636    var aboveLineNumber = function (lineNumber, clientRect) {
22637      return clientRect.line > lineNumber;
22638    };
22639    var isLineNumber = function (lineNumber, clientRect) {
22640      return clientRect.line === lineNumber;
22641    };
22642    var upUntil = curry(walkUntil, VDirection.Up, isAbove, isBelow);
22643    var downUntil = curry(walkUntil, VDirection.Down, isBelow, isAbove);
22644    var positionsUntil = function (direction, root, predicateFn, node) {
22645      var caretWalker = CaretWalker(root);
22646      var walkFn, isBelowFn, isAboveFn, caretPosition;
22647      var result = [];
22648      var line = 0, clientRect;
22649      var getClientRect = function (caretPosition) {
22650        if (direction === 1) {
22651          return last$1(caretPosition.getClientRects());
22652        }
22653        return last$1(caretPosition.getClientRects());
22654      };
22655      if (direction === 1) {
22656        walkFn = caretWalker.next;
22657        isBelowFn = isBelow;
22658        isAboveFn = isAbove;
22659        caretPosition = CaretPosition$1.after(node);
22660      } else {
22661        walkFn = caretWalker.prev;
22662        isBelowFn = isAbove;
22663        isAboveFn = isBelow;
22664        caretPosition = CaretPosition$1.before(node);
22665      }
22666      var targetClientRect = getClientRect(caretPosition);
22667      do {
22668        if (!caretPosition.isVisible()) {
22669          continue;
22670        }
22671        clientRect = getClientRect(caretPosition);
22672        if (isAboveFn(clientRect, targetClientRect)) {
22673          continue;
22674        }
22675        if (result.length > 0 && isBelowFn(clientRect, last$1(result))) {
22676          line++;
22677        }
22678        clientRect = clone$2(clientRect);
22679        clientRect.position = caretPosition;
22680        clientRect.line = line;
22681        if (predicateFn(clientRect)) {
22682          return result;
22683        }
22684        result.push(clientRect);
22685      } while (caretPosition = walkFn(caretPosition));
22686      return result;
22687    };
22688    var isAboveLine = function (lineNumber) {
22689      return function (clientRect) {
22690        return aboveLineNumber(lineNumber, clientRect);
22691      };
22692    };
22693    var isLine = function (lineNumber) {
22694      return function (clientRect) {
22695        return isLineNumber(lineNumber, clientRect);
22696      };
22697    };
22698
22699    var isContentEditableFalse$8 = isContentEditableFalse;
22700    var findNode$1 = findNode;
22701    var distanceToRectLeft = function (clientRect, clientX) {
22702      return Math.abs(clientRect.left - clientX);
22703    };
22704    var distanceToRectRight = function (clientRect, clientX) {
22705      return Math.abs(clientRect.right - clientX);
22706    };
22707    var isInsideX = function (clientX, clientRect) {
22708      return clientX >= clientRect.left && clientX <= clientRect.right;
22709    };
22710    var isInsideY = function (clientY, clientRect) {
22711      return clientY >= clientRect.top && clientY <= clientRect.bottom;
22712    };
22713    var findClosestClientRect = function (clientRects, clientX) {
22714      return reduce(clientRects, function (oldClientRect, clientRect) {
22715        var oldDistance = Math.min(distanceToRectLeft(oldClientRect, clientX), distanceToRectRight(oldClientRect, clientX));
22716        var newDistance = Math.min(distanceToRectLeft(clientRect, clientX), distanceToRectRight(clientRect, clientX));
22717        if (isInsideX(clientX, clientRect)) {
22718          return clientRect;
22719        }
22720        if (isInsideX(clientX, oldClientRect)) {
22721          return oldClientRect;
22722        }
22723        if (newDistance === oldDistance && isContentEditableFalse$8(clientRect.node)) {
22724          return clientRect;
22725        }
22726        if (newDistance < oldDistance) {
22727          return clientRect;
22728        }
22729        return oldClientRect;
22730      });
22731    };
22732    var walkUntil$1 = function (direction, root, predicateFn, startNode, includeChildren) {
22733      var node = findNode$1(startNode, direction, isEditableCaretCandidate, root, !includeChildren);
22734      do {
22735        if (!node || predicateFn(node)) {
22736          return;
22737        }
22738      } while (node = findNode$1(node, direction, isEditableCaretCandidate, root));
22739    };
22740    var findLineNodeRects = function (root, targetNodeRect, includeChildren) {
22741      if (includeChildren === void 0) {
22742        includeChildren = true;
22743      }
22744      var clientRects = [];
22745      var collect = function (checkPosFn, node) {
22746        var lineRects = filter(getClientRects([node]), function (clientRect) {
22747          return !checkPosFn(clientRect, targetNodeRect);
22748        });
22749        clientRects = clientRects.concat(lineRects);
22750        return lineRects.length === 0;
22751      };
22752      clientRects.push(targetNodeRect);
22753      walkUntil$1(VDirection.Up, root, curry(collect, isAbove), targetNodeRect.node, includeChildren);
22754      walkUntil$1(VDirection.Down, root, curry(collect, isBelow), targetNodeRect.node, includeChildren);
22755      return clientRects;
22756    };
22757    var getFakeCaretTargets = function (root) {
22758      return filter(from$1(root.getElementsByTagName('*')), isFakeCaretTarget);
22759    };
22760    var caretInfo = function (clientRect, clientX) {
22761      return {
22762        node: clientRect.node,
22763        before: distanceToRectLeft(clientRect, clientX) < distanceToRectRight(clientRect, clientX)
22764      };
22765    };
22766    var closestFakeCaret = function (root, clientX, clientY) {
22767      var fakeTargetNodeRects = getClientRects(getFakeCaretTargets(root));
22768      var targetNodeRects = filter(fakeTargetNodeRects, curry(isInsideY, clientY));
22769      var closestNodeRect = findClosestClientRect(targetNodeRects, clientX);
22770      if (closestNodeRect) {
22771        var includeChildren = !isTable(closestNodeRect.node) && !isMedia(closestNodeRect.node);
22772        closestNodeRect = findClosestClientRect(findLineNodeRects(root, closestNodeRect, includeChildren), clientX);
22773        if (closestNodeRect && isFakeCaretTarget(closestNodeRect.node)) {
22774          return caretInfo(closestNodeRect, clientX);
22775        }
22776      }
22777      return null;
22778    };
22779
22780    var moveToRange = function (editor, rng) {
22781      editor.selection.setRng(rng);
22782      scrollRangeIntoView(editor, editor.selection.getRng());
22783    };
22784    var renderRangeCaretOpt = function (editor, range, scrollIntoView) {
22785      return Optional.some(renderRangeCaret(editor, range, scrollIntoView));
22786    };
22787    var moveHorizontally = function (editor, direction, range, isBefore, isAfter, isElement) {
22788      var forwards = direction === HDirection.Forwards;
22789      var caretWalker = CaretWalker(editor.getBody());
22790      var getNextPosFn = curry(getVisualCaretPosition, forwards ? caretWalker.next : caretWalker.prev);
22791      var isBeforeFn = forwards ? isBefore : isAfter;
22792      if (!range.collapsed) {
22793        var node = getSelectedNode(range);
22794        if (isElement(node)) {
22795          return showCaret(direction, editor, node, direction === HDirection.Backwards, false);
22796        }
22797      }
22798      var caretPosition = getNormalizedRangeEndPoint(direction, editor.getBody(), range);
22799      if (isBeforeFn(caretPosition)) {
22800        return selectNode(editor, caretPosition.getNode(!forwards));
22801      }
22802      var nextCaretPosition = normalizePosition(forwards, getNextPosFn(caretPosition));
22803      var rangeIsInContainerBlock = isRangeInCaretContainerBlock(range);
22804      if (!nextCaretPosition) {
22805        return rangeIsInContainerBlock ? Optional.some(range) : Optional.none();
22806      }
22807      if (isBeforeFn(nextCaretPosition)) {
22808        return showCaret(direction, editor, nextCaretPosition.getNode(!forwards), forwards, false);
22809      }
22810      var peekCaretPosition = getNextPosFn(nextCaretPosition);
22811      if (peekCaretPosition && isBeforeFn(peekCaretPosition)) {
22812        if (isMoveInsideSameBlock(nextCaretPosition, peekCaretPosition)) {
22813          return showCaret(direction, editor, peekCaretPosition.getNode(!forwards), forwards, false);
22814        }
22815      }
22816      if (rangeIsInContainerBlock) {
22817        return renderRangeCaretOpt(editor, nextCaretPosition.toRange(), false);
22818      }
22819      return Optional.none();
22820    };
22821    var moveVertically = function (editor, direction, range, isBefore, isAfter, isElement) {
22822      var caretPosition = getNormalizedRangeEndPoint(direction, editor.getBody(), range);
22823      var caretClientRect = last$1(caretPosition.getClientRects());
22824      var forwards = direction === VDirection.Down;
22825      if (!caretClientRect) {
22826        return Optional.none();
22827      }
22828      var walkerFn = forwards ? downUntil : upUntil;
22829      var linePositions = walkerFn(editor.getBody(), isAboveLine(1), caretPosition);
22830      var nextLinePositions = filter(linePositions, isLine(1));
22831      var clientX = caretClientRect.left;
22832      var nextLineRect = findClosestClientRect(nextLinePositions, clientX);
22833      if (nextLineRect && isElement(nextLineRect.node)) {
22834        var dist1 = Math.abs(clientX - nextLineRect.left);
22835        var dist2 = Math.abs(clientX - nextLineRect.right);
22836        return showCaret(direction, editor, nextLineRect.node, dist1 < dist2, false);
22837      }
22838      var currentNode;
22839      if (isBefore(caretPosition)) {
22840        currentNode = caretPosition.getNode();
22841      } else if (isAfter(caretPosition)) {
22842        currentNode = caretPosition.getNode(true);
22843      } else {
22844        currentNode = getSelectedNode(range);
22845      }
22846      if (currentNode) {
22847        var caretPositions = positionsUntil(direction, editor.getBody(), isAboveLine(1), currentNode);
22848        var closestNextLineRect = findClosestClientRect(filter(caretPositions, isLine(1)), clientX);
22849        if (closestNextLineRect) {
22850          return renderRangeCaretOpt(editor, closestNextLineRect.position.toRange(), false);
22851        }
22852        closestNextLineRect = last$1(filter(caretPositions, isLine(0)));
22853        if (closestNextLineRect) {
22854          return renderRangeCaretOpt(editor, closestNextLineRect.position.toRange(), false);
22855        }
22856      }
22857      if (nextLinePositions.length === 0) {
22858        return getLineEndPoint(editor, forwards).filter(forwards ? isAfter : isBefore).map(function (pos) {
22859          return renderRangeCaret(editor, pos.toRange(), false);
22860        });
22861      }
22862      return Optional.none();
22863    };
22864    var getLineEndPoint = function (editor, forward) {
22865      var rng = editor.selection.getRng();
22866      var body = editor.getBody();
22867      if (forward) {
22868        var from = CaretPosition$1.fromRangeEnd(rng);
22869        var result = getPositionsUntilNextLine(body, from);
22870        return last(result.positions);
22871      } else {
22872        var from = CaretPosition$1.fromRangeStart(rng);
22873        var result = getPositionsUntilPreviousLine(body, from);
22874        return head(result.positions);
22875      }
22876    };
22877    var moveToLineEndPoint = function (editor, forward, isElementPosition) {
22878      return getLineEndPoint(editor, forward).filter(isElementPosition).exists(function (pos) {
22879        editor.selection.setRng(pos.toRange());
22880        return true;
22881      });
22882    };
22883
22884    var isContentEditableFalse$9 = isContentEditableFalse;
22885    var moveToCeFalseHorizontally = function (direction, editor, range) {
22886      return moveHorizontally(editor, direction, range, isBeforeContentEditableFalse, isAfterContentEditableFalse, isContentEditableFalse$9);
22887    };
22888    var moveToCeFalseVertically = function (direction, editor, range) {
22889      var isBefore = function (caretPosition) {
22890        return isBeforeContentEditableFalse(caretPosition) || isBeforeTable(caretPosition);
22891      };
22892      var isAfter = function (caretPosition) {
22893        return isAfterContentEditableFalse(caretPosition) || isAfterTable(caretPosition);
22894      };
22895      return moveVertically(editor, direction, range, isBefore, isAfter, isContentEditableFalse$9);
22896    };
22897    var createTextBlock = function (editor) {
22898      var textBlock = editor.dom.create(getForcedRootBlock(editor));
22899      if (!Env.ie || Env.ie >= 11) {
22900        textBlock.innerHTML = '<br data-mce-bogus="1">';
22901      }
22902      return textBlock;
22903    };
22904    var exitPreBlock = function (editor, direction, range) {
22905      var caretWalker = CaretWalker(editor.getBody());
22906      var getVisualCaretPosition$1 = curry(getVisualCaretPosition, direction === 1 ? caretWalker.next : caretWalker.prev);
22907      if (range.collapsed && hasForcedRootBlock(editor)) {
22908        var pre = editor.dom.getParent(range.startContainer, 'PRE');
22909        if (!pre) {
22910          return;
22911        }
22912        var caretPos = getVisualCaretPosition$1(CaretPosition$1.fromRangeStart(range));
22913        if (!caretPos) {
22914          var newBlock = createTextBlock(editor);
22915          if (direction === 1) {
22916            editor.$(pre).after(newBlock);
22917          } else {
22918            editor.$(pre).before(newBlock);
22919          }
22920          editor.selection.select(newBlock, true);
22921          editor.selection.collapse();
22922        }
22923      }
22924    };
22925    var getHorizontalRange = function (editor, forward) {
22926      var direction = forward ? HDirection.Forwards : HDirection.Backwards;
22927      var range = editor.selection.getRng();
22928      return moveToCeFalseHorizontally(direction, editor, range).orThunk(function () {
22929        exitPreBlock(editor, direction, range);
22930        return Optional.none();
22931      });
22932    };
22933    var getVerticalRange = function (editor, down) {
22934      var direction = down ? 1 : -1;
22935      var range = editor.selection.getRng();
22936      return moveToCeFalseVertically(direction, editor, range).orThunk(function () {
22937        exitPreBlock(editor, direction, range);
22938        return Optional.none();
22939      });
22940    };
22941    var moveH = function (editor, forward) {
22942      return getHorizontalRange(editor, forward).exists(function (newRange) {
22943        moveToRange(editor, newRange);
22944        return true;
22945      });
22946    };
22947    var moveV = function (editor, down) {
22948      return getVerticalRange(editor, down).exists(function (newRange) {
22949        moveToRange(editor, newRange);
22950        return true;
22951      });
22952    };
22953    var moveToLineEndPoint$1 = function (editor, forward) {
22954      var isCefPosition = forward ? isAfterContentEditableFalse : isBeforeContentEditableFalse;
22955      return moveToLineEndPoint(editor, forward, isCefPosition);
22956    };
22957
22958    var isTarget = function (node) {
22959      return contains(['figcaption'], name(node));
22960    };
22961    var rangeBefore = function (target) {
22962      var rng = document.createRange();
22963      rng.setStartBefore(target.dom);
22964      rng.setEndBefore(target.dom);
22965      return rng;
22966    };
22967    var insertElement = function (root, elm, forward) {
22968      if (forward) {
22969        append(root, elm);
22970      } else {
22971        prepend(root, elm);
22972      }
22973    };
22974    var insertBr = function (root, forward) {
22975      var br = SugarElement.fromTag('br');
22976      insertElement(root, br, forward);
22977      return rangeBefore(br);
22978    };
22979    var insertBlock$1 = function (root, forward, blockName, attrs) {
22980      var block = SugarElement.fromTag(blockName);
22981      var br = SugarElement.fromTag('br');
22982      setAll(block, attrs);
22983      append(block, br);
22984      insertElement(root, block, forward);
22985      return rangeBefore(br);
22986    };
22987    var insertEmptyLine = function (root, rootBlockName, attrs, forward) {
22988      if (rootBlockName === '') {
22989        return insertBr(root, forward);
22990      } else {
22991        return insertBlock$1(root, forward, rootBlockName, attrs);
22992      }
22993    };
22994    var getClosestTargetBlock = function (pos, root) {
22995      var isRoot = curry(eq$2, root);
22996      return closest(SugarElement.fromDom(pos.container()), isBlock, isRoot).filter(isTarget);
22997    };
22998    var isAtFirstOrLastLine = function (root, forward, pos) {
22999      return forward ? isAtLastLine(root.dom, pos) : isAtFirstLine(root.dom, pos);
23000    };
23001    var moveCaretToNewEmptyLine = function (editor, forward) {
23002      var root = SugarElement.fromDom(editor.getBody());
23003      var pos = CaretPosition$1.fromRangeStart(editor.selection.getRng());
23004      var rootBlock = getForcedRootBlock(editor);
23005      var rootBlockAttrs = getForcedRootBlockAttrs(editor);
23006      return getClosestTargetBlock(pos, root).exists(function () {
23007        if (isAtFirstOrLastLine(root, forward, pos)) {
23008          var rng = insertEmptyLine(root, rootBlock, rootBlockAttrs, forward);
23009          editor.selection.setRng(rng);
23010          return true;
23011        } else {
23012          return false;
23013        }
23014      });
23015    };
23016    var moveV$1 = function (editor, forward) {
23017      if (editor.selection.isCollapsed()) {
23018        return moveCaretToNewEmptyLine(editor, forward);
23019      } else {
23020        return false;
23021      }
23022    };
23023
23024    var defaultPatterns = function (patterns) {
23025      return map(patterns, function (pattern) {
23026        return __assign({
23027          shiftKey: false,
23028          altKey: false,
23029          ctrlKey: false,
23030          metaKey: false,
23031          keyCode: 0,
23032          action: noop
23033        }, pattern);
23034      });
23035    };
23036    var matchesEvent = function (pattern, evt) {
23037      return evt.keyCode === pattern.keyCode && evt.shiftKey === pattern.shiftKey && evt.altKey === pattern.altKey && evt.ctrlKey === pattern.ctrlKey && evt.metaKey === pattern.metaKey;
23038    };
23039    var match$1 = function (patterns, evt) {
23040      return bind(defaultPatterns(patterns), function (pattern) {
23041        return matchesEvent(pattern, evt) ? [pattern] : [];
23042      });
23043    };
23044    var action = function (f) {
23045      var x = [];
23046      for (var _i = 1; _i < arguments.length; _i++) {
23047        x[_i - 1] = arguments[_i];
23048      }
23049      return function () {
23050        return f.apply(null, x);
23051      };
23052    };
23053    var execute = function (patterns, evt) {
23054      return find(match$1(patterns, evt), function (pattern) {
23055        return pattern.action();
23056      });
23057    };
23058
23059    var moveH$1 = function (editor, forward) {
23060      var direction = forward ? HDirection.Forwards : HDirection.Backwards;
23061      var range = editor.selection.getRng();
23062      return moveHorizontally(editor, direction, range, isBeforeMedia, isAfterMedia, isMedia).exists(function (newRange) {
23063        moveToRange(editor, newRange);
23064        return true;
23065      });
23066    };
23067    var moveV$2 = function (editor, down) {
23068      var direction = down ? 1 : -1;
23069      var range = editor.selection.getRng();
23070      return moveVertically(editor, direction, range, isBeforeMedia, isAfterMedia, isMedia).exists(function (newRange) {
23071        moveToRange(editor, newRange);
23072        return true;
23073      });
23074    };
23075    var moveToLineEndPoint$2 = function (editor, forward) {
23076      var isNearMedia = forward ? isAfterMedia : isBeforeMedia;
23077      return moveToLineEndPoint(editor, forward, isNearMedia);
23078    };
23079
23080    var deflate = function (rect, delta) {
23081      return {
23082        left: rect.left - delta,
23083        top: rect.top - delta,
23084        right: rect.right + delta * 2,
23085        bottom: rect.bottom + delta * 2,
23086        width: rect.width + delta,
23087        height: rect.height + delta
23088      };
23089    };
23090    var getCorners = function (getYAxisValue, tds) {
23091      return bind(tds, function (td) {
23092        var rect = deflate(clone$2(td.getBoundingClientRect()), -1);
23093        return [
23094          {
23095            x: rect.left,
23096            y: getYAxisValue(rect),
23097            cell: td
23098          },
23099          {
23100            x: rect.right,
23101            y: getYAxisValue(rect),
23102            cell: td
23103          }
23104        ];
23105      });
23106    };
23107    var findClosestCorner = function (corners, x, y) {
23108      return foldl(corners, function (acc, newCorner) {
23109        return acc.fold(function () {
23110          return Optional.some(newCorner);
23111        }, function (oldCorner) {
23112          var oldDist = Math.sqrt(Math.abs(oldCorner.x - x) + Math.abs(oldCorner.y - y));
23113          var newDist = Math.sqrt(Math.abs(newCorner.x - x) + Math.abs(newCorner.y - y));
23114          return Optional.some(newDist < oldDist ? newCorner : oldCorner);
23115        });
23116      }, Optional.none());
23117    };
23118    var getClosestCell$1 = function (getYAxisValue, isTargetCorner, table, x, y) {
23119      var cells = descendants$1(SugarElement.fromDom(table), 'td,th,caption').map(function (e) {
23120        return e.dom;
23121      });
23122      var corners = filter(getCorners(getYAxisValue, cells), function (corner) {
23123        return isTargetCorner(corner, y);
23124      });
23125      return findClosestCorner(corners, x, y).map(function (corner) {
23126        return corner.cell;
23127      });
23128    };
23129    var getBottomValue = function (rect) {
23130      return rect.bottom;
23131    };
23132    var getTopValue = function (rect) {
23133      return rect.top;
23134    };
23135    var isAbove$1 = function (corner, y) {
23136      return corner.y < y;
23137    };
23138    var isBelow$1 = function (corner, y) {
23139      return corner.y > y;
23140    };
23141    var getClosestCellAbove = curry(getClosestCell$1, getBottomValue, isAbove$1);
23142    var getClosestCellBelow = curry(getClosestCell$1, getTopValue, isBelow$1);
23143    var findClosestPositionInAboveCell = function (table, pos) {
23144      return head(pos.getClientRects()).bind(function (rect) {
23145        return getClosestCellAbove(table, rect.left, rect.top);
23146      }).bind(function (cell) {
23147        return findClosestHorizontalPosition(getLastLinePositions(cell), pos);
23148      });
23149    };
23150    var findClosestPositionInBelowCell = function (table, pos) {
23151      return last(pos.getClientRects()).bind(function (rect) {
23152        return getClosestCellBelow(table, rect.left, rect.top);
23153      }).bind(function (cell) {
23154        return findClosestHorizontalPosition(getFirstLinePositions(cell), pos);
23155      });
23156    };
23157
23158    var hasNextBreak = function (getPositionsUntil, scope, lineInfo) {
23159      return lineInfo.breakAt.exists(function (breakPos) {
23160        return getPositionsUntil(scope, breakPos).breakAt.isSome();
23161      });
23162    };
23163    var startsWithWrapBreak = function (lineInfo) {
23164      return lineInfo.breakType === BreakType.Wrap && lineInfo.positions.length === 0;
23165    };
23166    var startsWithBrBreak = function (lineInfo) {
23167      return lineInfo.breakType === BreakType.Br && lineInfo.positions.length === 1;
23168    };
23169    var isAtTableCellLine = function (getPositionsUntil, scope, pos) {
23170      var lineInfo = getPositionsUntil(scope, pos);
23171      if (startsWithWrapBreak(lineInfo) || !isBr(pos.getNode()) && startsWithBrBreak(lineInfo)) {
23172        return !hasNextBreak(getPositionsUntil, scope, lineInfo);
23173      } else {
23174        return lineInfo.breakAt.isNone();
23175      }
23176    };
23177    var isAtFirstTableCellLine = curry(isAtTableCellLine, getPositionsUntilPreviousLine);
23178    var isAtLastTableCellLine = curry(isAtTableCellLine, getPositionsUntilNextLine);
23179    var isCaretAtStartOrEndOfTable = function (forward, rng, table) {
23180      var caretPos = CaretPosition$1.fromRangeStart(rng);
23181      return positionIn(!forward, table).exists(function (pos) {
23182        return pos.isEqual(caretPos);
23183      });
23184    };
23185    var navigateHorizontally = function (editor, forward, table, _td) {
23186      var rng = editor.selection.getRng();
23187      var direction = forward ? 1 : -1;
23188      if (isFakeCaretTableBrowser() && isCaretAtStartOrEndOfTable(forward, rng, table)) {
23189        showCaret(direction, editor, table, !forward, false).each(function (newRng) {
23190          moveToRange(editor, newRng);
23191        });
23192        return true;
23193      }
23194      return false;
23195    };
23196    var getClosestAbovePosition = function (root, table, start) {
23197      return findClosestPositionInAboveCell(table, start).orThunk(function () {
23198        return head(start.getClientRects()).bind(function (rect) {
23199          return findClosestHorizontalPositionFromPoint(getPositionsAbove(root, CaretPosition$1.before(table)), rect.left);
23200        });
23201      }).getOr(CaretPosition$1.before(table));
23202    };
23203    var getClosestBelowPosition = function (root, table, start) {
23204      return findClosestPositionInBelowCell(table, start).orThunk(function () {
23205        return head(start.getClientRects()).bind(function (rect) {
23206          return findClosestHorizontalPositionFromPoint(getPositionsBelow(root, CaretPosition$1.after(table)), rect.left);
23207        });
23208      }).getOr(CaretPosition$1.after(table));
23209    };
23210    var getTable = function (previous, pos) {
23211      var node = pos.getNode(previous);
23212      return isElement$1(node) && node.nodeName === 'TABLE' ? Optional.some(node) : Optional.none();
23213    };
23214    var renderBlock = function (down, editor, table, pos) {
23215      var forcedRootBlock = getForcedRootBlock(editor);
23216      if (forcedRootBlock) {
23217        editor.undoManager.transact(function () {
23218          var element = SugarElement.fromTag(forcedRootBlock);
23219          setAll(element, getForcedRootBlockAttrs(editor));
23220          append(element, SugarElement.fromTag('br'));
23221          if (down) {
23222            after(SugarElement.fromDom(table), element);
23223          } else {
23224            before(SugarElement.fromDom(table), element);
23225          }
23226          var rng = editor.dom.createRng();
23227          rng.setStart(element.dom, 0);
23228          rng.setEnd(element.dom, 0);
23229          moveToRange(editor, rng);
23230        });
23231      } else {
23232        moveToRange(editor, pos.toRange());
23233      }
23234    };
23235    var moveCaret = function (editor, down, pos) {
23236      var table = down ? getTable(true, pos) : getTable(false, pos);
23237      var last = down === false;
23238      table.fold(function () {
23239        return moveToRange(editor, pos.toRange());
23240      }, function (table) {
23241        return positionIn(last, editor.getBody()).filter(function (lastPos) {
23242          return lastPos.isEqual(pos);
23243        }).fold(function () {
23244          return moveToRange(editor, pos.toRange());
23245        }, function (_) {
23246          return renderBlock(down, editor, table, pos);
23247        });
23248      });
23249    };
23250    var navigateVertically = function (editor, down, table, td) {
23251      var rng = editor.selection.getRng();
23252      var pos = CaretPosition$1.fromRangeStart(rng);
23253      var root = editor.getBody();
23254      if (!down && isAtFirstTableCellLine(td, pos)) {
23255        var newPos = getClosestAbovePosition(root, table, pos);
23256        moveCaret(editor, down, newPos);
23257        return true;
23258      } else if (down && isAtLastTableCellLine(td, pos)) {
23259        var newPos = getClosestBelowPosition(root, table, pos);
23260        moveCaret(editor, down, newPos);
23261        return true;
23262      } else {
23263        return false;
23264      }
23265    };
23266    var move$1 = function (editor, forward, mover) {
23267      return Optional.from(editor.dom.getParent(editor.selection.getNode(), 'td,th')).bind(function (td) {
23268        return Optional.from(editor.dom.getParent(td, 'table')).map(function (table) {
23269          return mover(editor, forward, table, td);
23270        });
23271      }).getOr(false);
23272    };
23273    var moveH$2 = function (editor, forward) {
23274      return move$1(editor, forward, navigateHorizontally);
23275    };
23276    var moveV$3 = function (editor, forward) {
23277      return move$1(editor, forward, navigateVertically);
23278    };
23279
23280    var executeKeydownOverride = function (editor, caret, evt) {
23281      var os = detect$3().os;
23282      execute([
23283        {
23284          keyCode: VK.RIGHT,
23285          action: action(moveH, editor, true)
23286        },
23287        {
23288          keyCode: VK.LEFT,
23289          action: action(moveH, editor, false)
23290        },
23291        {
23292          keyCode: VK.UP,
23293          action: action(moveV, editor, false)
23294        },
23295        {
23296          keyCode: VK.DOWN,
23297          action: action(moveV, editor, true)
23298        },
23299        {
23300          keyCode: VK.RIGHT,
23301          action: action(moveH$2, editor, true)
23302        },
23303        {
23304          keyCode: VK.LEFT,
23305          action: action(moveH$2, editor, false)
23306        },
23307        {
23308          keyCode: VK.UP,
23309          action: action(moveV$3, editor, false)
23310        },
23311        {
23312          keyCode: VK.DOWN,
23313          action: action(moveV$3, editor, true)
23314        },
23315        {
23316          keyCode: VK.RIGHT,
23317          action: action(moveH$1, editor, true)
23318        },
23319        {
23320          keyCode: VK.LEFT,
23321          action: action(moveH$1, editor, false)
23322        },
23323        {
23324          keyCode: VK.UP,
23325          action: action(moveV$2, editor, false)
23326        },
23327        {
23328          keyCode: VK.DOWN,
23329          action: action(moveV$2, editor, true)
23330        },
23331        {
23332          keyCode: VK.RIGHT,
23333          action: action(move, editor, caret, true)
23334        },
23335        {
23336          keyCode: VK.LEFT,
23337          action: action(move, editor, caret, false)
23338        },
23339        {
23340          keyCode: VK.RIGHT,
23341          ctrlKey: !os.isOSX(),
23342          altKey: os.isOSX(),
23343          action: action(moveNextWord, editor, caret)
23344        },
23345        {
23346          keyCode: VK.LEFT,
23347          ctrlKey: !os.isOSX(),
23348          altKey: os.isOSX(),
23349          action: action(movePrevWord, editor, caret)
23350        },
23351        {
23352          keyCode: VK.UP,
23353          action: action(moveV$1, editor, false)
23354        },
23355        {
23356          keyCode: VK.DOWN,
23357          action: action(moveV$1, editor, true)
23358        }
23359      ], evt).each(function (_) {
23360        evt.preventDefault();
23361      });
23362    };
23363    var setup$c = function (editor, caret) {
23364      editor.on('keydown', function (evt) {
23365        if (evt.isDefaultPrevented() === false) {
23366          executeKeydownOverride(editor, caret, evt);
23367        }
23368      });
23369    };
23370
23371    var executeKeydownOverride$1 = function (editor, caret, evt) {
23372      execute([
23373        {
23374          keyCode: VK.BACKSPACE,
23375          action: action(backspaceDelete$9, editor, false)
23376        },
23377        {
23378          keyCode: VK.BACKSPACE,
23379          action: action(backspaceDelete$4, editor, false)
23380        },
23381        {
23382          keyCode: VK.DELETE,
23383          action: action(backspaceDelete$4, editor, true)
23384        },
23385        {
23386          keyCode: VK.BACKSPACE,
23387          action: action(backspaceDelete$3, editor, false)
23388        },
23389        {
23390          keyCode: VK.DELETE,
23391          action: action(backspaceDelete$3, editor, true)
23392        },
23393        {
23394          keyCode: VK.BACKSPACE,
23395          action: action(backspaceDelete$6, editor, caret, false)
23396        },
23397        {
23398          keyCode: VK.DELETE,
23399          action: action(backspaceDelete$6, editor, caret, true)
23400        },
23401        {
23402          keyCode: VK.BACKSPACE,
23403          action: action(backspaceDelete, editor, false)
23404        },
23405        {
23406          keyCode: VK.DELETE,
23407          action: action(backspaceDelete, editor, true)
23408        },
23409        {
23410          keyCode: VK.BACKSPACE,
23411          action: action(backspaceDelete$5, editor, false)
23412        },
23413        {
23414          keyCode: VK.DELETE,
23415          action: action(backspaceDelete$5, editor, true)
23416        },
23417        {
23418          keyCode: VK.BACKSPACE,
23419          action: action(backspaceDelete$8, editor, false)
23420        },
23421        {
23422          keyCode: VK.DELETE,
23423          action: action(backspaceDelete$8, editor, true)
23424        },
23425        {
23426          keyCode: VK.BACKSPACE,
23427          action: action(backspaceDelete$2, editor, false)
23428        },
23429        {
23430          keyCode: VK.DELETE,
23431          action: action(backspaceDelete$2, editor, true)
23432        },
23433        {
23434          keyCode: VK.BACKSPACE,
23435          action: action(backspaceDelete$1, editor, false)
23436        },
23437        {
23438          keyCode: VK.DELETE,
23439          action: action(backspaceDelete$1, editor, true)
23440        },
23441        {
23442          keyCode: VK.BACKSPACE,
23443          action: action(backspaceDelete$7, editor, false)
23444        },
23445        {
23446          keyCode: VK.DELETE,
23447          action: action(backspaceDelete$7, editor, true)
23448        }
23449      ], evt).each(function (_) {
23450        evt.preventDefault();
23451      });
23452    };
23453    var executeKeyupOverride = function (editor, evt) {
23454      execute([
23455        {
23456          keyCode: VK.BACKSPACE,
23457          action: action(paddEmptyElement, editor)
23458        },
23459        {
23460          keyCode: VK.DELETE,
23461          action: action(paddEmptyElement, editor)
23462        }
23463      ], evt);
23464    };
23465    var setup$d = function (editor, caret) {
23466      editor.on('keydown', function (evt) {
23467        if (evt.isDefaultPrevented() === false) {
23468          executeKeydownOverride$1(editor, caret, evt);
23469        }
23470      });
23471      editor.on('keyup', function (evt) {
23472        if (evt.isDefaultPrevented() === false) {
23473          executeKeyupOverride(editor, evt);
23474        }
23475      });
23476    };
23477
23478    var firstNonWhiteSpaceNodeSibling = function (node) {
23479      while (node) {
23480        if (node.nodeType === 1 || node.nodeType === 3 && node.data && /[\r\n\s]/.test(node.data)) {
23481          return node;
23482        }
23483        node = node.nextSibling;
23484      }
23485    };
23486    var moveToCaretPosition = function (editor, root) {
23487      var node, lastNode = root;
23488      var dom = editor.dom;
23489      var moveCaretBeforeOnEnterElementsMap = editor.schema.getMoveCaretBeforeOnEnterElements();
23490      if (!root) {
23491        return;
23492      }
23493      if (/^(LI|DT|DD)$/.test(root.nodeName)) {
23494        var firstChild = firstNonWhiteSpaceNodeSibling(root.firstChild);
23495        if (firstChild && /^(UL|OL|DL)$/.test(firstChild.nodeName)) {
23496          root.insertBefore(dom.doc.createTextNode(nbsp), root.firstChild);
23497        }
23498      }
23499      var rng = dom.createRng();
23500      root.normalize();
23501      if (root.hasChildNodes()) {
23502        var walker = new DomTreeWalker(root, root);
23503        while (node = walker.current()) {
23504          if (isText$1(node)) {
23505            rng.setStart(node, 0);
23506            rng.setEnd(node, 0);
23507            break;
23508          }
23509          if (moveCaretBeforeOnEnterElementsMap[node.nodeName.toLowerCase()]) {
23510            rng.setStartBefore(node);
23511            rng.setEndBefore(node);
23512            break;
23513          }
23514          lastNode = node;
23515          node = walker.next();
23516        }
23517        if (!node) {
23518          rng.setStart(lastNode, 0);
23519          rng.setEnd(lastNode, 0);
23520        }
23521      } else {
23522        if (isBr(root)) {
23523          if (root.nextSibling && dom.isBlock(root.nextSibling)) {
23524            rng.setStartBefore(root);
23525            rng.setEndBefore(root);
23526          } else {
23527            rng.setStartAfter(root);
23528            rng.setEndAfter(root);
23529          }
23530        } else {
23531          rng.setStart(root, 0);
23532          rng.setEnd(root, 0);
23533        }
23534      }
23535      editor.selection.setRng(rng);
23536      scrollRangeIntoView(editor, rng);
23537    };
23538    var getEditableRoot = function (dom, node) {
23539      var root = dom.getRoot();
23540      var parent, editableRoot;
23541      parent = node;
23542      while (parent !== root && dom.getContentEditable(parent) !== 'false') {
23543        if (dom.getContentEditable(parent) === 'true') {
23544          editableRoot = parent;
23545        }
23546        parent = parent.parentNode;
23547      }
23548      return parent !== root ? editableRoot : root;
23549    };
23550    var getParentBlock$2 = function (editor) {
23551      return Optional.from(editor.dom.getParent(editor.selection.getStart(true), editor.dom.isBlock));
23552    };
23553    var getParentBlockName = function (editor) {
23554      return getParentBlock$2(editor).fold(constant(''), function (parentBlock) {
23555        return parentBlock.nodeName.toUpperCase();
23556      });
23557    };
23558    var isListItemParentBlock = function (editor) {
23559      return getParentBlock$2(editor).filter(function (elm) {
23560        return isListItem(SugarElement.fromDom(elm));
23561      }).isSome();
23562    };
23563
23564    var hasFirstChild = function (elm, name) {
23565      return elm.firstChild && elm.firstChild.nodeName === name;
23566    };
23567    var hasParent$1 = function (elm, parentName) {
23568      return elm && elm.parentNode && elm.parentNode.nodeName === parentName;
23569    };
23570    var isListBlock = function (elm) {
23571      return elm && /^(OL|UL|LI)$/.test(elm.nodeName);
23572    };
23573    var isNestedList = function (elm) {
23574      return isListBlock(elm) && isListBlock(elm.parentNode);
23575    };
23576    var getContainerBlock = function (containerBlock) {
23577      var containerBlockParent = containerBlock.parentNode;
23578      if (/^(LI|DT|DD)$/.test(containerBlockParent.nodeName)) {
23579        return containerBlockParent;
23580      }
23581      return containerBlock;
23582    };
23583    var isFirstOrLastLi = function (containerBlock, parentBlock, first) {
23584      var node = containerBlock[first ? 'firstChild' : 'lastChild'];
23585      while (node) {
23586        if (isElement$1(node)) {
23587          break;
23588        }
23589        node = node[first ? 'nextSibling' : 'previousSibling'];
23590      }
23591      return node === parentBlock;
23592    };
23593    var insert = function (editor, createNewBlock, containerBlock, parentBlock, newBlockName) {
23594      var dom = editor.dom;
23595      var rng = editor.selection.getRng();
23596      if (containerBlock === editor.getBody()) {
23597        return;
23598      }
23599      if (isNestedList(containerBlock)) {
23600        newBlockName = 'LI';
23601      }
23602      var newBlock = newBlockName ? createNewBlock(newBlockName) : dom.create('BR');
23603      if (isFirstOrLastLi(containerBlock, parentBlock, true) && isFirstOrLastLi(containerBlock, parentBlock, false)) {
23604        if (hasParent$1(containerBlock, 'LI')) {
23605          dom.insertAfter(newBlock, getContainerBlock(containerBlock));
23606        } else {
23607          dom.replace(newBlock, containerBlock);
23608        }
23609      } else if (isFirstOrLastLi(containerBlock, parentBlock, true)) {
23610        if (hasParent$1(containerBlock, 'LI')) {
23611          dom.insertAfter(newBlock, getContainerBlock(containerBlock));
23612          newBlock.appendChild(dom.doc.createTextNode(' '));
23613          newBlock.appendChild(containerBlock);
23614        } else {
23615          containerBlock.parentNode.insertBefore(newBlock, containerBlock);
23616        }
23617      } else if (isFirstOrLastLi(containerBlock, parentBlock, false)) {
23618        dom.insertAfter(newBlock, getContainerBlock(containerBlock));
23619      } else {
23620        containerBlock = getContainerBlock(containerBlock);
23621        var tmpRng = rng.cloneRange();
23622        tmpRng.setStartAfter(parentBlock);
23623        tmpRng.setEndAfter(containerBlock);
23624        var fragment = tmpRng.extractContents();
23625        if (newBlockName === 'LI' && hasFirstChild(fragment, 'LI')) {
23626          newBlock = fragment.firstChild;
23627          dom.insertAfter(fragment, containerBlock);
23628        } else {
23629          dom.insertAfter(fragment, containerBlock);
23630          dom.insertAfter(newBlock, containerBlock);
23631        }
23632      }
23633      dom.remove(parentBlock);
23634      moveToCaretPosition(editor, newBlock);
23635    };
23636
23637    var trimZwsp = function (fragment) {
23638      each(descendants(SugarElement.fromDom(fragment), isText), function (text) {
23639        var rawNode = text.dom;
23640        rawNode.nodeValue = trim$2(rawNode.nodeValue);
23641      });
23642    };
23643    var isEmptyAnchor = function (dom, elm) {
23644      return elm && elm.nodeName === 'A' && dom.isEmpty(elm);
23645    };
23646    var isTableCell$5 = function (node) {
23647      return node && /^(TD|TH|CAPTION)$/.test(node.nodeName);
23648    };
23649    var emptyBlock = function (elm) {
23650      elm.innerHTML = '<br data-mce-bogus="1">';
23651    };
23652    var containerAndSiblingName = function (container, nodeName) {
23653      return container.nodeName === nodeName || container.previousSibling && container.previousSibling.nodeName === nodeName;
23654    };
23655    var canSplitBlock = function (dom, node) {
23656      return node && dom.isBlock(node) && !/^(TD|TH|CAPTION|FORM)$/.test(node.nodeName) && !/^(fixed|absolute)/i.test(node.style.position) && dom.getContentEditable(node) !== 'true';
23657    };
23658    var trimInlineElementsOnLeftSideOfBlock = function (dom, nonEmptyElementsMap, block) {
23659      var node = block;
23660      var firstChilds = [];
23661      var i;
23662      if (!node) {
23663        return;
23664      }
23665      while (node = node.firstChild) {
23666        if (dom.isBlock(node)) {
23667          return;
23668        }
23669        if (isElement$1(node) && !nonEmptyElementsMap[node.nodeName.toLowerCase()]) {
23670          firstChilds.push(node);
23671        }
23672      }
23673      i = firstChilds.length;
23674      while (i--) {
23675        node = firstChilds[i];
23676        if (!node.hasChildNodes() || node.firstChild === node.lastChild && node.firstChild.nodeValue === '') {
23677          dom.remove(node);
23678        } else {
23679          if (isEmptyAnchor(dom, node)) {
23680            dom.remove(node);
23681          }
23682        }
23683      }
23684    };
23685    var normalizeZwspOffset = function (start, container, offset) {
23686      if (isText$1(container) === false) {
23687        return offset;
23688      } else if (start) {
23689        return offset === 1 && container.data.charAt(offset - 1) === ZWSP ? 0 : offset;
23690      } else {
23691        return offset === container.data.length - 1 && container.data.charAt(offset) === ZWSP ? container.data.length : offset;
23692      }
23693    };
23694    var includeZwspInRange = function (rng) {
23695      var newRng = rng.cloneRange();
23696      newRng.setStart(rng.startContainer, normalizeZwspOffset(true, rng.startContainer, rng.startOffset));
23697      newRng.setEnd(rng.endContainer, normalizeZwspOffset(false, rng.endContainer, rng.endOffset));
23698      return newRng;
23699    };
23700    var trimLeadingLineBreaks = function (node) {
23701      do {
23702        if (isText$1(node)) {
23703          node.nodeValue = node.nodeValue.replace(/^[\r\n]+/, '');
23704        }
23705        node = node.firstChild;
23706      } while (node);
23707    };
23708    var getEditableRoot$1 = function (dom, node) {
23709      var root = dom.getRoot();
23710      var parent, editableRoot;
23711      parent = node;
23712      while (parent !== root && dom.getContentEditable(parent) !== 'false') {
23713        if (dom.getContentEditable(parent) === 'true') {
23714          editableRoot = parent;
23715        }
23716        parent = parent.parentNode;
23717      }
23718      return parent !== root ? editableRoot : root;
23719    };
23720    var applyAttributes = function (editor, node, forcedRootBlockAttrs) {
23721      var dom = editor.dom;
23722      Optional.from(forcedRootBlockAttrs.style).map(dom.parseStyle).each(function (attrStyles) {
23723        var currentStyles = getAllRaw(SugarElement.fromDom(node));
23724        var newStyles = __assign(__assign({}, currentStyles), attrStyles);
23725        dom.setStyles(node, newStyles);
23726      });
23727      var attrClassesOpt = Optional.from(forcedRootBlockAttrs.class).map(function (attrClasses) {
23728        return attrClasses.split(/\s+/);
23729      });
23730      var currentClassesOpt = Optional.from(node.className).map(function (currentClasses) {
23731        return filter(currentClasses.split(/\s+/), function (clazz) {
23732          return clazz !== '';
23733        });
23734      });
23735      lift2(attrClassesOpt, currentClassesOpt, function (attrClasses, currentClasses) {
23736        var filteredClasses = filter(currentClasses, function (clazz) {
23737          return !contains(attrClasses, clazz);
23738        });
23739        var newClasses = __spreadArrays(attrClasses, filteredClasses);
23740        dom.setAttrib(node, 'class', newClasses.join(' '));
23741      });
23742      var appliedAttrs = [
23743        'style',
23744        'class'
23745      ];
23746      var remainingAttrs = filter$1(forcedRootBlockAttrs, function (_, attrs) {
23747        return !contains(appliedAttrs, attrs);
23748      });
23749      dom.setAttribs(node, remainingAttrs);
23750    };
23751    var setForcedBlockAttrs = function (editor, node) {
23752      var forcedRootBlockName = getForcedRootBlock(editor);
23753      if (forcedRootBlockName && forcedRootBlockName.toLowerCase() === node.tagName.toLowerCase()) {
23754        var forcedRootBlockAttrs = getForcedRootBlockAttrs(editor);
23755        applyAttributes(editor, node, forcedRootBlockAttrs);
23756      }
23757    };
23758    var wrapSelfAndSiblingsInDefaultBlock = function (editor, newBlockName, rng, container, offset) {
23759      var newBlock, parentBlock, startNode, node, next, rootBlockName;
23760      var blockName = newBlockName || 'P';
23761      var dom = editor.dom, editableRoot = getEditableRoot$1(dom, container);
23762      parentBlock = dom.getParent(container, dom.isBlock);
23763      if (!parentBlock || !canSplitBlock(dom, parentBlock)) {
23764        parentBlock = parentBlock || editableRoot;
23765        if (parentBlock === editor.getBody() || isTableCell$5(parentBlock)) {
23766          rootBlockName = parentBlock.nodeName.toLowerCase();
23767        } else {
23768          rootBlockName = parentBlock.parentNode.nodeName.toLowerCase();
23769        }
23770        if (!parentBlock.hasChildNodes()) {
23771          newBlock = dom.create(blockName);
23772          setForcedBlockAttrs(editor, newBlock);
23773          parentBlock.appendChild(newBlock);
23774          rng.setStart(newBlock, 0);
23775          rng.setEnd(newBlock, 0);
23776          return newBlock;
23777        }
23778        node = container;
23779        while (node.parentNode !== parentBlock) {
23780          node = node.parentNode;
23781        }
23782        while (node && !dom.isBlock(node)) {
23783          startNode = node;
23784          node = node.previousSibling;
23785        }
23786        if (startNode && editor.schema.isValidChild(rootBlockName, blockName.toLowerCase())) {
23787          newBlock = dom.create(blockName);
23788          setForcedBlockAttrs(editor, newBlock);
23789          startNode.parentNode.insertBefore(newBlock, startNode);
23790          node = startNode;
23791          while (node && !dom.isBlock(node)) {
23792            next = node.nextSibling;
23793            newBlock.appendChild(node);
23794            node = next;
23795          }
23796          rng.setStart(container, offset);
23797          rng.setEnd(container, offset);
23798        }
23799      }
23800      return container;
23801    };
23802    var addBrToBlockIfNeeded = function (dom, block) {
23803      block.normalize();
23804      var lastChild = block.lastChild;
23805      if (!lastChild || /^(left|right)$/gi.test(dom.getStyle(lastChild, 'float', true))) {
23806        dom.add(block, 'br');
23807      }
23808    };
23809    var insert$1 = function (editor, evt) {
23810      var tmpRng, container, offset, parentBlock;
23811      var newBlock, fragment, containerBlock, parentBlockName, newBlockName, isAfterLastNodeInContainer;
23812      var dom = editor.dom;
23813      var schema = editor.schema, nonEmptyElementsMap = schema.getNonEmptyElements();
23814      var rng = editor.selection.getRng();
23815      var createNewBlock = function (name) {
23816        var node = container, block, clonedNode, caretNode;
23817        var textInlineElements = schema.getTextInlineElements();
23818        if (name || parentBlockName === 'TABLE' || parentBlockName === 'HR') {
23819          block = dom.create(name || newBlockName);
23820        } else {
23821          block = parentBlock.cloneNode(false);
23822        }
23823        caretNode = block;
23824        if (shouldKeepStyles(editor) === false) {
23825          dom.setAttrib(block, 'style', null);
23826          dom.setAttrib(block, 'class', null);
23827        } else {
23828          do {
23829            if (textInlineElements[node.nodeName]) {
23830              if (isCaretNode(node) || isBookmarkNode$1(node)) {
23831                continue;
23832              }
23833              clonedNode = node.cloneNode(false);
23834              dom.setAttrib(clonedNode, 'id', '');
23835              if (block.hasChildNodes()) {
23836                clonedNode.appendChild(block.firstChild);
23837                block.appendChild(clonedNode);
23838              } else {
23839                caretNode = clonedNode;
23840                block.appendChild(clonedNode);
23841              }
23842            }
23843          } while ((node = node.parentNode) && node !== editableRoot);
23844        }
23845        setForcedBlockAttrs(editor, block);
23846        emptyBlock(caretNode);
23847        return block;
23848      };
23849      var isCaretAtStartOrEndOfBlock = function (start) {
23850        var node, name;
23851        var normalizedOffset = normalizeZwspOffset(start, container, offset);
23852        if (isText$1(container) && (start ? normalizedOffset > 0 : normalizedOffset < container.nodeValue.length)) {
23853          return false;
23854        }
23855        if (container.parentNode === parentBlock && isAfterLastNodeInContainer && !start) {
23856          return true;
23857        }
23858        if (start && isElement$1(container) && container === parentBlock.firstChild) {
23859          return true;
23860        }
23861        if (containerAndSiblingName(container, 'TABLE') || containerAndSiblingName(container, 'HR')) {
23862          return isAfterLastNodeInContainer && !start || !isAfterLastNodeInContainer && start;
23863        }
23864        var walker = new DomTreeWalker(container, parentBlock);
23865        if (isText$1(container)) {
23866          if (start && normalizedOffset === 0) {
23867            walker.prev();
23868          } else if (!start && normalizedOffset === container.nodeValue.length) {
23869            walker.next();
23870          }
23871        }
23872        while (node = walker.current()) {
23873          if (isElement$1(node)) {
23874            if (!node.getAttribute('data-mce-bogus')) {
23875              name = node.nodeName.toLowerCase();
23876              if (nonEmptyElementsMap[name] && name !== 'br') {
23877                return false;
23878              }
23879            }
23880          } else if (isText$1(node) && !isWhitespaceText(node.nodeValue)) {
23881            return false;
23882          }
23883          if (start) {
23884            walker.prev();
23885          } else {
23886            walker.next();
23887          }
23888        }
23889        return true;
23890      };
23891      var insertNewBlockAfter = function () {
23892        if (/^(H[1-6]|PRE|FIGURE)$/.test(parentBlockName) && containerBlockName !== 'HGROUP') {
23893          newBlock = createNewBlock(newBlockName);
23894        } else {
23895          newBlock = createNewBlock();
23896        }
23897        if (shouldEndContainerOnEmptyBlock(editor) && canSplitBlock(dom, containerBlock) && dom.isEmpty(parentBlock)) {
23898          newBlock = dom.split(containerBlock, parentBlock);
23899        } else {
23900          dom.insertAfter(newBlock, parentBlock);
23901        }
23902        moveToCaretPosition(editor, newBlock);
23903      };
23904      normalize(dom, rng).each(function (normRng) {
23905        rng.setStart(normRng.startContainer, normRng.startOffset);
23906        rng.setEnd(normRng.endContainer, normRng.endOffset);
23907      });
23908      container = rng.startContainer;
23909      offset = rng.startOffset;
23910      newBlockName = getForcedRootBlock(editor);
23911      var shiftKey = !!(evt && evt.shiftKey);
23912      var ctrlKey = !!(evt && evt.ctrlKey);
23913      if (isElement$1(container) && container.hasChildNodes()) {
23914        isAfterLastNodeInContainer = offset > container.childNodes.length - 1;
23915        container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container;
23916        if (isAfterLastNodeInContainer && isText$1(container)) {
23917          offset = container.nodeValue.length;
23918        } else {
23919          offset = 0;
23920        }
23921      }
23922      var editableRoot = getEditableRoot$1(dom, container);
23923      if (!editableRoot) {
23924        return;
23925      }
23926      if (newBlockName && !shiftKey || !newBlockName && shiftKey) {
23927        container = wrapSelfAndSiblingsInDefaultBlock(editor, newBlockName, rng, container, offset);
23928      }
23929      parentBlock = dom.getParent(container, dom.isBlock);
23930      containerBlock = parentBlock ? dom.getParent(parentBlock.parentNode, dom.isBlock) : null;
23931      parentBlockName = parentBlock ? parentBlock.nodeName.toUpperCase() : '';
23932      var containerBlockName = containerBlock ? containerBlock.nodeName.toUpperCase() : '';
23933      if (containerBlockName === 'LI' && !ctrlKey) {
23934        parentBlock = containerBlock;
23935        containerBlock = containerBlock.parentNode;
23936        parentBlockName = containerBlockName;
23937      }
23938      if (/^(LI|DT|DD)$/.test(parentBlockName)) {
23939        if (dom.isEmpty(parentBlock)) {
23940          insert(editor, createNewBlock, containerBlock, parentBlock, newBlockName);
23941          return;
23942        }
23943      }
23944      if (newBlockName && parentBlock === editor.getBody()) {
23945        return;
23946      }
23947      newBlockName = newBlockName || 'P';
23948      if (isCaretContainerBlock(parentBlock)) {
23949        newBlock = showCaretContainerBlock(parentBlock);
23950        if (dom.isEmpty(parentBlock)) {
23951          emptyBlock(parentBlock);
23952        }
23953        setForcedBlockAttrs(editor, newBlock);
23954        moveToCaretPosition(editor, newBlock);
23955      } else if (isCaretAtStartOrEndOfBlock()) {
23956        insertNewBlockAfter();
23957      } else if (isCaretAtStartOrEndOfBlock(true)) {
23958        newBlock = parentBlock.parentNode.insertBefore(createNewBlock(), parentBlock);
23959        moveToCaretPosition(editor, containerAndSiblingName(parentBlock, 'HR') ? newBlock : parentBlock);
23960      } else {
23961        tmpRng = includeZwspInRange(rng).cloneRange();
23962        tmpRng.setEndAfter(parentBlock);
23963        fragment = tmpRng.extractContents();
23964        trimZwsp(fragment);
23965        trimLeadingLineBreaks(fragment);
23966        newBlock = fragment.firstChild;
23967        dom.insertAfter(fragment, parentBlock);
23968        trimInlineElementsOnLeftSideOfBlock(dom, nonEmptyElementsMap, newBlock);
23969        addBrToBlockIfNeeded(dom, parentBlock);
23970        if (dom.isEmpty(parentBlock)) {
23971          emptyBlock(parentBlock);
23972        }
23973        newBlock.normalize();
23974        if (dom.isEmpty(newBlock)) {
23975          dom.remove(newBlock);
23976          insertNewBlockAfter();
23977        } else {
23978          setForcedBlockAttrs(editor, newBlock);
23979          moveToCaretPosition(editor, newBlock);
23980        }
23981      }
23982      dom.setAttrib(newBlock, 'id', '');
23983      editor.fire('NewBlock', { newBlock: newBlock });
23984    };
23985
23986    var hasRightSideContent = function (schema, container, parentBlock) {
23987      var walker = new DomTreeWalker(container, parentBlock);
23988      var node;
23989      var nonEmptyElementsMap = schema.getNonEmptyElements();
23990      while (node = walker.next()) {
23991        if (nonEmptyElementsMap[node.nodeName.toLowerCase()] || node.length > 0) {
23992          return true;
23993        }
23994      }
23995    };
23996    var scrollToBr = function (dom, selection, brElm) {
23997      var marker = dom.create('span', {}, '&nbsp;');
23998      brElm.parentNode.insertBefore(marker, brElm);
23999      selection.scrollIntoView(marker);
24000      dom.remove(marker);
24001    };
24002    var moveSelectionToBr = function (dom, selection, brElm, extraBr) {
24003      var rng = dom.createRng();
24004      if (!extraBr) {
24005        rng.setStartAfter(brElm);
24006        rng.setEndAfter(brElm);
24007      } else {
24008        rng.setStartBefore(brElm);
24009        rng.setEndBefore(brElm);
24010      }
24011      selection.setRng(rng);
24012    };
24013    var insertBrAtCaret = function (editor, evt) {
24014      var selection = editor.selection;
24015      var dom = editor.dom;
24016      var rng = selection.getRng();
24017      var brElm;
24018      var extraBr;
24019      normalize(dom, rng).each(function (normRng) {
24020        rng.setStart(normRng.startContainer, normRng.startOffset);
24021        rng.setEnd(normRng.endContainer, normRng.endOffset);
24022      });
24023      var offset = rng.startOffset;
24024      var container = rng.startContainer;
24025      if (container.nodeType === 1 && container.hasChildNodes()) {
24026        var isAfterLastNodeInContainer = offset > container.childNodes.length - 1;
24027        container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container;
24028        if (isAfterLastNodeInContainer && container.nodeType === 3) {
24029          offset = container.nodeValue.length;
24030        } else {
24031          offset = 0;
24032        }
24033      }
24034      var parentBlock = dom.getParent(container, dom.isBlock);
24035      var containerBlock = parentBlock ? dom.getParent(parentBlock.parentNode, dom.isBlock) : null;
24036      var containerBlockName = containerBlock ? containerBlock.nodeName.toUpperCase() : '';
24037      var isControlKey = !!(evt && evt.ctrlKey);
24038      if (containerBlockName === 'LI' && !isControlKey) {
24039        parentBlock = containerBlock;
24040      }
24041      if (container && container.nodeType === 3 && offset >= container.nodeValue.length) {
24042        if (!hasRightSideContent(editor.schema, container, parentBlock)) {
24043          brElm = dom.create('br');
24044          rng.insertNode(brElm);
24045          rng.setStartAfter(brElm);
24046          rng.setEndAfter(brElm);
24047          extraBr = true;
24048        }
24049      }
24050      brElm = dom.create('br');
24051      rangeInsertNode(dom, rng, brElm);
24052      scrollToBr(dom, selection, brElm);
24053      moveSelectionToBr(dom, selection, brElm, extraBr);
24054      editor.undoManager.add();
24055    };
24056    var insertBrBefore = function (editor, inline) {
24057      var br = SugarElement.fromTag('br');
24058      before(SugarElement.fromDom(inline), br);
24059      editor.undoManager.add();
24060    };
24061    var insertBrAfter = function (editor, inline) {
24062      if (!hasBrAfter(editor.getBody(), inline)) {
24063        after(SugarElement.fromDom(inline), SugarElement.fromTag('br'));
24064      }
24065      var br = SugarElement.fromTag('br');
24066      after(SugarElement.fromDom(inline), br);
24067      scrollToBr(editor.dom, editor.selection, br.dom);
24068      moveSelectionToBr(editor.dom, editor.selection, br.dom, false);
24069      editor.undoManager.add();
24070    };
24071    var isBeforeBr$1 = function (pos) {
24072      return isBr(pos.getNode());
24073    };
24074    var hasBrAfter = function (rootNode, startNode) {
24075      if (isBeforeBr$1(CaretPosition$1.after(startNode))) {
24076        return true;
24077      } else {
24078        return nextPosition(rootNode, CaretPosition$1.after(startNode)).map(function (pos) {
24079          return isBr(pos.getNode());
24080        }).getOr(false);
24081      }
24082    };
24083    var isAnchorLink = function (elm) {
24084      return elm && elm.nodeName === 'A' && 'href' in elm;
24085    };
24086    var isInsideAnchor = function (location) {
24087      return location.fold(never, isAnchorLink, isAnchorLink, never);
24088    };
24089    var readInlineAnchorLocation = function (editor) {
24090      var isInlineTarget$1 = curry(isInlineTarget, editor);
24091      var position = CaretPosition$1.fromRangeStart(editor.selection.getRng());
24092      return readLocation(isInlineTarget$1, editor.getBody(), position).filter(isInsideAnchor);
24093    };
24094    var insertBrOutsideAnchor = function (editor, location) {
24095      location.fold(noop, curry(insertBrBefore, editor), curry(insertBrAfter, editor), noop);
24096    };
24097    var insert$2 = function (editor, evt) {
24098      var anchorLocation = readInlineAnchorLocation(editor);
24099      if (anchorLocation.isSome()) {
24100        anchorLocation.each(curry(insertBrOutsideAnchor, editor));
24101      } else {
24102        insertBrAtCaret(editor, evt);
24103      }
24104    };
24105
24106    var matchesSelector = function (editor, selector) {
24107      return getParentBlock$2(editor).filter(function (parentBlock) {
24108        return selector.length > 0 && is$1(SugarElement.fromDom(parentBlock), selector);
24109      }).isSome();
24110    };
24111    var shouldInsertBr = function (editor) {
24112      return matchesSelector(editor, getBrNewLineSelector(editor));
24113    };
24114    var shouldBlockNewLine = function (editor) {
24115      return matchesSelector(editor, getNoNewLineSelector(editor));
24116    };
24117
24118    var newLineAction = Adt.generate([
24119      { br: [] },
24120      { block: [] },
24121      { none: [] }
24122    ]);
24123    var shouldBlockNewLine$1 = function (editor, _shiftKey) {
24124      return shouldBlockNewLine(editor);
24125    };
24126    var isBrMode = function (requiredState) {
24127      return function (editor, _shiftKey) {
24128        var brMode = getForcedRootBlock(editor) === '';
24129        return brMode === requiredState;
24130      };
24131    };
24132    var inListBlock = function (requiredState) {
24133      return function (editor, _shiftKey) {
24134        return isListItemParentBlock(editor) === requiredState;
24135      };
24136    };
24137    var inBlock = function (blockName, requiredState) {
24138      return function (editor, _shiftKey) {
24139        var state = getParentBlockName(editor) === blockName.toUpperCase();
24140        return state === requiredState;
24141      };
24142    };
24143    var inPreBlock = function (requiredState) {
24144      return inBlock('pre', requiredState);
24145    };
24146    var inSummaryBlock = function () {
24147      return inBlock('summary', true);
24148    };
24149    var shouldPutBrInPre$1 = function (requiredState) {
24150      return function (editor, _shiftKey) {
24151        return shouldPutBrInPre(editor) === requiredState;
24152      };
24153    };
24154    var inBrContext = function (editor, _shiftKey) {
24155      return shouldInsertBr(editor);
24156    };
24157    var hasShiftKey = function (_editor, shiftKey) {
24158      return shiftKey;
24159    };
24160    var canInsertIntoEditableRoot = function (editor) {
24161      var forcedRootBlock = getForcedRootBlock(editor);
24162      var rootEditable = getEditableRoot(editor.dom, editor.selection.getStart());
24163      return rootEditable && editor.schema.isValidChild(rootEditable.nodeName, forcedRootBlock ? forcedRootBlock : 'P');
24164    };
24165    var match$2 = function (predicates, action) {
24166      return function (editor, shiftKey) {
24167        var isMatch = foldl(predicates, function (res, p) {
24168          return res && p(editor, shiftKey);
24169        }, true);
24170        return isMatch ? Optional.some(action) : Optional.none();
24171      };
24172    };
24173    var getAction$1 = function (editor, evt) {
24174      return evaluateUntil([
24175        match$2([shouldBlockNewLine$1], newLineAction.none()),
24176        match$2([inSummaryBlock()], newLineAction.br()),
24177        match$2([
24178          inPreBlock(true),
24179          shouldPutBrInPre$1(false),
24180          hasShiftKey
24181        ], newLineAction.br()),
24182        match$2([
24183          inPreBlock(true),
24184          shouldPutBrInPre$1(false)
24185        ], newLineAction.block()),
24186        match$2([
24187          inPreBlock(true),
24188          shouldPutBrInPre$1(true),
24189          hasShiftKey
24190        ], newLineAction.block()),
24191        match$2([
24192          inPreBlock(true),
24193          shouldPutBrInPre$1(true)
24194        ], newLineAction.br()),
24195        match$2([
24196          inListBlock(true),
24197          hasShiftKey
24198        ], newLineAction.br()),
24199        match$2([inListBlock(true)], newLineAction.block()),
24200        match$2([
24201          isBrMode(true),
24202          hasShiftKey,
24203          canInsertIntoEditableRoot
24204        ], newLineAction.block()),
24205        match$2([isBrMode(true)], newLineAction.br()),
24206        match$2([inBrContext], newLineAction.br()),
24207        match$2([
24208          isBrMode(false),
24209          hasShiftKey
24210        ], newLineAction.br()),
24211        match$2([canInsertIntoEditableRoot], newLineAction.block())
24212      ], [
24213        editor,
24214        !!(evt && evt.shiftKey)
24215      ]).getOr(newLineAction.none());
24216    };
24217
24218    var insert$3 = function (editor, evt) {
24219      getAction$1(editor, evt).fold(function () {
24220        insert$2(editor, evt);
24221      }, function () {
24222        insert$1(editor, evt);
24223      }, noop);
24224    };
24225
24226    var handleEnterKeyEvent = function (editor, event) {
24227      if (event.isDefaultPrevented()) {
24228        return;
24229      }
24230      event.preventDefault();
24231      endTypingLevelIgnoreLocks(editor.undoManager);
24232      editor.undoManager.transact(function () {
24233        if (editor.selection.isCollapsed() === false) {
24234          editor.execCommand('Delete');
24235        }
24236        insert$3(editor, event);
24237      });
24238    };
24239    var setup$e = function (editor) {
24240      editor.on('keydown', function (event) {
24241        if (event.keyCode === VK.ENTER) {
24242          handleEnterKeyEvent(editor, event);
24243        }
24244      });
24245    };
24246
24247    var executeKeydownOverride$2 = function (editor, evt) {
24248      execute([
24249        {
24250          keyCode: VK.END,
24251          action: action(moveToLineEndPoint$1, editor, true)
24252        },
24253        {
24254          keyCode: VK.HOME,
24255          action: action(moveToLineEndPoint$1, editor, false)
24256        },
24257        {
24258          keyCode: VK.END,
24259          action: action(moveToLineEndPoint$2, editor, true)
24260        },
24261        {
24262          keyCode: VK.HOME,
24263          action: action(moveToLineEndPoint$2, editor, false)
24264        }
24265      ], evt).each(function (_) {
24266        evt.preventDefault();
24267      });
24268    };
24269    var setup$f = function (editor) {
24270      editor.on('keydown', function (evt) {
24271        if (evt.isDefaultPrevented() === false) {
24272          executeKeydownOverride$2(editor, evt);
24273        }
24274      });
24275    };
24276
24277    var browser$4 = detect$3().browser;
24278    var setupIeInput = function (editor) {
24279      var keypressThrotter = first(function () {
24280        if (!editor.composing) {
24281          normalizeNbspsInEditor(editor);
24282        }
24283      }, 0);
24284      if (browser$4.isIE()) {
24285        editor.on('keypress', function (_e) {
24286          keypressThrotter.throttle();
24287        });
24288        editor.on('remove', function (_e) {
24289          keypressThrotter.cancel();
24290        });
24291      }
24292    };
24293    var setup$g = function (editor) {
24294      setupIeInput(editor);
24295      editor.on('input', function (e) {
24296        if (e.isComposing === false) {
24297          normalizeNbspsInEditor(editor);
24298        }
24299      });
24300    };
24301
24302    var insertTextAtPosition = function (text, pos) {
24303      var container = pos.container();
24304      var offset = pos.offset();
24305      if (isText$1(container)) {
24306        container.insertData(offset, text);
24307        return Optional.some(CaretPosition(container, offset + text.length));
24308      } else {
24309        return getElementFromPosition(pos).map(function (elm) {
24310          var textNode = SugarElement.fromText(text);
24311          if (pos.isAtEnd()) {
24312            after(elm, textNode);
24313          } else {
24314            before(elm, textNode);
24315          }
24316          return CaretPosition(textNode.dom, text.length);
24317        });
24318      }
24319    };
24320    var insertNbspAtPosition = curry(insertTextAtPosition, nbsp);
24321    var insertSpaceAtPosition = curry(insertTextAtPosition, ' ');
24322
24323    var locationToCaretPosition = function (root) {
24324      return function (location) {
24325        return location.fold(function (element) {
24326          return prevPosition(root.dom, CaretPosition$1.before(element));
24327        }, function (element) {
24328          return firstPositionIn(element);
24329        }, function (element) {
24330          return lastPositionIn(element);
24331        }, function (element) {
24332          return nextPosition(root.dom, CaretPosition$1.after(element));
24333        });
24334      };
24335    };
24336    var insertInlineBoundarySpaceOrNbsp = function (root, pos) {
24337      return function (checkPos) {
24338        return needsToHaveNbsp(root, checkPos) ? insertNbspAtPosition(pos) : insertSpaceAtPosition(pos);
24339      };
24340    };
24341    var setSelection$1 = function (editor) {
24342      return function (pos) {
24343        editor.selection.setRng(pos.toRange());
24344        editor.nodeChanged();
24345        return true;
24346      };
24347    };
24348    var insertSpaceOrNbspAtSelection = function (editor) {
24349      var pos = CaretPosition$1.fromRangeStart(editor.selection.getRng());
24350      var root = SugarElement.fromDom(editor.getBody());
24351      if (editor.selection.isCollapsed()) {
24352        var isInlineTarget$1 = curry(isInlineTarget, editor);
24353        var caretPosition = CaretPosition$1.fromRangeStart(editor.selection.getRng());
24354        return readLocation(isInlineTarget$1, editor.getBody(), caretPosition).bind(locationToCaretPosition(root)).bind(insertInlineBoundarySpaceOrNbsp(root, pos)).exists(setSelection$1(editor));
24355      } else {
24356        return false;
24357      }
24358    };
24359
24360    var executeKeydownOverride$3 = function (editor, evt) {
24361      execute([{
24362          keyCode: VK.SPACEBAR,
24363          action: action(insertSpaceOrNbspAtSelection, editor)
24364        }], evt).each(function (_) {
24365        evt.preventDefault();
24366      });
24367    };
24368    var setup$h = function (editor) {
24369      editor.on('keydown', function (evt) {
24370        if (evt.isDefaultPrevented() === false) {
24371          executeKeydownOverride$3(editor, evt);
24372        }
24373      });
24374    };
24375
24376    var registerKeyboardOverrides = function (editor) {
24377      var caret = setupSelectedState(editor);
24378      setup$b(editor);
24379      setup$c(editor, caret);
24380      setup$d(editor, caret);
24381      setup$e(editor);
24382      setup$h(editor);
24383      setup$g(editor);
24384      setup$f(editor);
24385      return caret;
24386    };
24387    var setup$i = function (editor) {
24388      if (!isRtc(editor)) {
24389        return registerKeyboardOverrides(editor);
24390      } else {
24391        return Cell(null);
24392      }
24393    };
24394
24395    var NodeChange = function () {
24396      function NodeChange(editor) {
24397        this.lastPath = [];
24398        this.editor = editor;
24399        var lastRng;
24400        var self = this;
24401        if (!('onselectionchange' in editor.getDoc())) {
24402          editor.on('NodeChange click mouseup keyup focus', function (e) {
24403            var nativeRng = editor.selection.getRng();
24404            var fakeRng = {
24405              startContainer: nativeRng.startContainer,
24406              startOffset: nativeRng.startOffset,
24407              endContainer: nativeRng.endContainer,
24408              endOffset: nativeRng.endOffset
24409            };
24410            if (e.type === 'nodechange' || !isEq$1(fakeRng, lastRng)) {
24411              editor.fire('SelectionChange');
24412            }
24413            lastRng = fakeRng;
24414          });
24415        }
24416        editor.on('contextmenu', function () {
24417          editor.fire('SelectionChange');
24418        });
24419        editor.on('SelectionChange', function () {
24420          var startElm = editor.selection.getStart(true);
24421          if (!startElm || !Env.range && editor.selection.isCollapsed()) {
24422            return;
24423          }
24424          if (hasAnyRanges(editor) && !self.isSameElementPath(startElm) && editor.dom.isChildOf(startElm, editor.getBody())) {
24425            editor.nodeChanged({ selectionChange: true });
24426          }
24427        });
24428        editor.on('mouseup', function (e) {
24429          if (!e.isDefaultPrevented() && hasAnyRanges(editor)) {
24430            if (editor.selection.getNode().nodeName === 'IMG') {
24431              Delay.setEditorTimeout(editor, function () {
24432                editor.nodeChanged();
24433              });
24434            } else {
24435              editor.nodeChanged();
24436            }
24437          }
24438        });
24439      }
24440      NodeChange.prototype.nodeChanged = function (args) {
24441        var selection = this.editor.selection;
24442        var node, parents, root;
24443        if (this.editor.initialized && selection && !shouldDisableNodeChange(this.editor) && !this.editor.mode.isReadOnly()) {
24444          root = this.editor.getBody();
24445          node = selection.getStart(true) || root;
24446          if (node.ownerDocument !== this.editor.getDoc() || !this.editor.dom.isChildOf(node, root)) {
24447            node = root;
24448          }
24449          parents = [];
24450          this.editor.dom.getParent(node, function (node) {
24451            if (node === root) {
24452              return true;
24453            }
24454            parents.push(node);
24455          });
24456          args = args || {};
24457          args.element = node;
24458          args.parents = parents;
24459          this.editor.fire('NodeChange', args);
24460        }
24461      };
24462      NodeChange.prototype.isSameElementPath = function (startElm) {
24463        var i;
24464        var currentPath = this.editor.$(startElm).parentsUntil(this.editor.getBody()).add(startElm);
24465        if (currentPath.length === this.lastPath.length) {
24466          for (i = currentPath.length; i >= 0; i--) {
24467            if (currentPath[i] !== this.lastPath[i]) {
24468              break;
24469            }
24470          }
24471          if (i === -1) {
24472            this.lastPath = currentPath;
24473            return true;
24474          }
24475        }
24476        this.lastPath = currentPath;
24477        return false;
24478      };
24479      return NodeChange;
24480    }();
24481
24482    var preventSummaryToggle = function (editor) {
24483      editor.on('click', function (e) {
24484        if (editor.dom.getParent(e.target, 'details')) {
24485          e.preventDefault();
24486        }
24487      });
24488    };
24489    var filterDetails = function (editor) {
24490      editor.parser.addNodeFilter('details', function (elms) {
24491        each(elms, function (details) {
24492          details.attr('data-mce-open', details.attr('open'));
24493          details.attr('open', 'open');
24494        });
24495      });
24496      editor.serializer.addNodeFilter('details', function (elms) {
24497        each(elms, function (details) {
24498          var open = details.attr('data-mce-open');
24499          details.attr('open', isString(open) ? open : null);
24500          details.attr('data-mce-open', null);
24501        });
24502      });
24503    };
24504    var setup$j = function (editor) {
24505      preventSummaryToggle(editor);
24506      filterDetails(editor);
24507    };
24508
24509    var isTextBlockNode = function (node) {
24510      return isElement$1(node) && isTextBlock(SugarElement.fromDom(node));
24511    };
24512    var normalizeSelection$1 = function (editor) {
24513      var rng = editor.selection.getRng();
24514      var startPos = CaretPosition.fromRangeStart(rng);
24515      var endPos = CaretPosition.fromRangeEnd(rng);
24516      if (CaretPosition.isElementPosition(startPos)) {
24517        var container = startPos.container();
24518        if (isTextBlockNode(container)) {
24519          firstPositionIn(container).each(function (pos) {
24520            return rng.setStart(pos.container(), pos.offset());
24521          });
24522        }
24523      }
24524      if (CaretPosition.isElementPosition(endPos)) {
24525        var container = startPos.container();
24526        if (isTextBlockNode(container)) {
24527          lastPositionIn(container).each(function (pos) {
24528            return rng.setEnd(pos.container(), pos.offset());
24529          });
24530        }
24531      }
24532      editor.selection.setRng(normalize$2(rng));
24533    };
24534    var setup$k = function (editor) {
24535      editor.on('click', function (e) {
24536        if (e.detail >= 3) {
24537          normalizeSelection$1(editor);
24538        }
24539      });
24540    };
24541
24542    var value$1 = function () {
24543      var subject = Cell(Optional.none());
24544      var clear = function () {
24545        return subject.set(Optional.none());
24546      };
24547      var set = function (s) {
24548        return subject.set(Optional.some(s));
24549      };
24550      var isSet = function () {
24551        return subject.get().isSome();
24552      };
24553      var on = function (f) {
24554        return subject.get().each(f);
24555      };
24556      return {
24557        clear: clear,
24558        set: set,
24559        isSet: isSet,
24560        on: on
24561      };
24562    };
24563
24564    var getAbsolutePosition = function (elm) {
24565      var clientRect = elm.getBoundingClientRect();
24566      var doc = elm.ownerDocument;
24567      var docElem = doc.documentElement;
24568      var win = doc.defaultView;
24569      return {
24570        top: clientRect.top + win.pageYOffset - docElem.clientTop,
24571        left: clientRect.left + win.pageXOffset - docElem.clientLeft
24572      };
24573    };
24574    var getBodyPosition = function (editor) {
24575      return editor.inline ? getAbsolutePosition(editor.getBody()) : {
24576        left: 0,
24577        top: 0
24578      };
24579    };
24580    var getScrollPosition = function (editor) {
24581      var body = editor.getBody();
24582      return editor.inline ? {
24583        left: body.scrollLeft,
24584        top: body.scrollTop
24585      } : {
24586        left: 0,
24587        top: 0
24588      };
24589    };
24590    var getBodyScroll = function (editor) {
24591      var body = editor.getBody(), docElm = editor.getDoc().documentElement;
24592      var inlineScroll = {
24593        left: body.scrollLeft,
24594        top: body.scrollTop
24595      };
24596      var iframeScroll = {
24597        left: body.scrollLeft || docElm.scrollLeft,
24598        top: body.scrollTop || docElm.scrollTop
24599      };
24600      return editor.inline ? inlineScroll : iframeScroll;
24601    };
24602    var getMousePosition = function (editor, event) {
24603      if (event.target.ownerDocument !== editor.getDoc()) {
24604        var iframePosition = getAbsolutePosition(editor.getContentAreaContainer());
24605        var scrollPosition = getBodyScroll(editor);
24606        return {
24607          left: event.pageX - iframePosition.left + scrollPosition.left,
24608          top: event.pageY - iframePosition.top + scrollPosition.top
24609        };
24610      }
24611      return {
24612        left: event.pageX,
24613        top: event.pageY
24614      };
24615    };
24616    var calculatePosition = function (bodyPosition, scrollPosition, mousePosition) {
24617      return {
24618        pageX: mousePosition.left - bodyPosition.left + scrollPosition.left,
24619        pageY: mousePosition.top - bodyPosition.top + scrollPosition.top
24620      };
24621    };
24622    var calc = function (editor, event) {
24623      return calculatePosition(getBodyPosition(editor), getScrollPosition(editor), getMousePosition(editor, event));
24624    };
24625
24626    var isContentEditableFalse$a = isContentEditableFalse, isContentEditableTrue$3 = isContentEditableTrue;
24627    var isDraggable = function (rootElm, elm) {
24628      return isContentEditableFalse$a(elm) && elm !== rootElm;
24629    };
24630    var isValidDropTarget = function (editor, targetElement, dragElement) {
24631      if (targetElement === dragElement || editor.dom.isChildOf(targetElement, dragElement)) {
24632        return false;
24633      }
24634      return !isContentEditableFalse$a(targetElement);
24635    };
24636    var cloneElement = function (elm) {
24637      var cloneElm = elm.cloneNode(true);
24638      cloneElm.removeAttribute('data-mce-selected');
24639      return cloneElm;
24640    };
24641    var createGhost = function (editor, elm, width, height) {
24642      var dom = editor.dom;
24643      var clonedElm = elm.cloneNode(true);
24644      dom.setStyles(clonedElm, {
24645        width: width,
24646        height: height
24647      });
24648      dom.setAttrib(clonedElm, 'data-mce-selected', null);
24649      var ghostElm = dom.create('div', {
24650        'class': 'mce-drag-container',
24651        'data-mce-bogus': 'all',
24652        'unselectable': 'on',
24653        'contenteditable': 'false'
24654      });
24655      dom.setStyles(ghostElm, {
24656        position: 'absolute',
24657        opacity: 0.5,
24658        overflow: 'hidden',
24659        border: 0,
24660        padding: 0,
24661        margin: 0,
24662        width: width,
24663        height: height
24664      });
24665      dom.setStyles(clonedElm, {
24666        margin: 0,
24667        boxSizing: 'border-box'
24668      });
24669      ghostElm.appendChild(clonedElm);
24670      return ghostElm;
24671    };
24672    var appendGhostToBody = function (ghostElm, bodyElm) {
24673      if (ghostElm.parentNode !== bodyElm) {
24674        bodyElm.appendChild(ghostElm);
24675      }
24676    };
24677    var moveGhost = function (ghostElm, position, width, height, maxX, maxY) {
24678      var overflowX = 0, overflowY = 0;
24679      ghostElm.style.left = position.pageX + 'px';
24680      ghostElm.style.top = position.pageY + 'px';
24681      if (position.pageX + width > maxX) {
24682        overflowX = position.pageX + width - maxX;
24683      }
24684      if (position.pageY + height > maxY) {
24685        overflowY = position.pageY + height - maxY;
24686      }
24687      ghostElm.style.width = width - overflowX + 'px';
24688      ghostElm.style.height = height - overflowY + 'px';
24689    };
24690    var removeElement = function (elm) {
24691      if (elm && elm.parentNode) {
24692        elm.parentNode.removeChild(elm);
24693      }
24694    };
24695    var isLeftMouseButtonPressed = function (e) {
24696      return e.button === 0;
24697    };
24698    var applyRelPos = function (state, position) {
24699      return {
24700        pageX: position.pageX - state.relX,
24701        pageY: position.pageY + 5
24702      };
24703    };
24704    var start$1 = function (state, editor) {
24705      return function (e) {
24706        if (isLeftMouseButtonPressed(e)) {
24707          var ceElm = find(editor.dom.getParents(e.target), or(isContentEditableFalse$a, isContentEditableTrue$3)).getOr(null);
24708          if (isDraggable(editor.getBody(), ceElm)) {
24709            var elmPos = editor.dom.getPos(ceElm);
24710            var bodyElm = editor.getBody();
24711            var docElm = editor.getDoc().documentElement;
24712            state.set({
24713              element: ceElm,
24714              dragging: false,
24715              screenX: e.screenX,
24716              screenY: e.screenY,
24717              maxX: (editor.inline ? bodyElm.scrollWidth : docElm.offsetWidth) - 2,
24718              maxY: (editor.inline ? bodyElm.scrollHeight : docElm.offsetHeight) - 2,
24719              relX: e.pageX - elmPos.x,
24720              relY: e.pageY - elmPos.y,
24721              width: ceElm.offsetWidth,
24722              height: ceElm.offsetHeight,
24723              ghost: createGhost(editor, ceElm, ceElm.offsetWidth, ceElm.offsetHeight)
24724            });
24725          }
24726        }
24727      };
24728    };
24729    var move$2 = function (state, editor) {
24730      var throttledPlaceCaretAt = Delay.throttle(function (clientX, clientY) {
24731        editor._selectionOverrides.hideFakeCaret();
24732        editor.selection.placeCaretAt(clientX, clientY);
24733      }, 0);
24734      return function (e) {
24735        return state.on(function (state) {
24736          var movement = Math.max(Math.abs(e.screenX - state.screenX), Math.abs(e.screenY - state.screenY));
24737          if (!state.dragging && movement > 10) {
24738            var args = editor.fire('dragstart', { target: state.element });
24739            if (args.isDefaultPrevented()) {
24740              return;
24741            }
24742            state.dragging = true;
24743            editor.focus();
24744          }
24745          if (state.dragging) {
24746            var targetPos = applyRelPos(state, calc(editor, e));
24747            appendGhostToBody(state.ghost, editor.getBody());
24748            moveGhost(state.ghost, targetPos, state.width, state.height, state.maxX, state.maxY);
24749            throttledPlaceCaretAt(e.clientX, e.clientY);
24750          }
24751        });
24752      };
24753    };
24754    var getRawTarget = function (selection) {
24755      var rng = selection.getSel().getRangeAt(0);
24756      var startContainer = rng.startContainer;
24757      return startContainer.nodeType === 3 ? startContainer.parentNode : startContainer;
24758    };
24759    var drop = function (state, editor) {
24760      return function (e) {
24761        state.on(function (state) {
24762          if (state.dragging) {
24763            if (isValidDropTarget(editor, getRawTarget(editor.selection), state.element)) {
24764              var targetClone_1 = cloneElement(state.element);
24765              var args = editor.fire('drop', {
24766                clientX: e.clientX,
24767                clientY: e.clientY
24768              });
24769              if (!args.isDefaultPrevented()) {
24770                editor.undoManager.transact(function () {
24771                  removeElement(state.element);
24772                  editor.insertContent(editor.dom.getOuterHTML(targetClone_1));
24773                  editor._selectionOverrides.hideFakeCaret();
24774                });
24775              }
24776            }
24777          }
24778        });
24779        removeDragState(state);
24780      };
24781    };
24782    var stop = function (state, editor) {
24783      return function () {
24784        state.on(function (state) {
24785          if (state.dragging) {
24786            editor.fire('dragend');
24787          }
24788        });
24789        removeDragState(state);
24790      };
24791    };
24792    var removeDragState = function (state) {
24793      state.on(function (state) {
24794        removeElement(state.ghost);
24795      });
24796      state.clear();
24797    };
24798    var bindFakeDragEvents = function (editor) {
24799      var state = value$1();
24800      var pageDom = DOMUtils$1.DOM;
24801      var rootDocument = document;
24802      var dragStartHandler = start$1(state, editor);
24803      var dragHandler = move$2(state, editor);
24804      var dropHandler = drop(state, editor);
24805      var dragEndHandler = stop(state, editor);
24806      editor.on('mousedown', dragStartHandler);
24807      editor.on('mousemove', dragHandler);
24808      editor.on('mouseup', dropHandler);
24809      pageDom.bind(rootDocument, 'mousemove', dragHandler);
24810      pageDom.bind(rootDocument, 'mouseup', dragEndHandler);
24811      editor.on('remove', function () {
24812        pageDom.unbind(rootDocument, 'mousemove', dragHandler);
24813        pageDom.unbind(rootDocument, 'mouseup', dragEndHandler);
24814      });
24815    };
24816    var blockIeDrop = function (editor) {
24817      editor.on('drop', function (e) {
24818        var realTarget = typeof e.clientX !== 'undefined' ? editor.getDoc().elementFromPoint(e.clientX, e.clientY) : null;
24819        if (isContentEditableFalse$a(realTarget) || editor.dom.getContentEditableParent(realTarget) === 'false') {
24820          e.preventDefault();
24821        }
24822      });
24823    };
24824    var blockUnsupportedFileDrop = function (editor) {
24825      var preventFileDrop = function (e) {
24826        if (!e.defaultPrevented) {
24827          var dataTransfer = e.dataTransfer;
24828          if (dataTransfer && (contains(dataTransfer.types, 'Files') || dataTransfer.files.length > 0)) {
24829            e.preventDefault();
24830            if (e.type === 'drop') {
24831              displayError(editor, 'Dropped file type is not supported');
24832            }
24833          }
24834        }
24835      };
24836      var preventFileDropIfUIElement = function (e) {
24837        if (isUIElement(editor, e.target)) {
24838          preventFileDrop(e);
24839        }
24840      };
24841      var setup = function () {
24842        var pageDom = DOMUtils$1.DOM;
24843        var dom = editor.dom;
24844        var doc = document;
24845        var editorRoot = editor.inline ? editor.getBody() : editor.getDoc();
24846        var eventNames = [
24847          'drop',
24848          'dragover'
24849        ];
24850        each(eventNames, function (name) {
24851          pageDom.bind(doc, name, preventFileDropIfUIElement);
24852          dom.bind(editorRoot, name, preventFileDrop);
24853        });
24854        editor.on('remove', function () {
24855          each(eventNames, function (name) {
24856            pageDom.unbind(doc, name, preventFileDropIfUIElement);
24857            dom.unbind(editorRoot, name, preventFileDrop);
24858          });
24859        });
24860      };
24861      editor.on('init', function () {
24862        Delay.setEditorTimeout(editor, setup, 0);
24863      });
24864    };
24865    var init = function (editor) {
24866      bindFakeDragEvents(editor);
24867      blockIeDrop(editor);
24868      if (shouldBlockUnsupportedDrop(editor)) {
24869        blockUnsupportedFileDrop(editor);
24870      }
24871    };
24872
24873    var setup$l = function (editor) {
24874      var renderFocusCaret = first(function () {
24875        if (!editor.removed && editor.getBody().contains(document.activeElement)) {
24876          var rng = editor.selection.getRng();
24877          if (rng.collapsed) {
24878            var caretRange = renderRangeCaret(editor, rng, false);
24879            editor.selection.setRng(caretRange);
24880          }
24881        }
24882      }, 0);
24883      editor.on('focus', function () {
24884        renderFocusCaret.throttle();
24885      });
24886      editor.on('blur', function () {
24887        renderFocusCaret.cancel();
24888      });
24889    };
24890
24891    var setup$m = function (editor) {
24892      editor.on('init', function () {
24893        editor.on('focusin', function (e) {
24894          var target = e.target;
24895          if (isMedia(target)) {
24896            var ceRoot = getContentEditableRoot(editor.getBody(), target);
24897            var node = isContentEditableFalse(ceRoot) ? ceRoot : target;
24898            if (editor.selection.getNode() !== node) {
24899              selectNode(editor, node).each(function (rng) {
24900                return editor.selection.setRng(rng);
24901              });
24902            }
24903          }
24904        });
24905      });
24906    };
24907
24908    var isContentEditableTrue$4 = isContentEditableTrue;
24909    var isContentEditableFalse$b = isContentEditableFalse;
24910    var getContentEditableRoot$1 = function (editor, node) {
24911      return getContentEditableRoot(editor.getBody(), node);
24912    };
24913    var SelectionOverrides = function (editor) {
24914      var selection = editor.selection, dom = editor.dom;
24915      var isBlock = dom.isBlock;
24916      var rootNode = editor.getBody();
24917      var fakeCaret = FakeCaret(editor, rootNode, isBlock, function () {
24918        return hasFocus$1(editor);
24919      });
24920      var realSelectionId = 'sel-' + dom.uniqueId();
24921      var elementSelectionAttr = 'data-mce-selected';
24922      var selectedElement;
24923      var isFakeSelectionElement = function (node) {
24924        return dom.hasClass(node, 'mce-offscreen-selection');
24925      };
24926      var isFakeSelectionTargetElement = function (node) {
24927        return isContentEditableFalse$b(node) || isMedia(node);
24928      };
24929      var isNearFakeSelectionElement = function (pos) {
24930        return isBeforeContentEditableFalse(pos) || isAfterContentEditableFalse(pos) || isBeforeMedia(pos) || isAfterMedia(pos);
24931      };
24932      var getRealSelectionElement = function () {
24933        var container = dom.get(realSelectionId);
24934        return container ? container.getElementsByTagName('*')[0] : container;
24935      };
24936      var setRange = function (range) {
24937        if (range) {
24938          selection.setRng(range);
24939        }
24940      };
24941      var getRange = selection.getRng;
24942      var showCaret = function (direction, node, before, scrollIntoView) {
24943        if (scrollIntoView === void 0) {
24944          scrollIntoView = true;
24945        }
24946        var e = editor.fire('ShowCaret', {
24947          target: node,
24948          direction: direction,
24949          before: before
24950        });
24951        if (e.isDefaultPrevented()) {
24952          return null;
24953        }
24954        if (scrollIntoView) {
24955          selection.scrollIntoView(node, direction === -1);
24956        }
24957        return fakeCaret.show(before, node);
24958      };
24959      var showBlockCaretContainer = function (blockCaretContainer) {
24960        if (blockCaretContainer.hasAttribute('data-mce-caret')) {
24961          showCaretContainerBlock(blockCaretContainer);
24962          setRange(getRange());
24963          selection.scrollIntoView(blockCaretContainer);
24964        }
24965      };
24966      var registerEvents = function () {
24967        editor.on('mouseup', function (e) {
24968          var range = getRange();
24969          if (range.collapsed && isXYInContentArea(editor, e.clientX, e.clientY)) {
24970            renderCaretAtRange(editor, range, false).each(setRange);
24971          }
24972        });
24973        editor.on('click', function (e) {
24974          var contentEditableRoot = getContentEditableRoot$1(editor, e.target);
24975          if (contentEditableRoot) {
24976            if (isContentEditableFalse$b(contentEditableRoot)) {
24977              e.preventDefault();
24978              editor.focus();
24979            }
24980            if (isContentEditableTrue$4(contentEditableRoot)) {
24981              if (dom.isChildOf(contentEditableRoot, selection.getNode())) {
24982                removeElementSelection();
24983              }
24984            }
24985          }
24986        });
24987        editor.on('blur NewBlock', removeElementSelection);
24988        editor.on('ResizeWindow FullscreenStateChanged', fakeCaret.reposition);
24989        var hasNormalCaretPosition = function (elm) {
24990          var caretWalker = CaretWalker(elm);
24991          if (!elm.firstChild) {
24992            return false;
24993          }
24994          var startPos = CaretPosition$1.before(elm.firstChild);
24995          var newPos = caretWalker.next(startPos);
24996          return newPos && !isNearFakeSelectionElement(newPos);
24997        };
24998        var isInSameBlock = function (node1, node2) {
24999          var block1 = dom.getParent(node1, isBlock);
25000          var block2 = dom.getParent(node2, isBlock);
25001          return block1 === block2;
25002        };
25003        var hasBetterMouseTarget = function (targetNode, caretNode) {
25004          var targetBlock = dom.getParent(targetNode, isBlock);
25005          var caretBlock = dom.getParent(caretNode, isBlock);
25006          if (targetBlock && targetNode !== caretBlock && dom.isChildOf(targetBlock, caretBlock) && isContentEditableFalse$b(getContentEditableRoot$1(editor, targetBlock)) === false) {
25007            return true;
25008          }
25009          return targetBlock && !isInSameBlock(targetBlock, caretBlock) && hasNormalCaretPosition(targetBlock);
25010        };
25011        editor.on('tap', function (e) {
25012          var targetElm = e.target;
25013          var contentEditableRoot = getContentEditableRoot$1(editor, targetElm);
25014          if (isContentEditableFalse$b(contentEditableRoot)) {
25015            e.preventDefault();
25016            selectNode(editor, contentEditableRoot).each(setElementSelection);
25017          } else if (isFakeSelectionTargetElement(targetElm)) {
25018            selectNode(editor, targetElm).each(setElementSelection);
25019          }
25020        }, true);
25021        editor.on('mousedown', function (e) {
25022          var targetElm = e.target;
25023          if (targetElm !== rootNode && targetElm.nodeName !== 'HTML' && !dom.isChildOf(targetElm, rootNode)) {
25024            return;
25025          }
25026          if (isXYInContentArea(editor, e.clientX, e.clientY) === false) {
25027            return;
25028          }
25029          var contentEditableRoot = getContentEditableRoot$1(editor, targetElm);
25030          if (contentEditableRoot) {
25031            if (isContentEditableFalse$b(contentEditableRoot)) {
25032              e.preventDefault();
25033              selectNode(editor, contentEditableRoot).each(setElementSelection);
25034            } else {
25035              removeElementSelection();
25036              if (!(isContentEditableTrue$4(contentEditableRoot) && e.shiftKey) && !isXYWithinRange(e.clientX, e.clientY, selection.getRng())) {
25037                hideFakeCaret();
25038                selection.placeCaretAt(e.clientX, e.clientY);
25039              }
25040            }
25041          } else if (isFakeSelectionTargetElement(targetElm)) {
25042            selectNode(editor, targetElm).each(setElementSelection);
25043          } else if (isFakeCaretTarget(targetElm) === false) {
25044            removeElementSelection();
25045            hideFakeCaret();
25046            var fakeCaretInfo = closestFakeCaret(rootNode, e.clientX, e.clientY);
25047            if (fakeCaretInfo) {
25048              if (!hasBetterMouseTarget(targetElm, fakeCaretInfo.node)) {
25049                e.preventDefault();
25050                var range = showCaret(1, fakeCaretInfo.node, fakeCaretInfo.before, false);
25051                editor.getBody().focus();
25052                setRange(range);
25053              }
25054            }
25055          }
25056        });
25057        editor.on('keypress', function (e) {
25058          if (VK.modifierPressed(e)) {
25059            return;
25060          }
25061          if (isContentEditableFalse$b(selection.getNode())) {
25062            e.preventDefault();
25063          }
25064        });
25065        editor.on('GetSelectionRange', function (e) {
25066          var rng = e.range;
25067          if (selectedElement) {
25068            if (!selectedElement.parentNode) {
25069              selectedElement = null;
25070              return;
25071            }
25072            rng = rng.cloneRange();
25073            rng.selectNode(selectedElement);
25074            e.range = rng;
25075          }
25076        });
25077        editor.on('SetSelectionRange', function (e) {
25078          e.range = normalizeShortEndedElementSelection(e.range);
25079          var rng = setElementSelection(e.range, e.forward);
25080          if (rng) {
25081            e.range = rng;
25082          }
25083        });
25084        var isPasteBin = function (node) {
25085          return node.id === 'mcepastebin';
25086        };
25087        editor.on('AfterSetSelectionRange', function (e) {
25088          var rng = e.range;
25089          var parentNode = rng.startContainer.parentNode;
25090          if (!isRangeInCaretContainer(rng) && !isPasteBin(parentNode)) {
25091            hideFakeCaret();
25092          }
25093          if (!isFakeSelectionElement(parentNode)) {
25094            removeElementSelection();
25095          }
25096        });
25097        editor.on('copy', function (e) {
25098          var clipboardData = e.clipboardData;
25099          if (!e.isDefaultPrevented() && e.clipboardData && !Env.ie) {
25100            var realSelectionElement = getRealSelectionElement();
25101            if (realSelectionElement) {
25102              e.preventDefault();
25103              clipboardData.clearData();
25104              clipboardData.setData('text/html', realSelectionElement.outerHTML);
25105              clipboardData.setData('text/plain', realSelectionElement.outerText || realSelectionElement.innerText);
25106            }
25107          }
25108        });
25109        init(editor);
25110        setup$l(editor);
25111        setup$m(editor);
25112      };
25113      var isWithinCaretContainer = function (node) {
25114        return isCaretContainer(node) || startsWithCaretContainer(node) || endsWithCaretContainer(node);
25115      };
25116      var isRangeInCaretContainer = function (rng) {
25117        return isWithinCaretContainer(rng.startContainer) || isWithinCaretContainer(rng.endContainer);
25118      };
25119      var normalizeShortEndedElementSelection = function (rng) {
25120        var shortEndedElements = editor.schema.getShortEndedElements();
25121        var newRng = dom.createRng();
25122        var startContainer = rng.startContainer;
25123        var startOffset = rng.startOffset;
25124        var endContainer = rng.endContainer;
25125        var endOffset = rng.endOffset;
25126        if (has(shortEndedElements, startContainer.nodeName.toLowerCase())) {
25127          if (startOffset === 0) {
25128            newRng.setStartBefore(startContainer);
25129          } else {
25130            newRng.setStartAfter(startContainer);
25131          }
25132        } else {
25133          newRng.setStart(startContainer, startOffset);
25134        }
25135        if (has(shortEndedElements, endContainer.nodeName.toLowerCase())) {
25136          if (endOffset === 0) {
25137            newRng.setEndBefore(endContainer);
25138          } else {
25139            newRng.setEndAfter(endContainer);
25140          }
25141        } else {
25142          newRng.setEnd(endContainer, endOffset);
25143        }
25144        return newRng;
25145      };
25146      var setupOffscreenSelection = function (node, targetClone, origTargetClone) {
25147        var $ = editor.$;
25148        var $realSelectionContainer = descendant(SugarElement.fromDom(editor.getBody()), '#' + realSelectionId).fold(function () {
25149          return $([]);
25150        }, function (elm) {
25151          return $([elm.dom]);
25152        });
25153        if ($realSelectionContainer.length === 0) {
25154          $realSelectionContainer = $('<div data-mce-bogus="all" class="mce-offscreen-selection"></div>').attr('id', realSelectionId);
25155          $realSelectionContainer.appendTo(editor.getBody());
25156        }
25157        var newRange = dom.createRng();
25158        if (targetClone === origTargetClone && Env.ie) {
25159          $realSelectionContainer.empty().append('<p style="font-size: 0" data-mce-bogus="all">\xA0</p>').append(targetClone);
25160          newRange.setStartAfter($realSelectionContainer[0].firstChild.firstChild);
25161          newRange.setEndAfter(targetClone);
25162        } else {
25163          $realSelectionContainer.empty().append(nbsp).append(targetClone).append(nbsp);
25164          newRange.setStart($realSelectionContainer[0].firstChild, 1);
25165          newRange.setEnd($realSelectionContainer[0].lastChild, 0);
25166        }
25167        $realSelectionContainer.css({ top: dom.getPos(node, editor.getBody()).y });
25168        $realSelectionContainer[0].focus();
25169        var sel = selection.getSel();
25170        sel.removeAllRanges();
25171        sel.addRange(newRange);
25172        return newRange;
25173      };
25174      var selectElement = function (elm) {
25175        var targetClone = elm.cloneNode(true);
25176        var e = editor.fire('ObjectSelected', {
25177          target: elm,
25178          targetClone: targetClone
25179        });
25180        if (e.isDefaultPrevented()) {
25181          return null;
25182        }
25183        var range = setupOffscreenSelection(elm, e.targetClone, targetClone);
25184        var nodeElm = SugarElement.fromDom(elm);
25185        each(descendants$1(SugarElement.fromDom(editor.getBody()), '*[data-mce-selected]'), function (elm) {
25186          if (!eq$2(nodeElm, elm)) {
25187            remove$1(elm, elementSelectionAttr);
25188          }
25189        });
25190        if (!dom.getAttrib(elm, elementSelectionAttr)) {
25191          elm.setAttribute(elementSelectionAttr, '1');
25192        }
25193        selectedElement = elm;
25194        hideFakeCaret();
25195        return range;
25196      };
25197      var setElementSelection = function (range, forward) {
25198        if (!range) {
25199          return null;
25200        }
25201        if (range.collapsed) {
25202          if (!isRangeInCaretContainer(range)) {
25203            var dir = forward ? 1 : -1;
25204            var caretPosition = getNormalizedRangeEndPoint(dir, rootNode, range);
25205            var beforeNode = caretPosition.getNode(!forward);
25206            if (isFakeCaretTarget(beforeNode)) {
25207              return showCaret(dir, beforeNode, forward ? !caretPosition.isAtEnd() : false, false);
25208            }
25209            var afterNode = caretPosition.getNode(forward);
25210            if (isFakeCaretTarget(afterNode)) {
25211              return showCaret(dir, afterNode, forward ? false : !caretPosition.isAtEnd(), false);
25212            }
25213          }
25214          return null;
25215        }
25216        var startContainer = range.startContainer;
25217        var startOffset = range.startOffset;
25218        var endOffset = range.endOffset;
25219        if (startContainer.nodeType === 3 && startOffset === 0 && isContentEditableFalse$b(startContainer.parentNode)) {
25220          startContainer = startContainer.parentNode;
25221          startOffset = dom.nodeIndex(startContainer);
25222          startContainer = startContainer.parentNode;
25223        }
25224        if (startContainer.nodeType !== 1) {
25225          return null;
25226        }
25227        if (endOffset === startOffset + 1 && startContainer === range.endContainer) {
25228          var node = startContainer.childNodes[startOffset];
25229          if (isFakeSelectionTargetElement(node)) {
25230            return selectElement(node);
25231          }
25232        }
25233        return null;
25234      };
25235      var removeElementSelection = function () {
25236        if (selectedElement) {
25237          selectedElement.removeAttribute(elementSelectionAttr);
25238        }
25239        descendant(SugarElement.fromDom(editor.getBody()), '#' + realSelectionId).each(remove);
25240        selectedElement = null;
25241      };
25242      var destroy = function () {
25243        fakeCaret.destroy();
25244        selectedElement = null;
25245      };
25246      var hideFakeCaret = function () {
25247        fakeCaret.hide();
25248      };
25249      if (Env.ceFalse) {
25250        registerEvents();
25251      }
25252      return {
25253        showCaret: showCaret,
25254        showBlockCaretContainer: showBlockCaretContainer,
25255        hideFakeCaret: hideFakeCaret,
25256        destroy: destroy
25257      };
25258    };
25259
25260    var Quirks = function (editor) {
25261      var each = Tools.each;
25262      var BACKSPACE = VK.BACKSPACE, DELETE = VK.DELETE, dom = editor.dom, selection = editor.selection, parser = editor.parser;
25263      var isGecko = Env.gecko, isIE = Env.ie, isWebKit = Env.webkit;
25264      var mceInternalUrlPrefix = 'data:text/mce-internal,';
25265      var mceInternalDataType = isIE ? 'Text' : 'URL';
25266      var setEditorCommandState = function (cmd, state) {
25267        try {
25268          editor.getDoc().execCommand(cmd, false, state);
25269        } catch (ex) {
25270        }
25271      };
25272      var isDefaultPrevented = function (e) {
25273        return e.isDefaultPrevented();
25274      };
25275      var setMceInternalContent = function (e) {
25276        var selectionHtml, internalContent;
25277        if (e.dataTransfer) {
25278          if (editor.selection.isCollapsed() && e.target.tagName === 'IMG') {
25279            selection.select(e.target);
25280          }
25281          selectionHtml = editor.selection.getContent();
25282          if (selectionHtml.length > 0) {
25283            internalContent = mceInternalUrlPrefix + escape(editor.id) + ',' + escape(selectionHtml);
25284            e.dataTransfer.setData(mceInternalDataType, internalContent);
25285          }
25286        }
25287      };
25288      var getMceInternalContent = function (e) {
25289        var internalContent;
25290        if (e.dataTransfer) {
25291          internalContent = e.dataTransfer.getData(mceInternalDataType);
25292          if (internalContent && internalContent.indexOf(mceInternalUrlPrefix) >= 0) {
25293            internalContent = internalContent.substr(mceInternalUrlPrefix.length).split(',');
25294            return {
25295              id: unescape(internalContent[0]),
25296              html: unescape(internalContent[1])
25297            };
25298          }
25299        }
25300        return null;
25301      };
25302      var insertClipboardContents = function (content, internal) {
25303        if (editor.queryCommandSupported('mceInsertClipboardContent')) {
25304          editor.execCommand('mceInsertClipboardContent', false, {
25305            content: content,
25306            internal: internal
25307          });
25308        } else {
25309          editor.execCommand('mceInsertContent', false, content);
25310        }
25311      };
25312      var emptyEditorWhenDeleting = function () {
25313        var serializeRng = function (rng) {
25314          var body = dom.create('body');
25315          var contents = rng.cloneContents();
25316          body.appendChild(contents);
25317          return selection.serializer.serialize(body, { format: 'html' });
25318        };
25319        var allContentsSelected = function (rng) {
25320          var selection = serializeRng(rng);
25321          var allRng = dom.createRng();
25322          allRng.selectNode(editor.getBody());
25323          var allSelection = serializeRng(allRng);
25324          return selection === allSelection;
25325        };
25326        editor.on('keydown', function (e) {
25327          var keyCode = e.keyCode;
25328          var isCollapsed, body;
25329          if (!isDefaultPrevented(e) && (keyCode === DELETE || keyCode === BACKSPACE)) {
25330            isCollapsed = editor.selection.isCollapsed();
25331            body = editor.getBody();
25332            if (isCollapsed && !dom.isEmpty(body)) {
25333              return;
25334            }
25335            if (!isCollapsed && !allContentsSelected(editor.selection.getRng())) {
25336              return;
25337            }
25338            e.preventDefault();
25339            editor.setContent('');
25340            if (body.firstChild && dom.isBlock(body.firstChild)) {
25341              editor.selection.setCursorLocation(body.firstChild, 0);
25342            } else {
25343              editor.selection.setCursorLocation(body, 0);
25344            }
25345            editor.nodeChanged();
25346          }
25347        });
25348      };
25349      var selectAll = function () {
25350        editor.shortcuts.add('meta+a', null, 'SelectAll');
25351      };
25352      var inputMethodFocus = function () {
25353        if (!editor.inline) {
25354          dom.bind(editor.getDoc(), 'mousedown mouseup', function (e) {
25355            var rng;
25356            if (e.target === editor.getDoc().documentElement) {
25357              rng = selection.getRng();
25358              editor.getBody().focus();
25359              if (e.type === 'mousedown') {
25360                if (isCaretContainer(rng.startContainer)) {
25361                  return;
25362                }
25363                selection.placeCaretAt(e.clientX, e.clientY);
25364              } else {
25365                selection.setRng(rng);
25366              }
25367            }
25368          });
25369        }
25370      };
25371      var removeHrOnBackspace = function () {
25372        editor.on('keydown', function (e) {
25373          if (!isDefaultPrevented(e) && e.keyCode === BACKSPACE) {
25374            if (!editor.getBody().getElementsByTagName('hr').length) {
25375              return;
25376            }
25377            if (selection.isCollapsed() && selection.getRng().startOffset === 0) {
25378              var node = selection.getNode();
25379              var previousSibling = node.previousSibling;
25380              if (node.nodeName === 'HR') {
25381                dom.remove(node);
25382                e.preventDefault();
25383                return;
25384              }
25385              if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === 'hr') {
25386                dom.remove(previousSibling);
25387                e.preventDefault();
25388              }
25389            }
25390          }
25391        });
25392      };
25393      var focusBody = function () {
25394        if (!Range.prototype.getClientRects) {
25395          editor.on('mousedown', function (e) {
25396            if (!isDefaultPrevented(e) && e.target.nodeName === 'HTML') {
25397              var body_1 = editor.getBody();
25398              body_1.blur();
25399              Delay.setEditorTimeout(editor, function () {
25400                body_1.focus();
25401              });
25402            }
25403          });
25404        }
25405      };
25406      var selectControlElements = function () {
25407        editor.on('click', function (e) {
25408          var target = e.target;
25409          if (/^(IMG|HR)$/.test(target.nodeName) && dom.getContentEditableParent(target) !== 'false') {
25410            e.preventDefault();
25411            editor.selection.select(target);
25412            editor.nodeChanged();
25413          }
25414          if (target.nodeName === 'A' && dom.hasClass(target, 'mce-item-anchor')) {
25415            e.preventDefault();
25416            selection.select(target);
25417          }
25418        });
25419      };
25420      var removeStylesWhenDeletingAcrossBlockElements = function () {
25421        var getAttributeApplyFunction = function () {
25422          var template = dom.getAttribs(selection.getStart().cloneNode(false));
25423          return function () {
25424            var target = selection.getStart();
25425            if (target !== editor.getBody()) {
25426              dom.setAttrib(target, 'style', null);
25427              each(template, function (attr) {
25428                target.setAttributeNode(attr.cloneNode(true));
25429              });
25430            }
25431          };
25432        };
25433        var isSelectionAcrossElements = function () {
25434          return !selection.isCollapsed() && dom.getParent(selection.getStart(), dom.isBlock) !== dom.getParent(selection.getEnd(), dom.isBlock);
25435        };
25436        editor.on('keypress', function (e) {
25437          var applyAttributes;
25438          if (!isDefaultPrevented(e) && (e.keyCode === 8 || e.keyCode === 46) && isSelectionAcrossElements()) {
25439            applyAttributes = getAttributeApplyFunction();
25440            editor.getDoc().execCommand('delete', false, null);
25441            applyAttributes();
25442            e.preventDefault();
25443            return false;
25444          }
25445        });
25446        dom.bind(editor.getDoc(), 'cut', function (e) {
25447          var applyAttributes;
25448          if (!isDefaultPrevented(e) && isSelectionAcrossElements()) {
25449            applyAttributes = getAttributeApplyFunction();
25450            Delay.setEditorTimeout(editor, function () {
25451              applyAttributes();
25452            });
25453          }
25454        });
25455      };
25456      var disableBackspaceIntoATable = function () {
25457        editor.on('keydown', function (e) {
25458          if (!isDefaultPrevented(e) && e.keyCode === BACKSPACE) {
25459            if (selection.isCollapsed() && selection.getRng().startOffset === 0) {
25460              var previousSibling = selection.getNode().previousSibling;
25461              if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === 'table') {
25462                e.preventDefault();
25463                return false;
25464              }
25465            }
25466          }
25467        });
25468      };
25469      var removeBlockQuoteOnBackSpace = function () {
25470        editor.on('keydown', function (e) {
25471          var rng, parent;
25472          if (isDefaultPrevented(e) || e.keyCode !== VK.BACKSPACE) {
25473            return;
25474          }
25475          rng = selection.getRng();
25476          var container = rng.startContainer;
25477          var offset = rng.startOffset;
25478          var root = dom.getRoot();
25479          parent = container;
25480          if (!rng.collapsed || offset !== 0) {
25481            return;
25482          }
25483          while (parent && parent.parentNode && parent.parentNode.firstChild === parent && parent.parentNode !== root) {
25484            parent = parent.parentNode;
25485          }
25486          if (parent.tagName === 'BLOCKQUOTE') {
25487            editor.formatter.toggle('blockquote', null, parent);
25488            rng = dom.createRng();
25489            rng.setStart(container, 0);
25490            rng.setEnd(container, 0);
25491            selection.setRng(rng);
25492          }
25493        });
25494      };
25495      var setGeckoEditingOptions = function () {
25496        var setOpts = function () {
25497          setEditorCommandState('StyleWithCSS', false);
25498          setEditorCommandState('enableInlineTableEditing', false);
25499          if (!getObjectResizing(editor)) {
25500            setEditorCommandState('enableObjectResizing', false);
25501          }
25502        };
25503        if (!isReadOnly(editor)) {
25504          editor.on('BeforeExecCommand mousedown', setOpts);
25505        }
25506      };
25507      var addBrAfterLastLinks = function () {
25508        var fixLinks = function () {
25509          each(dom.select('a'), function (node) {
25510            var parentNode = node.parentNode;
25511            var root = dom.getRoot();
25512            if (parentNode.lastChild === node) {
25513              while (parentNode && !dom.isBlock(parentNode)) {
25514                if (parentNode.parentNode.lastChild !== parentNode || parentNode === root) {
25515                  return;
25516                }
25517                parentNode = parentNode.parentNode;
25518              }
25519              dom.add(parentNode, 'br', { 'data-mce-bogus': 1 });
25520            }
25521          });
25522        };
25523        editor.on('SetContent ExecCommand', function (e) {
25524          if (e.type === 'setcontent' || e.command === 'mceInsertLink') {
25525            fixLinks();
25526          }
25527        });
25528      };
25529      var setDefaultBlockType = function () {
25530        if (getForcedRootBlock(editor)) {
25531          editor.on('init', function () {
25532            setEditorCommandState('DefaultParagraphSeparator', getForcedRootBlock(editor));
25533          });
25534        }
25535      };
25536      var normalizeSelection = function () {
25537        editor.on('keyup focusin mouseup', function (e) {
25538          if (!VK.modifierPressed(e)) {
25539            selection.normalize();
25540          }
25541        }, true);
25542      };
25543      var showBrokenImageIcon = function () {
25544        editor.contentStyles.push('img:-moz-broken {' + '-moz-force-broken-image-icon:1;' + 'min-width:24px;' + 'min-height:24px' + '}');
25545      };
25546      var restoreFocusOnKeyDown = function () {
25547        if (!editor.inline) {
25548          editor.on('keydown', function () {
25549            if (document.activeElement === document.body) {
25550              editor.getWin().focus();
25551            }
25552          });
25553        }
25554      };
25555      var bodyHeight = function () {
25556        if (!editor.inline) {
25557          editor.contentStyles.push('body {min-height: 150px}');
25558          editor.on('click', function (e) {
25559            var rng;
25560            if (e.target.nodeName === 'HTML') {
25561              if (Env.ie > 11) {
25562                editor.getBody().focus();
25563                return;
25564              }
25565              rng = editor.selection.getRng();
25566              editor.getBody().focus();
25567              editor.selection.setRng(rng);
25568              editor.selection.normalize();
25569              editor.nodeChanged();
25570            }
25571          });
25572        }
25573      };
25574      var blockCmdArrowNavigation = function () {
25575        if (Env.mac) {
25576          editor.on('keydown', function (e) {
25577            if (VK.metaKeyPressed(e) && !e.shiftKey && (e.keyCode === 37 || e.keyCode === 39)) {
25578              e.preventDefault();
25579              var selection_1 = editor.selection.getSel();
25580              selection_1.modify('move', e.keyCode === 37 ? 'backward' : 'forward', 'lineboundary');
25581            }
25582          });
25583        }
25584      };
25585      var disableAutoUrlDetect = function () {
25586        setEditorCommandState('AutoUrlDetect', false);
25587      };
25588      var tapLinksAndImages = function () {
25589        editor.on('click', function (e) {
25590          var elm = e.target;
25591          do {
25592            if (elm.tagName === 'A') {
25593              e.preventDefault();
25594              return;
25595            }
25596          } while (elm = elm.parentNode);
25597        });
25598        editor.contentStyles.push('.mce-content-body {-webkit-touch-callout: none}');
25599      };
25600      var blockFormSubmitInsideEditor = function () {
25601        editor.on('init', function () {
25602          editor.dom.bind(editor.getBody(), 'submit', function (e) {
25603            e.preventDefault();
25604          });
25605        });
25606      };
25607      var removeAppleInterchangeBrs = function () {
25608        parser.addNodeFilter('br', function (nodes) {
25609          var i = nodes.length;
25610          while (i--) {
25611            if (nodes[i].attr('class') === 'Apple-interchange-newline') {
25612              nodes[i].remove();
25613            }
25614          }
25615        });
25616      };
25617      var ieInternalDragAndDrop = function () {
25618        editor.on('dragstart', function (e) {
25619          setMceInternalContent(e);
25620        });
25621        editor.on('drop', function (e) {
25622          if (!isDefaultPrevented(e)) {
25623            var internalContent = getMceInternalContent(e);
25624            if (internalContent && internalContent.id !== editor.id) {
25625              e.preventDefault();
25626              var rng = fromPoint$1(e.x, e.y, editor.getDoc());
25627              selection.setRng(rng);
25628              insertClipboardContents(internalContent.html, true);
25629            }
25630          }
25631        });
25632      };
25633      var refreshContentEditable = function () {
25634      };
25635      var isHidden = function () {
25636        if (!isGecko || editor.removed) {
25637          return false;
25638        }
25639        var sel = editor.selection.getSel();
25640        return !sel || !sel.rangeCount || sel.rangeCount === 0;
25641      };
25642      removeBlockQuoteOnBackSpace();
25643      emptyEditorWhenDeleting();
25644      if (!Env.windowsPhone) {
25645        normalizeSelection();
25646      }
25647      if (isWebKit) {
25648        inputMethodFocus();
25649        selectControlElements();
25650        setDefaultBlockType();
25651        blockFormSubmitInsideEditor();
25652        disableBackspaceIntoATable();
25653        removeAppleInterchangeBrs();
25654        if (Env.iOS) {
25655          restoreFocusOnKeyDown();
25656          bodyHeight();
25657          tapLinksAndImages();
25658        } else {
25659          selectAll();
25660        }
25661      }
25662      if (Env.ie >= 11) {
25663        bodyHeight();
25664        disableBackspaceIntoATable();
25665      }
25666      if (Env.ie) {
25667        selectAll();
25668        disableAutoUrlDetect();
25669        ieInternalDragAndDrop();
25670      }
25671      if (isGecko) {
25672        removeHrOnBackspace();
25673        focusBody();
25674        removeStylesWhenDeletingAcrossBlockElements();
25675        setGeckoEditingOptions();
25676        addBrAfterLastLinks();
25677        showBrokenImageIcon();
25678        blockCmdArrowNavigation();
25679        disableBackspaceIntoATable();
25680      }
25681      return {
25682        refreshContentEditable: refreshContentEditable,
25683        isHidden: isHidden
25684      };
25685    };
25686
25687    var DOM$4 = DOMUtils$1.DOM;
25688    var appendStyle = function (editor, text) {
25689      var body = SugarElement.fromDom(editor.getBody());
25690      var container = getStyleContainer(getRootNode(body));
25691      var style = SugarElement.fromTag('style');
25692      set(style, 'type', 'text/css');
25693      append(style, SugarElement.fromText(text));
25694      append(container, style);
25695      editor.on('remove', function () {
25696        remove(style);
25697      });
25698    };
25699    var getRootName = function (editor) {
25700      return editor.inline ? editor.getElement().nodeName.toLowerCase() : undefined;
25701    };
25702    var removeUndefined = function (obj) {
25703      return filter$1(obj, function (v) {
25704        return isUndefined(v) === false;
25705      });
25706    };
25707    var mkParserSettings = function (editor) {
25708      var settings = editor.settings;
25709      var blobCache = editor.editorUpload.blobCache;
25710      return removeUndefined({
25711        allow_conditional_comments: settings.allow_conditional_comments,
25712        allow_html_data_urls: settings.allow_html_data_urls,
25713        allow_html_in_named_anchor: settings.allow_html_in_named_anchor,
25714        allow_script_urls: settings.allow_script_urls,
25715        allow_unsafe_link_target: settings.allow_unsafe_link_target,
25716        convert_fonts_to_spans: settings.convert_fonts_to_spans,
25717        fix_list_elements: settings.fix_list_elements,
25718        font_size_legacy_values: settings.font_size_legacy_values,
25719        forced_root_block: settings.forced_root_block,
25720        forced_root_block_attrs: settings.forced_root_block_attrs,
25721        padd_empty_with_br: settings.padd_empty_with_br,
25722        preserve_cdata: settings.preserve_cdata,
25723        remove_trailing_brs: settings.remove_trailing_brs,
25724        inline_styles: settings.inline_styles,
25725        root_name: getRootName(editor),
25726        validate: true,
25727        blob_cache: blobCache,
25728        images_dataimg_filter: settings.images_dataimg_filter
25729      });
25730    };
25731    var mkSerializerSettings = function (editor) {
25732      var settings = editor.settings;
25733      return __assign(__assign({}, mkParserSettings(editor)), removeUndefined({
25734        url_converter: settings.url_converter,
25735        url_converter_scope: settings.url_converter_scope,
25736        element_format: settings.element_format,
25737        entities: settings.entities,
25738        entity_encoding: settings.entity_encoding,
25739        indent: settings.indent,
25740        indent_after: settings.indent_after,
25741        indent_before: settings.indent_before,
25742        block_elements: settings.block_elements,
25743        boolean_attributes: settings.boolean_attributes,
25744        custom_elements: settings.custom_elements,
25745        extended_valid_elements: settings.extended_valid_elements,
25746        invalid_elements: settings.invalid_elements,
25747        invalid_styles: settings.invalid_styles,
25748        move_caret_before_on_enter_elements: settings.move_caret_before_on_enter_elements,
25749        non_empty_elements: settings.non_empty_elements,
25750        schema: settings.schema,
25751        self_closing_elements: settings.self_closing_elements,
25752        short_ended_elements: settings.short_ended_elements,
25753        special: settings.special,
25754        text_block_elements: settings.text_block_elements,
25755        text_inline_elements: settings.text_inline_elements,
25756        valid_children: settings.valid_children,
25757        valid_classes: settings.valid_classes,
25758        valid_elements: settings.valid_elements,
25759        valid_styles: settings.valid_styles,
25760        verify_html: settings.verify_html,
25761        whitespace_elements: settings.whitespace_elements
25762      }));
25763    };
25764    var createParser = function (editor) {
25765      var parser = DomParser(mkParserSettings(editor), editor.schema);
25766      parser.addAttributeFilter('src,href,style,tabindex', function (nodes, name) {
25767        var i = nodes.length, node, value;
25768        var dom = editor.dom;
25769        var internalName = 'data-mce-' + name;
25770        while (i--) {
25771          node = nodes[i];
25772          value = node.attr(name);
25773          if (value && !node.attr(internalName)) {
25774            if (value.indexOf('data:') === 0 || value.indexOf('blob:') === 0) {
25775              continue;
25776            }
25777            if (name === 'style') {
25778              value = dom.serializeStyle(dom.parseStyle(value), node.name);
25779              if (!value.length) {
25780                value = null;
25781              }
25782              node.attr(internalName, value);
25783              node.attr(name, value);
25784            } else if (name === 'tabindex') {
25785              node.attr(internalName, value);
25786              node.attr(name, null);
25787            } else {
25788              node.attr(internalName, editor.convertURL(value, name, node.name));
25789            }
25790          }
25791        }
25792      });
25793      parser.addNodeFilter('script', function (nodes) {
25794        var i = nodes.length;
25795        while (i--) {
25796          var node = nodes[i];
25797          var type = node.attr('type') || 'no/type';
25798          if (type.indexOf('mce-') !== 0) {
25799            node.attr('type', 'mce-' + type);
25800          }
25801        }
25802      });
25803      if (editor.settings.preserve_cdata) {
25804        parser.addNodeFilter('#cdata', function (nodes) {
25805          var i = nodes.length;
25806          while (i--) {
25807            var node = nodes[i];
25808            node.type = 8;
25809            node.name = '#comment';
25810            node.value = '[CDATA[' + editor.dom.encode(node.value) + ']]';
25811          }
25812        });
25813      }
25814      parser.addNodeFilter('p,h1,h2,h3,h4,h5,h6,div', function (nodes) {
25815        var i = nodes.length;
25816        var nonEmptyElements = editor.schema.getNonEmptyElements();
25817        while (i--) {
25818          var node = nodes[i];
25819          if (node.isEmpty(nonEmptyElements) && node.getAll('br').length === 0) {
25820            node.append(new AstNode('br', 1)).shortEnded = true;
25821          }
25822        }
25823      });
25824      return parser;
25825    };
25826    var autoFocus = function (editor) {
25827      if (editor.settings.auto_focus) {
25828        Delay.setEditorTimeout(editor, function () {
25829          var focusEditor;
25830          if (editor.settings.auto_focus === true) {
25831            focusEditor = editor;
25832          } else {
25833            focusEditor = editor.editorManager.get(editor.settings.auto_focus);
25834          }
25835          if (!focusEditor.destroyed) {
25836            focusEditor.focus();
25837          }
25838        }, 100);
25839      }
25840    };
25841    var moveSelectionToFirstCaretPosition = function (editor) {
25842      var root = editor.dom.getRoot();
25843      if (!editor.inline && (!hasAnyRanges(editor) || editor.selection.getStart(true) === root)) {
25844        firstPositionIn(root).each(function (pos) {
25845          var node = pos.getNode();
25846          var caretPos = isTable(node) ? firstPositionIn(node).getOr(pos) : pos;
25847          if (Env.browser.isIE()) {
25848            storeNative(editor, caretPos.toRange());
25849          } else {
25850            editor.selection.setRng(caretPos.toRange());
25851          }
25852        });
25853      }
25854    };
25855    var initEditor = function (editor) {
25856      editor.bindPendingEventDelegates();
25857      editor.initialized = true;
25858      fireInit(editor);
25859      editor.focus(true);
25860      moveSelectionToFirstCaretPosition(editor);
25861      editor.nodeChanged({ initial: true });
25862      editor.execCallback('init_instance_callback', editor);
25863      autoFocus(editor);
25864    };
25865    var getStyleSheetLoader = function (editor) {
25866      return editor.inline ? editor.ui.styleSheetLoader : editor.dom.styleSheetLoader;
25867    };
25868    var loadContentCss = function (editor, css) {
25869      var styleSheetLoader = getStyleSheetLoader(editor);
25870      var loaded = function () {
25871        editor.on('remove', function () {
25872          return styleSheetLoader.unloadAll(css);
25873        });
25874        initEditor(editor);
25875      };
25876      styleSheetLoader.loadAll(css, loaded, loaded);
25877    };
25878    var preInit = function (editor, rtcMode) {
25879      var settings = editor.settings, doc = editor.getDoc(), body = editor.getBody();
25880      if (!settings.browser_spellcheck && !settings.gecko_spellcheck) {
25881        doc.body.spellcheck = false;
25882        DOM$4.setAttrib(body, 'spellcheck', 'false');
25883      }
25884      editor.quirks = Quirks(editor);
25885      firePostRender(editor);
25886      var directionality = getDirectionality(editor);
25887      if (directionality !== undefined) {
25888        body.dir = directionality;
25889      }
25890      if (settings.protect) {
25891        editor.on('BeforeSetContent', function (e) {
25892          Tools.each(settings.protect, function (pattern) {
25893            e.content = e.content.replace(pattern, function (str) {
25894              return '<!--mce:protected ' + escape(str) + '-->';
25895            });
25896          });
25897        });
25898      }
25899      editor.on('SetContent', function () {
25900        editor.addVisual(editor.getBody());
25901      });
25902      if (rtcMode === false) {
25903        editor.load({
25904          initial: true,
25905          format: 'html'
25906        });
25907      }
25908      editor.startContent = editor.getContent({ format: 'raw' });
25909      editor.on('compositionstart compositionend', function (e) {
25910        editor.composing = e.type === 'compositionstart';
25911      });
25912      if (editor.contentStyles.length > 0) {
25913        var contentCssText_1 = '';
25914        Tools.each(editor.contentStyles, function (style) {
25915          contentCssText_1 += style + '\r\n';
25916        });
25917        editor.dom.addStyle(contentCssText_1);
25918      }
25919      loadContentCss(editor, editor.contentCSS);
25920      if (settings.content_style) {
25921        appendStyle(editor, settings.content_style);
25922      }
25923    };
25924    var initContentBody = function (editor, skipWrite) {
25925      var settings = editor.settings;
25926      var targetElm = editor.getElement();
25927      var doc = editor.getDoc();
25928      if (!settings.inline) {
25929        editor.getElement().style.visibility = editor.orgVisibility;
25930      }
25931      if (!skipWrite && !editor.inline) {
25932        doc.open();
25933        doc.write(editor.iframeHTML);
25934        doc.close();
25935      }
25936      if (editor.inline) {
25937        DOM$4.addClass(targetElm, 'mce-content-body');
25938        editor.contentDocument = doc = document;
25939        editor.contentWindow = window;
25940        editor.bodyElement = targetElm;
25941        editor.contentAreaContainer = targetElm;
25942      }
25943      var body = editor.getBody();
25944      body.disabled = true;
25945      editor.readonly = !!settings.readonly;
25946      if (!editor.readonly) {
25947        if (editor.inline && DOM$4.getStyle(body, 'position', true) === 'static') {
25948          body.style.position = 'relative';
25949        }
25950        body.contentEditable = editor.getParam('content_editable_state', true);
25951      }
25952      body.disabled = false;
25953      editor.editorUpload = EditorUpload(editor);
25954      editor.schema = Schema(settings);
25955      editor.dom = DOMUtils$1(doc, {
25956        keep_values: true,
25957        url_converter: editor.convertURL,
25958        url_converter_scope: editor,
25959        hex_colors: settings.force_hex_style_colors,
25960        update_styles: true,
25961        root_element: editor.inline ? editor.getBody() : null,
25962        collect: function () {
25963          return editor.inline;
25964        },
25965        schema: editor.schema,
25966        contentCssCors: shouldUseContentCssCors(editor),
25967        referrerPolicy: getReferrerPolicy(editor),
25968        onSetAttrib: function (e) {
25969          editor.fire('SetAttrib', e);
25970        }
25971      });
25972      editor.parser = createParser(editor);
25973      editor.serializer = DomSerializer(mkSerializerSettings(editor), editor);
25974      editor.selection = EditorSelection(editor.dom, editor.getWin(), editor.serializer, editor);
25975      editor.annotator = Annotator(editor);
25976      editor.formatter = Formatter(editor);
25977      editor.undoManager = UndoManager(editor);
25978      editor._nodeChangeDispatcher = new NodeChange(editor);
25979      editor._selectionOverrides = SelectionOverrides(editor);
25980      setup$9(editor);
25981      setup$j(editor);
25982      if (!isRtc(editor)) {
25983        setup$k(editor);
25984      }
25985      var caret = setup$i(editor);
25986      setup$8(editor, caret);
25987      setup$a(editor);
25988      setup$7(editor);
25989      firePreInit(editor);
25990      setup$4(editor).fold(function () {
25991        preInit(editor, false);
25992      }, function (loadingRtc) {
25993        editor.setProgressState(true);
25994        loadingRtc.then(function (rtcMode) {
25995          editor.setProgressState(false);
25996          preInit(editor, rtcMode);
25997        });
25998      });
25999    };
26000
26001    var DOM$5 = DOMUtils$1.DOM;
26002    var relaxDomain = function (editor, ifr) {
26003      if (document.domain !== window.location.hostname && Env.browser.isIE()) {
26004        var bodyUuid = uuid('mce');
26005        editor[bodyUuid] = function () {
26006          initContentBody(editor);
26007        };
26008        var domainRelaxUrl = 'javascript:(function(){' + 'document.open();document.domain="' + document.domain + '";' + 'var ed = window.parent.tinymce.get("' + editor.id + '");document.write(ed.iframeHTML);' + 'document.close();ed.' + bodyUuid + '(true);})()';
26009        DOM$5.setAttrib(ifr, 'src', domainRelaxUrl);
26010        return true;
26011      }
26012      return false;
26013    };
26014    var createIframeElement = function (id, title, height, customAttrs) {
26015      var iframe = SugarElement.fromTag('iframe');
26016      setAll(iframe, customAttrs);
26017      setAll(iframe, {
26018        id: id + '_ifr',
26019        frameBorder: '0',
26020        allowTransparency: 'true',
26021        title: title
26022      });
26023      add$3(iframe, 'tox-edit-area__iframe');
26024      return iframe;
26025    };
26026    var getIframeHtml = function (editor) {
26027      var iframeHTML = getDocType(editor) + '<html><head>';
26028      if (getDocumentBaseUrl(editor) !== editor.documentBaseUrl) {
26029        iframeHTML += '<base href="' + editor.documentBaseURI.getURI() + '" />';
26030      }
26031      iframeHTML += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';
26032      var bodyId = getBodyId(editor);
26033      var bodyClass = getBodyClass(editor);
26034      if (getContentSecurityPolicy(editor)) {
26035        iframeHTML += '<meta http-equiv="Content-Security-Policy" content="' + getContentSecurityPolicy(editor) + '" />';
26036      }
26037      iframeHTML += '</head><body id="' + bodyId + '" class="mce-content-body ' + bodyClass + '" data-id="' + editor.id + '"><br></body></html>';
26038      return iframeHTML;
26039    };
26040    var createIframe = function (editor, o) {
26041      var title = editor.editorManager.translate('Rich Text Area. Press ALT-0 for help.');
26042      var ifr = createIframeElement(editor.id, title, o.height, getIframeAttrs(editor)).dom;
26043      ifr.onload = function () {
26044        ifr.onload = null;
26045        editor.fire('load');
26046      };
26047      var isDomainRelaxed = relaxDomain(editor, ifr);
26048      editor.contentAreaContainer = o.iframeContainer;
26049      editor.iframeElement = ifr;
26050      editor.iframeHTML = getIframeHtml(editor);
26051      DOM$5.add(o.iframeContainer, ifr);
26052      return isDomainRelaxed;
26053    };
26054    var init$1 = function (editor, boxInfo) {
26055      var isDomainRelaxed = createIframe(editor, boxInfo);
26056      if (boxInfo.editorContainer) {
26057        DOM$5.get(boxInfo.editorContainer).style.display = editor.orgDisplay;
26058        editor.hidden = DOM$5.isHidden(boxInfo.editorContainer);
26059      }
26060      editor.getElement().style.display = 'none';
26061      DOM$5.setAttrib(editor.id, 'aria-hidden', 'true');
26062      if (!isDomainRelaxed) {
26063        initContentBody(editor);
26064      }
26065    };
26066
26067    var DOM$6 = DOMUtils$1.DOM;
26068    var initPlugin = function (editor, initializedPlugins, plugin) {
26069      var Plugin = PluginManager.get(plugin);
26070      var pluginUrl = PluginManager.urls[plugin] || editor.documentBaseUrl.replace(/\/$/, '');
26071      plugin = Tools.trim(plugin);
26072      if (Plugin && Tools.inArray(initializedPlugins, plugin) === -1) {
26073        Tools.each(PluginManager.dependencies(plugin), function (dep) {
26074          initPlugin(editor, initializedPlugins, dep);
26075        });
26076        if (editor.plugins[plugin]) {
26077          return;
26078        }
26079        try {
26080          var pluginInstance = new Plugin(editor, pluginUrl, editor.$);
26081          editor.plugins[plugin] = pluginInstance;
26082          if (pluginInstance.init) {
26083            pluginInstance.init(editor, pluginUrl);
26084            initializedPlugins.push(plugin);
26085          }
26086        } catch (e) {
26087          pluginInitError(editor, plugin, e);
26088        }
26089      }
26090    };
26091    var trimLegacyPrefix = function (name) {
26092      return name.replace(/^\-/, '');
26093    };
26094    var initPlugins = function (editor) {
26095      var initializedPlugins = [];
26096      Tools.each(getPlugins(editor).split(/[ ,]/), function (name) {
26097        initPlugin(editor, initializedPlugins, trimLegacyPrefix(name));
26098      });
26099    };
26100    var initIcons = function (editor) {
26101      var iconPackName = Tools.trim(getIconPackName(editor));
26102      var currentIcons = editor.ui.registry.getAll().icons;
26103      var loadIcons = __assign(__assign({}, IconManager.get('default').icons), IconManager.get(iconPackName).icons);
26104      each$1(loadIcons, function (svgData, icon) {
26105        if (!has(currentIcons, icon)) {
26106          editor.ui.registry.addIcon(icon, svgData);
26107        }
26108      });
26109    };
26110    var initTheme = function (editor) {
26111      var theme = getTheme(editor);
26112      if (isString(theme)) {
26113        editor.settings.theme = trimLegacyPrefix(theme);
26114        var Theme = ThemeManager.get(theme);
26115        editor.theme = new Theme(editor, ThemeManager.urls[theme]);
26116        if (editor.theme.init) {
26117          editor.theme.init(editor, ThemeManager.urls[theme] || editor.documentBaseUrl.replace(/\/$/, ''), editor.$);
26118        }
26119      } else {
26120        editor.theme = {};
26121      }
26122    };
26123    var renderFromLoadedTheme = function (editor) {
26124      return editor.theme.renderUI();
26125    };
26126    var renderFromThemeFunc = function (editor) {
26127      var elm = editor.getElement();
26128      var theme = getTheme(editor);
26129      var info = theme(editor, elm);
26130      if (info.editorContainer.nodeType) {
26131        info.editorContainer.id = info.editorContainer.id || editor.id + '_parent';
26132      }
26133      if (info.iframeContainer && info.iframeContainer.nodeType) {
26134        info.iframeContainer.id = info.iframeContainer.id || editor.id + '_iframecontainer';
26135      }
26136      info.height = info.iframeHeight ? info.iframeHeight : elm.offsetHeight;
26137      return info;
26138    };
26139    var createThemeFalseResult = function (element) {
26140      return {
26141        editorContainer: element,
26142        iframeContainer: element,
26143        api: {}
26144      };
26145    };
26146    var renderThemeFalseIframe = function (targetElement) {
26147      var iframeContainer = DOM$6.create('div');
26148      DOM$6.insertAfter(iframeContainer, targetElement);
26149      return createThemeFalseResult(iframeContainer);
26150    };
26151    var renderThemeFalse = function (editor) {
26152      var targetElement = editor.getElement();
26153      return editor.inline ? createThemeFalseResult(null) : renderThemeFalseIframe(targetElement);
26154    };
26155    var renderThemeUi = function (editor) {
26156      var elm = editor.getElement();
26157      editor.orgDisplay = elm.style.display;
26158      if (isString(getTheme(editor))) {
26159        return renderFromLoadedTheme(editor);
26160      } else if (isFunction(getTheme(editor))) {
26161        return renderFromThemeFunc(editor);
26162      } else {
26163        return renderThemeFalse(editor);
26164      }
26165    };
26166    var init$2 = function (editor) {
26167      editor.fire('ScriptsLoaded');
26168      initIcons(editor);
26169      initTheme(editor);
26170      initPlugins(editor);
26171      var renderInfo = renderThemeUi(editor);
26172      editor.ui = __assign(__assign({}, editor.ui), renderInfo.api);
26173      var boxInfo = {
26174        editorContainer: renderInfo.editorContainer,
26175        iframeContainer: renderInfo.iframeContainer
26176      };
26177      editor.editorContainer = boxInfo.editorContainer ? boxInfo.editorContainer : null;
26178      appendContentCssFromSettings(editor);
26179      if (editor.inline) {
26180        return initContentBody(editor);
26181      } else {
26182        return init$1(editor, boxInfo);
26183      }
26184    };
26185
26186    var DOM$7 = DOMUtils$1.DOM;
26187    var hasSkipLoadPrefix = function (name) {
26188      return name.charAt(0) === '-';
26189    };
26190    var loadLanguage = function (scriptLoader, editor) {
26191      var languageCode = getLanguageCode(editor);
26192      var languageUrl = getLanguageUrl(editor);
26193      if (I18n.hasCode(languageCode) === false && languageCode !== 'en') {
26194        var url_1 = languageUrl !== '' ? languageUrl : editor.editorManager.baseURL + '/langs/' + languageCode + '.js';
26195        scriptLoader.add(url_1, noop, undefined, function () {
26196          languageLoadError(editor, url_1, languageCode);
26197        });
26198      }
26199    };
26200    var loadTheme = function (scriptLoader, editor, suffix, callback) {
26201      var theme = getTheme(editor);
26202      if (isString(theme)) {
26203        if (!hasSkipLoadPrefix(theme) && !ThemeManager.urls.hasOwnProperty(theme)) {
26204          var themeUrl = getThemeUrl(editor);
26205          if (themeUrl) {
26206            ThemeManager.load(theme, editor.documentBaseURI.toAbsolute(themeUrl));
26207          } else {
26208            ThemeManager.load(theme, 'themes/' + theme + '/theme' + suffix + '.js');
26209          }
26210        }
26211        scriptLoader.loadQueue(function () {
26212          ThemeManager.waitFor(theme, callback);
26213        });
26214      } else {
26215        callback();
26216      }
26217    };
26218    var getIconsUrlMetaFromUrl = function (editor) {
26219      return Optional.from(getIconsUrl(editor)).filter(function (url) {
26220        return url.length > 0;
26221      }).map(function (url) {
26222        return {
26223          url: url,
26224          name: Optional.none()
26225        };
26226      });
26227    };
26228    var getIconsUrlMetaFromName = function (editor, name, suffix) {
26229      return Optional.from(name).filter(function (name) {
26230        return name.length > 0 && !IconManager.has(name);
26231      }).map(function (name) {
26232        return {
26233          url: editor.editorManager.baseURL + '/icons/' + name + '/icons' + suffix + '.js',
26234          name: Optional.some(name)
26235        };
26236      });
26237    };
26238    var loadIcons = function (scriptLoader, editor, suffix) {
26239      var defaultIconsUrl = getIconsUrlMetaFromName(editor, 'default', suffix);
26240      var customIconsUrl = getIconsUrlMetaFromUrl(editor).orThunk(function () {
26241        return getIconsUrlMetaFromName(editor, getIconPackName(editor), '');
26242      });
26243      each(cat([
26244        defaultIconsUrl,
26245        customIconsUrl
26246      ]), function (urlMeta) {
26247        scriptLoader.add(urlMeta.url, noop, undefined, function () {
26248          iconsLoadError(editor, urlMeta.url, urlMeta.name.getOrUndefined());
26249        });
26250      });
26251    };
26252    var loadPlugins = function (editor, suffix) {
26253      Tools.each(getExternalPlugins(editor), function (url, name) {
26254        PluginManager.load(name, url, noop, undefined, function () {
26255          pluginLoadError(editor, url, name);
26256        });
26257        editor.settings.plugins += ' ' + name;
26258      });
26259      Tools.each(getPlugins(editor).split(/[ ,]/), function (plugin) {
26260        plugin = Tools.trim(plugin);
26261        if (plugin && !PluginManager.urls[plugin]) {
26262          if (hasSkipLoadPrefix(plugin)) {
26263            plugin = plugin.substr(1, plugin.length);
26264            var dependencies = PluginManager.dependencies(plugin);
26265            Tools.each(dependencies, function (depPlugin) {
26266              var defaultSettings = {
26267                prefix: 'plugins/',
26268                resource: depPlugin,
26269                suffix: '/plugin' + suffix + '.js'
26270              };
26271              var dep = PluginManager.createUrl(defaultSettings, depPlugin);
26272              PluginManager.load(dep.resource, dep, noop, undefined, function () {
26273                pluginLoadError(editor, dep.prefix + dep.resource + dep.suffix, dep.resource);
26274              });
26275            });
26276          } else {
26277            var url_2 = {
26278              prefix: 'plugins/',
26279              resource: plugin,
26280              suffix: '/plugin' + suffix + '.js'
26281            };
26282            PluginManager.load(plugin, url_2, noop, undefined, function () {
26283              pluginLoadError(editor, url_2.prefix + url_2.resource + url_2.suffix, plugin);
26284            });
26285          }
26286        }
26287      });
26288    };
26289    var loadScripts = function (editor, suffix) {
26290      var scriptLoader = ScriptLoader.ScriptLoader;
26291      loadTheme(scriptLoader, editor, suffix, function () {
26292        loadLanguage(scriptLoader, editor);
26293        loadIcons(scriptLoader, editor, suffix);
26294        loadPlugins(editor, suffix);
26295        scriptLoader.loadQueue(function () {
26296          if (!editor.removed) {
26297            init$2(editor);
26298          }
26299        }, editor, function () {
26300          if (!editor.removed) {
26301            init$2(editor);
26302          }
26303        });
26304      });
26305    };
26306    var getStyleSheetLoader$1 = function (element, editor) {
26307      return instance.forElement(element, {
26308        contentCssCors: hasContentCssCors(editor),
26309        referrerPolicy: getReferrerPolicy(editor)
26310      });
26311    };
26312    var render = function (editor) {
26313      var id = editor.id;
26314      I18n.setCode(getLanguageCode(editor));
26315      var readyHandler = function () {
26316        DOM$7.unbind(window, 'ready', readyHandler);
26317        editor.render();
26318      };
26319      if (!EventUtils.Event.domLoaded) {
26320        DOM$7.bind(window, 'ready', readyHandler);
26321        return;
26322      }
26323      if (!editor.getElement()) {
26324        return;
26325      }
26326      if (!Env.contentEditable) {
26327        return;
26328      }
26329      var element = SugarElement.fromDom(editor.getElement());
26330      var snapshot = clone(element);
26331      editor.on('remove', function () {
26332        eachr(element.dom.attributes, function (attr) {
26333          return remove$1(element, attr.name);
26334        });
26335        setAll(element, snapshot);
26336      });
26337      editor.ui.styleSheetLoader = getStyleSheetLoader$1(element, editor);
26338      if (!isInline$1(editor)) {
26339        editor.orgVisibility = editor.getElement().style.visibility;
26340        editor.getElement().style.visibility = 'hidden';
26341      } else {
26342        editor.inline = true;
26343      }
26344      var form = editor.getElement().form || DOM$7.getParent(id, 'form');
26345      if (form) {
26346        editor.formElement = form;
26347        if (hasHiddenInput(editor) && !isTextareaOrInput(editor.getElement())) {
26348          DOM$7.insertAfter(DOM$7.create('input', {
26349            type: 'hidden',
26350            name: id
26351          }), id);
26352          editor.hasHiddenInput = true;
26353        }
26354        editor.formEventDelegate = function (e) {
26355          editor.fire(e.type, e);
26356        };
26357        DOM$7.bind(form, 'submit reset', editor.formEventDelegate);
26358        editor.on('reset', function () {
26359          editor.resetContent();
26360        });
26361        if (shouldPatchSubmit(editor) && !form.submit.nodeType && !form.submit.length && !form._mceOldSubmit) {
26362          form._mceOldSubmit = form.submit;
26363          form.submit = function () {
26364            editor.editorManager.triggerSave();
26365            editor.setDirty(false);
26366            return form._mceOldSubmit(form);
26367          };
26368        }
26369      }
26370      editor.windowManager = WindowManager(editor);
26371      editor.notificationManager = NotificationManager(editor);
26372      if (isEncodingXml(editor)) {
26373        editor.on('GetContent', function (e) {
26374          if (e.save) {
26375            e.content = DOM$7.encode(e.content);
26376          }
26377        });
26378      }
26379      if (shouldAddFormSubmitTrigger(editor)) {
26380        editor.on('submit', function () {
26381          if (editor.initialized) {
26382            editor.save();
26383          }
26384        });
26385      }
26386      if (shouldAddUnloadTrigger(editor)) {
26387        editor._beforeUnload = function () {
26388          if (editor.initialized && !editor.destroyed && !editor.isHidden()) {
26389            editor.save({
26390              format: 'raw',
26391              no_events: true,
26392              set_dirty: false
26393            });
26394          }
26395        };
26396        editor.editorManager.on('BeforeUnload', editor._beforeUnload);
26397      }
26398      editor.editorManager.add(editor);
26399      loadScripts(editor, editor.suffix);
26400    };
26401
26402    var ensureIsRoot = function (isRoot) {
26403      return isFunction(isRoot) ? isRoot : never;
26404    };
26405    var ancestor$3 = function (scope, transform, isRoot) {
26406      var element = scope.dom;
26407      var stop = ensureIsRoot(isRoot);
26408      while (element.parentNode) {
26409        element = element.parentNode;
26410        var el = SugarElement.fromDom(element);
26411        var transformed = transform(el);
26412        if (transformed.isSome()) {
26413          return transformed;
26414        } else if (stop(el)) {
26415          break;
26416        }
26417      }
26418      return Optional.none();
26419    };
26420    var closest$2 = function (scope, transform, isRoot) {
26421      var current = transform(scope);
26422      var stop = ensureIsRoot(isRoot);
26423      return current.orThunk(function () {
26424        return stop(scope) ? Optional.none() : ancestor$3(scope, transform, stop
26424);
26425      });
26426    };
26427
26428    var legacyPropNames = {
26429      'font-size': 'size',
26430      'font-family': 'face'
26431    };
26432    var getSpecifiedFontProp = function (propName, rootElm, elm) {
26433      var getProperty = function (elm) {
26434        return getRaw(elm, propName).orThunk(function () {
26435          if (name(elm) === 'font') {
26436            return get(legacyPropNames, propName).bind(function (legacyPropName) {
26437              return getOpt(elm, legacyPropName);
26438            });
26439          } else {
26440            return Optional.none();
26441          }
26442        });
26443      };
26444      var isRoot = function (elm) {
26445        return eq$2(SugarElement.fromDom(rootElm), elm);
26446      };
26447      return closest$2(SugarElement.fromDom(elm), function (elm) {
26448        return getProperty(elm);
26449      }, isRoot);
26450    };
26451    var normalizeFontFamily = function (fontFamily) {
26452      return fontFamily.replace(/[\'\"\\]/g, '').replace(/,\s+/g, ',');
26453    };
26454    var getComputedFontProp = function (propName, elm) {
26455      return Optional.from(DOMUtils$1.DOM.getStyle(elm, propName, true));
26456    };
26457    var getFontProp = function (propName) {
26458      return function (rootElm, elm) {
26459        return Optional.from(elm).map(SugarElement.fromDom).filter(isElement).bind(function (element) {
26460          return getSpecifiedFontProp(propName, rootElm, element.dom).or(getComputedFontProp(propName, element.dom));
26461        }).getOr('');
26462      };
26463    };
26464    var getFontSize = getFontProp('font-size');
26465    var getFontFamily = compose(normalizeFontFamily, getFontProp('font-family'));
26466
26467    var findFirstCaretElement = function (editor) {
26468      return firstPositionIn(editor.getBody()).map(function (caret) {
26469        var container = caret.container();
26470        return isText$1(container) ? container.parentNode : container;
26471      });
26472    };
26473    var getCaretElement = function (editor) {
26474      return Optional.from(editor.selection.getRng()).bind(function (rng) {
26475        var root = editor.getBody();
26476        var atStartOfNode = rng.startContainer === root && rng.startOffset === 0;
26477        return atStartOfNode ? Optional.none() : Optional.from(editor.selection.getStart(true));
26478      });
26479    };
26480    var mapRange = function (editor, mapper) {
26481      return getCaretElement(editor).orThunk(curry(findFirstCaretElement, editor)).map(SugarElement.fromDom).filter(isElement).map(mapper);
26482    };
26483
26484    var fromFontSizeNumber = function (editor, value) {
26485      if (/^[0-9.]+$/.test(value)) {
26486        var fontSizeNumber = parseInt(value, 10);
26487        if (fontSizeNumber >= 1 && fontSizeNumber <= 7) {
26488          var fontSizes = getFontStyleValues(editor);
26489          var fontClasses = getFontSizeClasses(editor);
26490          if (fontClasses) {
26491            return fontClasses[fontSizeNumber - 1] || value;
26492          } else {
26493            return fontSizes[fontSizeNumber - 1] || value;
26494          }
26495        } else {
26496          return value;
26497        }
26498      } else {
26499        return value;
26500      }
26501    };
26502    var normalizeFontNames = function (font) {
26503      var fonts = font.split(/\s*,\s*/);
26504      return map(fonts, function (font) {
26505        if (font.indexOf(' ') !== -1 && !(startsWith(font, '"') || startsWith(font, '\''))) {
26506          return '\'' + font + '\'';
26507        } else {
26508          return font;
26509        }
26510      }).join(',');
26511    };
26512    var fontNameAction = function (editor, value) {
26513      var font = fromFontSizeNumber(editor, value);
26514      editor.formatter.toggle('fontname', { value: normalizeFontNames(font) });
26515      editor.nodeChanged();
26516    };
26517    var fontNameQuery = function (editor) {
26518      return mapRange(editor, function (elm) {
26519        return getFontFamily(editor.getBody(), elm.dom);
26520      }).getOr('');
26521    };
26522    var fontSizeAction = function (editor, value) {
26523      editor.formatter.toggle('fontsize', { value: fromFontSizeNumber(editor, value) });
26524      editor.nodeChanged();
26525    };
26526    var fontSizeQuery = function (editor) {
26527      return mapRange(editor, function (elm) {
26528        return getFontSize(editor.getBody(), elm.dom);
26529      }).getOr('');
26530    };
26531
26532    var lineHeightQuery = function (editor) {
26533      return mapRange(editor, function (elm) {
26534        var root = SugarElement.fromDom(editor.getBody());
26535        var specifiedStyle = closest$2(elm, function (elm) {
26536          return getRaw(elm, 'line-height');
26537        }, curry(eq$2, root));
26538        var computedStyle = function () {
26539          var lineHeight = parseFloat(get$4(elm, 'line-height'));
26540          var fontSize = parseFloat(get$4(elm, 'font-size'));
26541          return String(lineHeight / fontSize);
26542        };
26543        return specifiedStyle.getOrThunk(computedStyle);
26544      }).getOr('');
26545    };
26546    var lineHeightAction = function (editor, lineHeight) {
26547      editor.undoManager.transact(function () {
26548        editor.formatter.toggle('lineheight', { value: String(lineHeight) });
26549        editor.nodeChanged();
26550      });
26551    };
26552
26553    var processValue = function (value) {
26554      var details;
26555      if (typeof value !== 'string') {
26556        details = Tools.extend({
26557          paste: value.paste,
26558          data: { paste: value.paste }
26559        }, value);
26560        return {
26561          content: value.content,
26562          details: details
26563        };
26564      }
26565      return {
26566        content: value,
26567        details: {}
26568      };
26569    };
26570    var insertAtCaret$1 = function (editor, value) {
26571      var result = processValue(value);
26572      insertContent(editor, result.content, result.details);
26573    };
26574
26575    var each$f = Tools.each;
26576    var map$3 = Tools.map, inArray$2 = Tools.inArray;
26577    var EditorCommands = function () {
26578      function EditorCommands(editor) {
26579        this.commands = {
26580          state: {},
26581          exec: {},
26582          value: {}
26583        };
26584        this.editor = editor;
26585        this.setupCommands(editor);
26586      }
26587      EditorCommands.prototype.execCommand = function (command, ui, value, args
26587) {
26588        var func, state = false;
26589        var self = this;
26590        if (self.editor.removed) {
26591          return;
26592        }
26593        if (!/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint)$/.test(command) && (!args || !args.skip_focus)) {
26594          self.editor.focus();
26595        } else {
26596          restore(self.editor);
26597        }
26598        args = self.editor.fire('BeforeExecCommand', {
26599          command: command,
26600          ui: ui,
26601          value: value
26602        });
26603        if (args.isDefaultPrevented()) {
26604          return false;
26605        }
26606        var customCommand = command.toLowerCase();
26607        if (func = self.commands.exec[customCommand]) {
26608          func(customCommand, ui, value);
26609          self.editor.fire('ExecCommand', {
26610            command: command,
26611            ui: ui,
26612            value: value
26613          });
26614          return true;
26615        }
26616        each$f(this.editor.plugins, function (p) {
26617          if (p.execCommand && p.execCommand(command, ui, value)) {
26618            self.editor.fire('ExecCommand', {
26619              command: command,
26620              ui: ui,
26621              value: value
26622            });
26623            state = true;
26624            return false;
26625          }
26626        });
26627        if (state) {
26628          return state;
26629        }
26630        if (self.editor.theme && self.editor.theme.execCommand && self.editor.theme.execCommand(command, ui, value)) {
26631          self.editor.fire('ExecCommand', {
26632            command: command,
26633            ui: ui,
26634            value: value
26635          });
26636          return true;
26637        }
26638        try {
26639          state = self.editor.getDoc().execCommand(command, ui, value);
26640        } catch (ex) {
26641        }
26642        if (state) {
26643          self.editor.fire('ExecCommand', {
26644            command: command,
26645            ui: ui,
26646            value: value
26647          });
26648          return true;
26649        }
26650        return false;
26651      };
26652      EditorCommands.prototype.queryCommandState = function (command) {
26653        var func;
26654        if (this.editor.quirks.isHidden() || this.editor.removed) {
26655          return;
26656        }
26657        command = command.toLowerCase();
26658        if (func = this.commands.state[command]) {
26659          return func(command);
26660        }
26661        try {
26662          return this.editor.getDoc().queryCommandState(command);
26663        } catch (ex) {
26664        }
26665        return false;
26666      };
26667      EditorCommands.prototype.queryCommandValue = function (command) {
26668        var func;
26669        if (this.editor.quirks.isHidden() || this.editor.removed) {
26670          return;
26671        }
26672        command = command.toLowerCase();
26673        if (func = this.commands.value[command]) {
26674          return func(command);
26675        }
26676        try {
26677          return this.editor.getDoc().queryCommandValue(command);
26678        } catch (ex) {
26679        }
26680      };
26681      EditorCommands.prototype.addCommands = function (commandList, type) {
26682        if (type === void 0) {
26683          type = 'exec';
26684        }
26685        var self = this;
26686        each$f(commandList, function (callback, command) {
26687          each$f(command.toLowerCase().split(','), function (command) {
26688            self.commands[type][command] = callback;
26689          });
26690        });
26691      };
26692      EditorCommands.prototype.addCommand = function (command, callback, scope) {
26693        var _this = this;
26694        command = command.toLowerCase();
26695        this.commands.exec[command] = function (command, ui, value, args) {
26696          return callback.call(scope || _this.editor, ui, value, args);
26697        };
26698      };
26699      EditorCommands.prototype.queryCommandSupported = function (command) {
26700        command = command.toLowerCase();
26701        if (this.commands.exec[command]) {
26702          return true;
26703        }
26704        try {
26705          return this.editor.getDoc().queryCommandSupported(command);
26706        } catch (ex) {
26707        }
26708        return false;
26709      };
26710      EditorCommands.prototype.addQueryStateHandler = function (command, callback, scope) {
26711        var _this = this;
26712        command = command.toLowerCase();
26713        this.commands.state[command] = function () {
26714          return callback.call(scope || _this.editor);
26715        };
26716      };
26717      EditorCommands.prototype.addQueryValueHandler = function (command, callback, scope) {
26718        var _this = this;
26719        command = command.toLowerCase();
26720        this.commands.value[command] = function () {
26721          return callback.call(scope || _this.editor);
26722        };
26723      };
26724      EditorCommands.prototype.hasCustomCommand = function (command) {
26725        command = command.toLowerCase();
26726        return !!this.commands.exec[command];
26727      };
26728      EditorCommands.prototype.execNativeCommand = function (command, ui, value) {
26729        if (ui === undefined) {
26730          ui = false;
26731        }
26732        if (value === undefined) {
26733          value = null;
26734        }
26735        return this.editor.getDoc().execCommand(command, ui, value);
26736      };
26737      EditorCommands.prototype.isFormatMatch = function (name) {
26738        return this.editor.formatter.match(name);
26739      };
26740      EditorCommands.prototype.toggleFormat = function (name, value) {
26741        this.editor.formatter.toggle(name, value ? { value: value } : undefined);
26742        this.editor.nodeChanged();
26743      };
26744      EditorCommands.prototype.storeSelection = function (type) {
26745        this.selectionBookmark = this.editor.selection.getBookmark(type);
26746      };
26747      EditorCommands.prototype.restoreSelection = function () {
26748        this.editor.selection.moveToBookmark(this.selectionBookmark);
26749      };
26750      EditorCommands.prototype.setupCommands = function (editor) {
26751        var self = this;
26752        this.addCommands({
26753          'mceResetDesignMode,mceBeginUndoLevel': function () {
26754          },
26755          'mceEndUndoLevel,mceAddUndoLevel': function () {
26756            editor.undoManager.add();
26757          },
26758          'Cut,Copy,Paste': function (command) {
26759            var doc = editor.getDoc();
26760            var failed;
26761            try {
26762              self.execNativeCommand(command);
26763            } catch (ex) {
26764              failed = true;
26765            }
26766            if (command === 'paste' && !doc.queryCommandEnabled(command)) {
26767              failed = true;
26768            }
26769            if (failed || !doc.queryCommandSupported(command)) {
26770              var msg = editor.translate('Your browser doesn\'t support direct access to the clipboard. ' + 'Please use the Ctrl+X/C/V keyboard shortcuts instead.');
26771              if (Env.mac) {
26772                msg = msg.replace(/Ctrl\+/g, '\u2318+');
26773              }
26774              editor.notificationManager.open({
26775                text: msg,
26776                type: 'error'
26777              });
26778            }
26779          },
26780          'unlink': function () {
26781            if (editor.selection.isCollapsed()) {
26782              var elm = editor.dom.getParent(editor.selection.getStart(), 'a');
26783              if (elm) {
26784                editor.dom.remove(elm, true);
26785              }
26786              return;
26787            }
26788            editor.formatter.remove('link');
26789          },
26790          'JustifyLeft,JustifyCenter,JustifyRight,JustifyFull,JustifyNone': function (command) {
26791            var align = command.substring(7);
26792            if (align === 'full') {
26793              align = 'justify';
26794            }
26795            each$f('left,center,right,justify'.split(','), function (name) {
26796              if (align !== name) {
26797                editor.formatter.remove('align' + name);
26798              }
26799            });
26800            if (align !== 'none') {
26801              self.toggleFormat('align' + align);
26802            }
26803          },
26804          'InsertUnorderedList,InsertOrderedList': function (command) {
26805            var listParent;
26806            self.execNativeCommand(command);
26807            var listElm = editor.dom.getParent(editor.selection.getNode(), 'ol,ul');
26808            if (listElm) {
26809              listParent = listElm.parentNode;
26810              if (/^(H[1-6]|P|ADDRESS|PRE)$/.test(listParent.nodeName)) {
26811                self.storeSelection();
26812                editor.dom.split(listParent, listElm);
26813                self.restoreSelection();
26814              }
26815            }
26816          },
26817          'Bold,Italic,Underline,Strikethrough,Superscript,Subscript': function (command) {
26818            self.toggleFormat(command);
26819          },
26820          'ForeColor,HiliteColor': function (command, ui, value) {
26821            self.toggleFormat(command, value);
26822          },
26823          'FontName': function (command, ui, value) {
26824            fontNameAction(editor, value);
26825          },
26826          'FontSize': function (command, ui, value) {
26827            fontSizeAction(editor, value);
26828          },
26829          'LineHeight': function (command, ui, value) {
26830            lineHeightAction(editor, value);
26831          },
26832          'RemoveFormat': function (command) {
26833            editor.formatter.remove(command);
26834          },
26835          'mceBlockQuote': function () {
26836            self.toggleFormat('blockquote');
26837          },
26838          'FormatBlock': function (command, ui, value) {
26839            return self.toggleFormat(value || 'p');
26840          },
26841          'mceCleanup': function () {
26842            var bookmark = editor.selection.getBookmark();
26843            editor.setContent(editor.getContent());
26844            editor.selection.moveToBookmark(bookmark);
26845          },
26846          'mceRemoveNode': function (command, ui, value) {
26847            var node = value || editor.selection.getNode();
26848            if (node !== editor.getBody()) {
26849              self.storeSelection();
26850              editor.dom.remove(node, true);
26851              self.restoreSelection();
26852            }
26853          },
26854          'mceSelectNodeDepth': function (command, ui, value) {
26855            var counter = 0;
26856            editor.dom.getParent(editor.selection.getNode(), function (node) {
26857              if (node.nodeType === 1 && counter++ === value) {
26858                editor.selection.select(node);
26859                return false;
26860              }
26861            }, editor.getBody());
26862          },
26863          'mceSelectNode': function (command, ui, value) {
26864            editor.selection.select(value);
26865          },
26866          'mceInsertContent': function (command, ui, value) {
26867            insertAtCaret$1(editor, value);
26868          },
26869          'mceInsertRawHTML': function (command, ui, value) {
26870            editor.selection.setContent('tiny_mce_marker');
26871            var content = editor.getContent();
26872            editor.setContent(content.replace(/tiny_mce_marker/g, function () {
26873              return value;
26874            }));
26875          },
26876          'mceInsertNewLine': function (command, ui, value) {
26877            insert$3(editor, value);
26878          },
26879          'mceToggleFormat': function (command, ui, value) {
26880            self.toggleFormat(value);
26881          },
26882          'mceSetContent': function (command, ui, value) {
26883            editor.setContent(value);
26884          },
26885          'Indent,Outdent': function (command) {
26886            handle(editor, command);
26887          },
26888          'mceRepaint': function () {
26889          },
26890          'InsertHorizontalRule': function () {
26891            editor.execCommand('mceInsertContent', false, '<hr />');
26892          },
26893          'mceToggleVisualAid': function () {
26894            editor.hasVisual = !editor.hasVisual;
26895            editor.addVisual();
26896          },
26897          'mceReplaceContent': function (command, ui, value) {
26898            editor.execCommand('mceInsertContent', false, value.replace(/\{\$selection\}/g, editor.selection.getContent({ format: 'text' })));
26899          },
26900          'mceInsertLink': function (command, ui, value) {
26901            if (typeof value === 'string') {
26902              value = { href: value };
26903            }
26904            var anchor = editor.dom.getParent(editor.selection.getNode(), 'a');
26905            value.href = value.href.replace(/ /g, '%20');
26906            if (!anchor || !value.href) {
26907              editor.formatter.remove('link');
26908            }
26909            if (value.href) {
26910              editor.formatter.apply('link', value, anchor);
26911            }
26912          },
26913          'selectAll': function () {
26914            var editingHost = editor.dom.getParent(editor.selection.getStart(), isContentEditableTrue);
26915            if (editingHost) {
26916              var rng = editor.dom.createRng();
26917              rng.selectNodeContents(editingHost);
26918              editor.selection.setRng(rng);
26919            }
26920          },
26921          'mceNewDocument': function () {
26922            editor.setContent('');
26923          },
26924          'InsertLineBreak': function (command, ui, value) {
26925            insert$2(editor, value);
26926            return true;
26927          }
26928        });
26929        var alignStates = function (name) {
26930          return function () {
26931            var selection = editor.selection;
26932            var nodes = selection.isCollapsed() ? [editor.dom.getParent(selection.getNode(), editor.dom.isBlock)] : selection.getSelectedBlocks();
26933            var matches = map$3(nodes, function (node) {
26934              return !!editor.formatter.matchNode(node, name);
26935            });
26936            return inArray$2(matches, true) !== -1;
26937          };
26938        };
26939        self.addCommands({
26940          'JustifyLeft': alignStates('alignleft'),
26941          'JustifyCenter': alignStates('aligncenter'),
26942          'JustifyRight': alignStates('alignright'),
26943          'JustifyFull': alignStates('alignjustify'),
26944          'Bold,Italic,Underline,Strikethrough,Superscript,Subscript': function (command) {
26945            return self.isFormatMatch(command);
26946          },
26947          'mceBlockQuote': function () {
26948            return self.isFormatMatch('blockquote');
26949          },
26950          'Outdent': function () {
26951            return canOutdent(editor);
26952          },
26953          'InsertUnorderedList,InsertOrderedList': function (command) {
26954            var list = editor.dom.getParent(editor.selection.getNode(), 'ul,ol');
26955            return list && (command === 'insertunorderedlist' && list.tagName === 'UL' || command === 'insertorderedlist' && list.tagName === 'OL');
26956          }
26957        }, 'state');
26958        self.addCommands({
26959          Undo: function () {
26960            editor.undoManager.undo();
26961          },
26962          Redo: function () {
26963            editor.undoManager.redo();
26964          }
26965        });
26966        self.addQueryValueHandler('FontName', function () {
26967          return fontNameQuery(editor);
26968        }, this);
26969        self.addQueryValueHandler('FontSize', function () {
26970          return fontSizeQuery(editor);
26971        }, this);
26972        self.addQueryValueHandler('LineHeight', function () {
26973          return lineHeightQuery(editor);
26974        }, this);
26975      };
26976      return EditorCommands;
26977    }();
26978
26979    var internalContentEditableAttr = 'data-mce-contenteditable';
26980    var toggleClass = function (elm, cls, state) {
26981      if (has$2(elm, cls) && state === false) {
26982        remove$4(elm, cls);
26983      } else if (state) {
26984        add$3(elm, cls);
26985      }
26986    };
26987    var setEditorCommandState = function (editor, cmd, state) {
26988      try {
26989        editor.getDoc().execCommand(cmd, false, String(state));
26990      } catch (ex) {
26991      }
26992    };
26993    var setContentEditable = function (elm, state) {
26994      elm.dom.contentEditable = state ? 'true' : 'false';
26995    };
26996    var switchOffContentEditableTrue = function (elm) {
26997      each(descendants$1(elm, '*[contenteditable="true"]'), function (elm) {
26998        set(elm, internalContentEditableAttr, 'true');
26999        setContentEditable(elm, false);
27000      });
27001    };
27002    var switchOnContentEditableTrue = function (elm) {
27003      each(descendants$1(elm, '*[' + internalContentEditableAttr + '="true"]'), function (elm) {
27004        remove$1(elm, internalContentEditableAttr);
27005        setContentEditable(elm, true);
27006      });
27007    };
27008    var removeFakeSelection = function (editor) {
27009      Optional.from(editor.selection.getNode()).each(function (elm) {
27010        elm.removeAttribute('data-mce-selected');
27011      });
27012    };
27013    var restoreFakeSelection = function (editor) {
27014      editor.selection.setRng(editor.selection.getRng());
27015    };
27016    var toggleReadOnly = function (editor, state) {
27017      var body = SugarElement.fromDom(editor.getBody());
27018      toggleClass(body, 'mce-content-readonly', state);
27019      if (state) {
27020        editor.selection.controlSelection.hideResizeRect();
27021        editor._selectionOverrides.hideFakeCaret();
27022        removeFakeSelection(editor);
27023        editor.readonly = true;
27024        setContentEditable(body, false);
27025        switchOffContentEditableTrue(body);
27026      } else {
27027        editor.readonly = false;
27028        setContentEditable(body, true);
27029        switchOnContentEditableTrue(body);
27030        setEditorCommandState(editor, 'StyleWithCSS', false);
27031        setEditorCommandState(editor, 'enableInlineTableEditing', false);
27032        setEditorCommandState(editor, 'enableObjectResizing', false);
27033        if (hasEditorOrUiFocus(editor)) {
27034          editor.focus();
27035        }
27036        restoreFakeSelection(editor);
27037        editor.nodeChanged();
27038      }
27039    };
27040    var isReadOnly$1 = function (editor) {
27041      return editor.readonly;
27042    };
27043    var registerFilters = function (editor) {
27044      editor.parser.addAttributeFilter('contenteditable', function (nodes) {
27045        if (isReadOnly$1(editor)) {
27046          each(nodes, function (node) {
27047            node.attr(internalContentEditableAttr, node.attr('contenteditable'));
27048            node.attr('contenteditable', 'false');
27049          });
27050        }
27051      });
27052      editor.serializer.addAttributeFilter(internalContentEditableAttr, function (nodes) {
27053        if (isReadOnly$1(editor)) {
27054          each(nodes, function (node) {
27055            node.attr('contenteditable', node.attr(internalContentEditableAttr));
27056          });
27057        }
27058      });
27059      editor.serializer.addTempAttr(internalContentEditableAttr);
27060    };
27061    var registerReadOnlyContentFilters = function (editor) {
27062      if (editor.serializer) {
27063        registerFilters(editor);
27064      } else {
27065        editor.on('PreInit', function () {
27066          registerFilters(editor);
27067        });
27068      }
27069    };
27070    var isClickEvent = function (e) {
27071      return e.type === 'click';
27072    };
27073    var isInAnchor = function (editor, target) {
27074      return editor.dom.getParent(target, 'a') !== null;
27075    };
27076    var preventReadOnlyEvents = function (editor, e) {
27077      var target = e.target;
27078      if (isClickEvent(e) && !VK.metaKeyPressed(e) && isInAnchor(editor, target)) {
27079        e.preventDefault();
27080      }
27081    };
27082    var registerReadOnlySelectionBlockers = function (editor) {
27083      editor.on('ShowCaret', function (e) {
27084        if (isReadOnly$1(editor)) {
27085          e.preventDefault();
27086        }
27087      });
27088      editor.on('ObjectSelected', function (e) {
27089        if (isReadOnly$1(editor)) {
27090          e.preventDefault();
27091        }
27092      });
27093    };
27094
27095    var nativeEvents = Tools.makeMap('focus blur focusin focusout click dblclick mousedown mouseup mousemove mouseover beforepaste paste cut copy selectionchange ' + 'mouseout mouseenter mouseleave wheel keydown keypress keyup input beforeinput contextmenu dragstart dragend dragover ' + 'draggesture dragdrop drop drag submit ' + 'compositionstart compositionend compositionupdate touchstart touchmove touchend touchcancel', ' ');
27096    var EventDispatcher = function () {
27097      function EventDispatcher(settings) {
27098        this.bindings = {};
27099        this.settings = settings || {};
27100        this.scope = this.settings.scope || this;
27101        this.toggleEvent = this.settings.toggleEvent || never;
27102      }
27103      EventDispatcher.isNative = function (name) {
27104        return !!nativeEvents[name.toLowerCase()];
27105      };
27106      EventDispatcher.prototype.fire = function (nameIn, argsIn) {
27107        var name = nameIn.toLowerCase();
27108        var args = argsIn || {};
27109        args.type = name;
27110        if (!args.target) {
27111          args.target = this.scope;
27112        }
27113        if (!args.preventDefault) {
27114          args.preventDefault = function () {
27115            args.isDefaultPrevented = always;
27116          };
27117          args.stopPropagation = function () {
27118            args.isPropagationStopped = always;
27119          };
27120          args.stopImmediatePropagation = function () {
27121            args.isImmediatePropagationStopped = always;
27122          };
27123          args.isDefaultPrevented = never;
27124          args.isPropagationStopped = never;
27125          args.isImmediatePropagationStopped = never;
27126        }
27127        if (this.settings.beforeFire) {
27128          this.settings.beforeFire(args);
27129        }
27130        var handlers = this.bindings[name];
27131        if (handlers) {
27132          for (var i = 0, l = handlers.length; i < l; i++) {
27133            var callback = handlers[i];
27134            if (callback.once) {
27135              this.off(name, callback.func);
27136            }
27137            if (args.isImmediatePropagationStopped()) {
27138              args.stopPropagation();
27139              return args;
27140            }
27141            if (callback.func.call(this.scope, args) === false) {
27142              args.preventDefault();
27143              return args;
27144            }
27145          }
27146        }
27147        return args;
27148      };
27149      EventDispatcher.prototype.on = function (name, callback, prepend, extra) {
27150        if (callback === false) {
27151          callback = never;
27152        }
27153        if (callback) {
27154          var wrappedCallback = { func: callback };
27155          if (extra) {
27156            Tools.extend(wrappedCallback, extra);
27157          }
27158          var names = name.toLowerCase().split(' ');
27159          var i = names.length;
27160          while (i--) {
27161            var currentName = names[i];
27162            var handlers = this.bindings[currentName];
27163            if (!handlers) {
27164              handlers = this.bindings[currentName] = [];
27165              this.toggleEvent(currentName, true);
27166            }
27167            if (prepend) {
27168              handlers.unshift(wrappedCallback);
27169            } else {
27170              handlers.push(wrappedCallback);
27171            }
27172          }
27173        }
27174        return this;
27175      };
27176      EventDispatcher.prototype.off = function (name, callback) {
27177        var _this = this;
27178        if (name) {
27179          var names = name.toLowerCase().split(' ');
27180          var i = names.length;
27181          while (i--) {
27182            var currentName = names[i];
27183            var handlers = this.bindings[currentName];
27184            if (!currentName) {
27185              each$1(this.bindings, function (_value, bindingName) {
27186                _this.toggleEvent(bindingName, false);
27187                delete _this.bindings[bindingName];
27188              });
27189              return this;
27190            }
27191            if (handlers) {
27192              if (!callback) {
27193                handlers.length = 0;
27194              } else {
27195                var hi = handlers.length;
27196                while (hi--) {
27197                  if (handlers[hi].func === callback) {
27198                    handlers = handlers.slice(0, hi).concat(handlers.slice(hi + 1));
27199                    this.bindings[currentName] = handlers;
27200                  }
27201                }
27202              }
27203              if (!handlers.length) {
27204                this.toggleEvent(name, false);
27205                delete this.bindings[currentName];
27206              }
27207            }
27208          }
27209        } else {
27210          each$1(this.bindings, function (_value, name) {
27211            _this.toggleEvent(name, false);
27212          });
27213          this.bindings = {};
27214        }
27215        return this;
27216      };
27217      EventDispatcher.prototype.once = function (name, callback, prepend) {
27218        return this.on(name, callback, prepend, { once: true });
27219      };
27220      EventDispatcher.prototype.has = function (name) {
27221        name = name.toLowerCase();
27222        return !(!this.bindings[name] || this.bindings[name].length === 0);
27223      };
27224      return EventDispatcher;
27225    }();
27226
27227    var getEventDispatcher = function (obj) {
27228      if (!obj._eventDispatcher) {
27229        obj._eventDispatcher = new EventDispatcher({
27230          scope: obj,
27231          toggleEvent: function (name, state) {
27232            if (EventDispatcher.isNative(name) && obj.toggleNativeEvent) {
27233              obj.toggleNativeEvent(name, state);
27234            }
27235          }
27236        });
27237      }
27238      return obj._eventDispatcher;
27239    };
27240    var Observable = {
27241      fire: function (name, args, bubble) {
27242        var self = this;
27243        if (self.removed && name !== 'remove' && name !== 'detach') {
27244          return args;
27245        }
27246        var dispatcherArgs = getEventDispatcher(self).fire(name, args);
27247        if (bubble !== false && self.parent) {
27248          var parent_1 = self.parent();
27249          while (parent_1 && !dispatcherArgs.isPropagationStopped()) {
27250            parent_1.fire(name, dispatcherArgs, false);
27251            parent_1 = parent_1.parent();
27252          }
27253        }
27254        return dispatcherArgs;
27255      },
27256      on: function (name, callback, prepend) {
27257        return getEventDispatcher(this).on(name, callback, prepend);
27258      },
27259      off: function (name, callback) {
27260        return getEventDispatcher(this).off(name, callback);
27261      },
27262      once: function (name, callback) {
27263        return getEventDispatcher(this).once(name, callback);
27264      },
27265      hasEventListeners: function (name) {
27266        return getEventDispatcher(this).has(name);
27267      }
27268    };
27269
27270    var DOM$8 = DOMUtils$1.DOM;
27271    var customEventRootDelegates;
27272    var getEventTarget = function (editor, eventName) {
27273      if (eventName === 'selectionchange') {
27274        return editor.getDoc();
27275      }
27276      if (!editor.inline && /^mouse|touch|click|contextmenu|drop|dragover|dragend/.test(eventName)) {
27277        return editor.getDoc().documentElement;
27278      }
27279      var eventRoot = getEventRoot(editor);
27280      if (eventRoot) {
27281        if (!editor.eventRoot) {
27282          editor.eventRoot = DOM$8.select(eventRoot)[0];
27283        }
27284        return editor.eventRoot;
27285      }
27286      return editor.getBody();
27287    };
27288    var isListening = function (editor) {
27289      return !editor.hidden && !isReadOnly$1(editor);
27290    };
27291    var fireEvent = function (editor, eventName, e) {
27292      if (isListening(editor)) {
27293        editor.fire(eventName, e);
27294      } else if (isReadOnly$1(editor)) {
27295        preventReadOnlyEvents(editor, e);
27296      }
27297    };
27298    var bindEventDelegate = function (editor, eventName) {
27299      var delegate;
27300      if (!editor.delegates) {
27301        editor.delegates = {};
27302      }
27303      if (editor.delegates[eventName] || editor.removed) {
27304        return;
27305      }
27306      var eventRootElm = getEventTarget(editor, eventName);
27307      if (getEventRoot(editor)) {
27308        if (!customEventRootDelegates) {
27309          customEventRootDelegates = {};
27310          editor.editorManager.on('removeEditor', function () {
27311            if (!editor.editorManager.activeEditor) {
27312              if (customEventRootDelegates) {
27313                each$1(customEventRootDelegates, function (_value, name) {
27314                  editor.dom.unbind(getEventTarget(editor, name));
27315                });
27316                customEventRootDelegates = null;
27317              }
27318            }
27319          });
27320        }
27321        if (customEventRootDelegates[eventName]) {
27322          return;
27323        }
27324        delegate = function (e) {
27325          var target = e.target;
27326          var editors = editor.editorManager.get();
27327          var i = editors.length;
27328          while (i--) {
27329            var body = editors[i].getBody();
27330            if (body === target || DOM$8.isChildOf(target, body)) {
27331              fireEvent(editors[i], eventName, e);
27332            }
27333          }
27334        };
27335        customEventRootDelegates[eventName] = delegate;
27336        DOM$8.bind(eventRootElm, eventName, delegate);
27337      } else {
27338        delegate = function (e) {
27339          fireEvent(editor, eventName, e);
27340        };
27341        DOM$8.bind(eventRootElm, eventName, delegate);
27342        editor.delegates[eventName] = delegate;
27343      }
27344    };
27345    var EditorObservable = __assign(__assign({}, Observable), {
27346      bindPendingEventDelegates: function () {
27347        var self = this;
27348        Tools.each(self._pendingNativeEvents, function (name) {
27349          bindEventDelegate(self, name);
27350        });
27351      },
27352      toggleNativeEvent: function (name, state) {
27353        var self = this;
27354        if (name === 'focus' || name === 'blur') {
27355          return;
27356        }
27357        if (state) {
27358          if (self.initialized) {
27359            bindEventDelegate(self, name);
27360          } else {
27361            if (!self._pendingNativeEvents) {
27362              self._pendingNativeEvents = [name];
27363            } else {
27364              self._pendingNativeEvents.push(name);
27365            }
27366          }
27367        } else if (self.initialized) {
27368          self.dom.unbind(getEventTarget(self, name), name, self.delegates[name]);
27369          delete self.delegates[name];
27370        }
27371      },
27372      unbindAllNativeEvents: function () {
27373        var self = this;
27374        var body = self.getBody();
27375        var dom = self.dom;
27376        if (self.delegates) {
27377          each$1(self.delegates, function (value, name) {
27378            self.dom.unbind(getEventTarget(self, name), name, value);
27379          });
27380          delete self.delegates;
27381        }
27382        if (!self.inline && body && dom) {
27383          body.onload = null;
27384          dom.unbind(self.getWin());
27385          dom.unbind(self.getDoc());
27386        }
27387        if (dom) {
27388          dom.unbind(body);
27389          dom.unbind(self.getContainer());
27390        }
27391      }
27392    });
27393
27394    var defaultModes = [
27395      'design',
27396      'readonly'
27397    ];
27398    var switchToMode = function (editor, activeMode, availableModes, mode) {
27399      var oldMode = availableModes[activeMode.get()];
27400      var newMode = availableModes[mode];
27401      try {
27402        newMode.activate();
27403      } catch (e) {
27404        console.error('problem while activating editor mode ' + mode + ':', e);
27405        return;
27406      }
27407      oldMode.deactivate();
27408      if (oldMode.editorReadOnly !== newMode.editorReadOnly) {
27409        toggleReadOnly(editor, newMode.editorReadOnly);
27410      }
27411      activeMode.set(mode);
27412      fireSwitchMode(editor, mode);
27413    };
27414    var setMode = function (editor, availableModes, activeMode, mode) {
27415      if (mode === activeMode.get()) {
27416        return;
27417      } else if (!has(availableModes, mode)) {
27418        throw new Error('Editor mode \'' + mode + '\' is invalid');
27419      }
27420      if (editor.initialized) {
27421        switchToMode(editor, activeMode, availableModes, mode);
27422      } else {
27423        editor.on('init', function () {
27424          return switchToMode(editor, activeMode, availableModes, mode);
27425        });
27426      }
27427    };
27428    var registerMode = function (availableModes, mode, api) {
27429      var _a;
27430      if (contains(defaultModes, mode)) {
27431        throw new Error('Cannot override default mode ' + mode);
27432      }
27433      return __assign(__assign({}, availableModes), (_a = {}, _a[mode] = __assign(__assign({}, api), {
27434        deactivate: function () {
27435          try {
27436            api.deactivate();
27437          } catch (e) {
27438            console.error('problem while deactivating editor mode ' + mode + ':', e);
27439          }
27440        }
27441      }), _a));
27442    };
27443
27444    var create$5 = function (editor) {
27445      var activeMode = Cell('design');
27446      var availableModes = Cell({
27447        design: {
27448          activate: noop,
27449          deactivate: noop,
27450          editorReadOnly: false
27451        },
27452        readonly: {
27453          activate: noop,
27454          deactivate: noop,
27455          editorReadOnly: true
27456        }
27457      });
27458      registerReadOnlyContentFilters(editor);
27459      registerReadOnlySelectionBlockers(editor);
27460      return {
27461        isReadOnly: function () {
27462          return isReadOnly$1(editor);
27463        },
27464        set: function (mode) {
27465          return setMode(editor, availableModes.get(), activeMode, mode);
27466        },
27467        get: function () {
27468          return activeMode.get();
27469        },
27470        register: function (mode, api) {
27471          availableModes.set(registerMode(availableModes.get(), mode, api));
27472        }
27473      };
27474    };
27475
27476    var each$g = Tools.each, explode$3 = Tools.explode;
27477    var keyCodeLookup = {
27478      f1: 112,
27479      f2: 113,
27480      f3: 114,
27481      f4: 115,
27482      f5: 116,
27483      f6: 117,
27484      f7: 118,
27485      f8: 119,
27486      f9: 120,
27487      f10: 121,
27488      f11: 122,
27489      f12: 123
27490    };
27491    var modifierNames = Tools.makeMap('alt,ctrl,shift,meta,access');
27492    var Shortcuts = function () {
27493      function Shortcuts(editor) {
27494        this.shortcuts = {};
27495        this.pendingPatterns = [];
27496        this.editor = editor;
27497        var self = this;
27498        editor.on('keyup keypress keydown', function (e) {
27499          if ((self.hasModifier(e) || self.isFunctionKey(e)) && !e.isDefaultPrevented()) {
27500            each$g(self.shortcuts, function (shortcut) {
27501              if (self.matchShortcut(e, shortcut)) {
27502                self.pendingPatterns = shortcut.subpatterns.slice(0);
27503                if (e.type === 'keydown') {
27504                  self.executeShortcutAction(shortcut);
27505                }
27506                return true;
27507              }
27508            });
27509            if (self.matchShortcut(e, self.pendingPatterns[0])) {
27510              if (self.pendingPatterns.length === 1) {
27511                if (e.type === 'keydown') {
27512                  self.executeShortcutAction(self.pendingPatterns[0]);
27513                }
27514              }
27515              self.pendingPatterns.shift();
27516            }
27517          }
27518        });
27519      }
27520      Shortcuts.prototype.add = function (pattern, desc, cmdFunc, scope) {
27521        var self = this;
27522        var func = self.normalizeCommandFunc(cmdFunc);
27523        each$g(explode$3(Tools.trim(pattern)), function (pattern) {
27524          var shortcut = self.createShortcut(pattern, desc, func, scope);
27525          self.shortcuts[shortcut.id] = shortcut;
27526        });
27527        return true;
27528      };
27529      Shortcuts.prototype.remove = function (pattern) {
27530        var shortcut = this.createShortcut(pattern);
27531        if (this.shortcuts[shortcut.id]) {
27532          delete this.shortcuts[shortcut.id];
27533          return true;
27534        }
27535        return false;
27536      };
27537      Shortcuts.prototype.normalizeCommandFunc = function (cmdFunc) {
27538        var self = this;
27539        var cmd = cmdFunc;
27540        if (typeof cmd === 'string') {
27541          return function () {
27542            self.editor.execCommand(cmd, false, null);
27543          };
27544        } else if (Tools.isArray(cmd)) {
27545          return function () {
27546            self.editor.execCommand(cmd[0], cmd[1], cmd[2]);
27547          };
27548        } else {
27549          return cmd;
27550        }
27551      };
27552      Shortcuts.prototype.parseShortcut = function (pattern) {
27553        var key;
27554        var shortcut = {};
27555        each$g(explode$3(pattern.toLowerCase(), '+'), function (value) {
27556          if (value in modifierNames) {
27557            shortcut[value] = true;
27558          } else {
27559            if (/^[0-9]{2,}$/.test(value)) {
27560              shortcut.keyCode = parseInt(value, 10);
27561            } else {
27562              shortcut.charCode = value.charCodeAt(0);
27563              shortcut.keyCode = keyCodeLookup[value] || value.toUpperCase().charCodeAt(0);
27564            }
27565          }
27566        });
27567        var id = [shortcut.keyCode];
27568        for (key in modifierNames) {
27569          if (shortcut[key]) {
27570            id.push(key);
27571          } else {
27572            shortcut[key] = false;
27573          }
27574        }
27575        shortcut.id = id.join(',');
27576        if (shortcut.access) {
27577          shortcut.alt = true;
27578          if (Env.mac) {
27579            shortcut.ctrl = true;
27580          } else {
27581            shortcut.shift = true;
27582          }
27583        }
27584        if (shortcut.meta) {
27585          if (Env.mac) {
27586            shortcut.meta = true;
27587          } else {
27588            shortcut.ctrl = true;
27589            shortcut.meta = false;
27590          }
27591        }
27592        return shortcut;
27593      };
27594      Shortcuts.prototype.createShortcut = function (pattern, desc, cmdFunc, scope) {
27595        var shortcuts = Tools.map(explode$3(pattern, '>'), this.parseShortcut);
27596        shortcuts[shortcuts.length - 1] = Tools.extend(shortcuts[shortcuts.length - 1], {
27597          func: cmdFunc,
27598          scope: scope || this.editor
27599        });
27600        return Tools.extend(shortcuts[0], {
27601          desc: this.editor.translate(desc),
27602          subpatterns: shortcuts.slice(1)
27603        });
27604      };
27605      Shortcuts.prototype.hasModifier = function (e) {
27606        return e.altKey || e.ctrlKey || e.metaKey;
27607      };
27608      Shortcuts.prototype.isFunctionKey = function (e) {
27609        return e.type === 'keydown' && e.keyCode >= 112 && e.keyCode <= 123;
27610      };
27611      Shortcuts.prototype.matchShortcut = function (e, shortcut) {
27612        if (!shortcut) {
27613          return false;
27614        }
27615        if (shortcut.ctrl !== e.ctrlKey || shortcut.meta !== e.metaKey) {
27616          return false;
27617        }
27618        if (shortcut.alt !== e.altKey || shortcut.shift !== e.shiftKey) {
27619          return false;
27620        }
27621        if (e.keyCode === shortcut.keyCode || e.charCode && e.charCode === shortcut.charCode) {
27622          e.preventDefault();
27623          return true;
27624        }
27625        return false;
27626      };
27627      Shortcuts.prototype.executeShortcutAction = function (shortcut) {
27628        return shortcut.func ? shortcut.func.call(shortcut.scope) : null;
27629      };
27630      return Shortcuts;
27631    }();
27632
27633    var create$6 = function () {
27634      var buttons = {};
27635      var menuItems = {};
27636      var popups = {};
27637      var icons = {};
27638      var contextMenus = {};
27639      var contextToolbars = {};
27640      var sidebars = {};
27641      var add = function (collection, type) {
27642        return function (name, spec) {
27643          return collection[name.toLowerCase()] = __assign(__assign({}, spec), { type: type });
27644        };
27645      };
27646      var addIcon = function (name, svgData) {
27647        return icons[name.toLowerCase()] = svgData;
27648      };
27649      return {
27650        addButton: add(buttons, 'button'),
27651        addGroupToolbarButton: add(buttons, 'grouptoolbarbutton'),
27652        addToggleButton: add(buttons, 'togglebutton'),
27653        addMenuButton: add(buttons, 'menubutton'),
27654        addSplitButton: add(buttons, 'splitbutton'),
27655        addMenuItem: add(menuItems, 'menuitem'),
27656        addNestedMenuItem: add(menuItems, 'nestedmenuitem'),
27657        addToggleMenuItem: add(menuItems, 'togglemenuitem'),
27658        addAutocompleter: add(popups, 'autocompleter'),
27659        addContextMenu: add(contextMenus, 'contextmenu'),
27660        addContextToolbar: add(contextToolbars, 'contexttoolbar'),
27661        addContextForm: add(contextToolbars, 'contextform'),
27662        addSidebar: add(sidebars, 'sidebar'),
27663        addIcon: addIcon,
27664        getAll: function () {
27665          return {
27666            buttons: buttons,
27667            menuItems: menuItems,
27668            icons: icons,
27669            popups: popups,
27670            contextMenus: contextMenus,
27671            contextToolbars: contextToolbars,
27672            sidebars: sidebars
27673          };
27674        }
27675      };
27676    };
27677
27678    var registry = function () {
27679      var bridge = create$6();
27680      return {
27681        addAutocompleter: bridge.addAutocompleter,
27682        addButton: bridge.addButton,
27683        addContextForm: bridge.addContextForm,
27684        addContextMenu: bridge.addContextMenu,
27685        addContextToolbar: bridge.addContextToolbar,
27686        addIcon: bridge.addIcon,
27687        addMenuButton: bridge.addMenuButton,
27688        addMenuItem: bridge.addMenuItem,
27689        addNestedMenuItem: bridge.addNestedMenuItem,
27690        addSidebar: bridge.addSidebar,
27691        addSplitButton: bridge.addSplitButton,
27692        addToggleButton: bridge.addToggleButton,
27693        addGroupToolbarButton: bridge.addGroupToolbarButton,
27694        addToggleMenuItem: bridge.addToggleMenuItem,
27695        getAll: bridge.getAll
27696      };
27697    };
27698
27699    var each$h = Tools.each, trim$4 = Tools.trim;
27700    var queryParts = 'source protocol authority userInfo user password host port relative path directory file query anchor'.split(' ');
27701    var DEFAULT_PORTS = {
27702      ftp: 21,
27703      http: 80,
27704      https: 443,
27705      mailto: 25
27706    };
27707    var URI = function () {
27708      function URI(url, settings) {
27709        url = trim$4(url);
27710        this.settings = settings || {};
27711        var baseUri = this.settings.base_uri;
27712        var self = this;
27713        if (/^([\w\-]+):([^\/]{2})/i.test(url) || /^\s*#/.test(url)) {
27714          self.source = url;
27715          return;
27716        }
27717        var isProtocolRelative = url.indexOf('//') === 0;
27718        if (url.indexOf('/') === 0 && !isProtocolRelative) {
27719          url = (baseUri ? baseUri.protocol || 'http' : 'http') + '://mce_host' + url;
27720        }
27721        if (!/^[\w\-]*:?\/\//.test(url)) {
27722          var baseUrl = this.settings.base_uri ? this.settings.base_uri.path : new URI(document.location.href).directory;
27723          if (this.settings.base_uri && this.settings.base_uri.protocol == '') {
27724            url = '//mce_host' + self.toAbsPath(baseUrl, url);
27725          } else {
27726            var match = /([^#?]*)([#?]?.*)/.exec(url);
27727            url = (baseUri && baseUri.protocol || 'http') + '://mce_host' + self.toAbsPath(baseUrl, match[1]) + match[2];
27728          }
27729        }
27730        url = url.replace(/@@/g, '(mce_at)');
27731        var urlMatch = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@\/]*):?([^:@\/]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(url);
27732        each$h(queryParts, function (v, i) {
27733          var part = urlMatch[i];
27734          if (part) {
27735            part = part.replace(/\(mce_at\)/g, '@@');
27736          }
27737          self[v] = part;
27738        });
27739        if (baseUri) {
27740          if (!self.protocol) {
27741            self.protocol = baseUri.protocol;
27742          }
27743          if (!self.userInfo) {
27744            self.userInfo = baseUri.userInfo;
27745          }
27746          if (!self.port && self.host === 'mce_host') {
27747            self.port = baseUri.port;
27748          }
27749          if (!self.host || self.host === 'mce_host') {
27750            self.host = baseUri.host;
27751          }
27752          self.source = '';
27753        }
27754        if (isProtocolRelative) {
27755          self.protocol = '';
27756        }
27757      }
27758      URI.parseDataUri = function (uri) {
27759        var type;
27760        var uriComponents = decodeURIComponent(uri).split(',');
27761        var matches = /data:([^;]+)/.exec(uriComponents[0]);
27762        if (matches) {
27763          type = matches[1];
27764        }
27765        return {
27766          type: type,
27767          data: uriComponents[1]
27768        };
27769      };
27770      URI.getDocumentBaseUrl = function (loc) {
27771        var baseUrl;
27772        if (loc.protocol.indexOf('http') !== 0 && loc.protocol !== 'file:') {
27773          baseUrl = loc.href;
27774        } else {
27775          baseUrl = loc.protocol + '//' + loc.host + loc.pathname;
27776        }
27777        if (/^[^:]+:\/\/\/?[^\/]+\//.test(baseUrl)) {
27778          baseUrl = baseUrl.replace(/[\?#].*$/, '').replace(/[\/\\][^\/]+$/, '');
27779          if (!/[\/\\]$/.test(baseUrl)) {
27780            baseUrl += '/';
27781          }
27782        }
27783        return baseUrl;
27784      };
27785      URI.prototype.setPath = function (path) {
27786        var pathMatch = /^(.*?)\/?(\w+)?$/.exec(path);
27787        this.path = pathMatch[0];
27788        this.directory = pathMatch[1];
27789        this.file = pathMatch[2];
27790        this.source = '';
27791        this.getURI();
27792      };
27793      URI.prototype.toRelative = function (uri) {
27794        var output;
27795        if (uri === './') {
27796          return uri;
27797        }
27798        var relativeUri = new URI(uri, { base_uri: this });
27799        if (relativeUri.host !== 'mce_host' && this.host !== relativeUri.host && relativeUri.host || this.port !== relativeUri.port || this.protocol !== relativeUri.protocol && relativeUri.protocol !== '') {
27800          return relativeUri.getURI();
27801        }
27802        var tu = this.getURI(), uu = relativeUri.getURI();
27803        if (tu === uu || tu.charAt(tu.length - 1) === '/' && tu.substr(0, tu.length - 1) === uu) {
27804          return tu;
27805        }
27806        output = this.toRelPath(this.path, relativeUri.path);
27807        if (relativeUri.query) {
27808          output += '?' + relativeUri.query;
27809        }
27810        if (relativeUri.anchor) {
27811          output += '#' + relativeUri.anchor;
27812        }
27813        return output;
27814      };
27815      URI.prototype.toAbsolute = function (uri, noHost) {
27816        var absoluteUri = new URI(uri, { base_uri: this });
27817        return absoluteUri.getURI(noHost && this.isSameOrigin(absoluteUri));
27818      };
27819      URI.prototype.isSameOrigin = function (uri) {
27820        if (this.host == uri.host && this.protocol == uri.protocol) {
27821          if (this.port == uri.port) {
27822            return true;
27823          }
27824          var defaultPort = DEFAULT_PORTS[this.protocol];
27825          if (defaultPort && (this.port || defaultPort) == (uri.port || defaultPort)) {
27826            return true;
27827          }
27828        }
27829        return false;
27830      };
27831      URI.prototype.toRelPath = function (base, path) {
27832        var breakPoint = 0, out = '', i, l;
27833        var normalizedBase = base.substring(0, base.lastIndexOf('/')).split('/');
27834        var items = path.split('/');
27835        if (normalizedBase.length >= items.length) {
27836          for (i = 0, l = normalizedBase.length; i < l; i++) {
27837            if (i >= items.length || normalizedBase[i] !== items[i]) {
27838              breakPoint = i + 1;
27839              break;
27840            }
27841          }
27842        }
27843        if (normalizedBase.length < items.length) {
27844          for (i = 0, l = items.length; i < l; i++) {
27845            if (i >= normalizedBase.length || normalizedBase[i] !== items[i]) {
27846              breakPoint = i + 1;
27847              break;
27848            }
27849          }
27850        }
27851        if (breakPoint === 1) {
27852          return path;
27853        }
27854        for (i = 0, l = normalizedBase.length - (breakPoint - 1); i < l; i++) {
27855          out += '../';
27856        }
27857        for (i = breakPoint - 1, l = items.length; i < l; i++) {
27858          if (i !== breakPoint - 1) {
27859            out += '/' + items[i];
27860          } else {
27861            out += items[i];
27862          }
27863        }
27864        return out;
27865      };
27866      URI.prototype.toAbsPath = function (base, path) {
27867        var i, nb = 0, o = [], outPath;
27868        var tr = /\/$/.test(path) ? '/' : '';
27869        var normalizedBase = base.split('/');
27870        var normalizedPath = path.split('/');
27871        each$h(normalizedBase, function (k) {
27872          if (k) {
27873            o.push(k);
27874          }
27875        });
27876        normalizedBase = o;
27877        for (i = normalizedPath.length - 1, o = []; i >= 0; i--) {
27878          if (normalizedPath[i].length === 0 || normalizedPath[i] === '.') {
27879            continue;
27880          }
27881          if (normalizedPath[i] === '..') {
27882            nb++;
27883            continue;
27884          }
27885          if (nb > 0) {
27886            nb--;
27887            continue;
27888          }
27889          o.push(normalizedPath[i]);
27890        }
27891        i = normalizedBase.length - nb;
27892        if (i <= 0) {
27893          outPath = reverse(o).join('/');
27894        } else {
27895          outPath = normalizedBase.slice(0, i).join('/') + '/' + reverse(o).join('/');
27896        }
27897        if (outPath.indexOf('/') !== 0) {
27898          outPath = '/' + outPath;
27899        }
27900        if (tr && outPath.lastIndexOf('/') !== outPath.length - 1) {
27901          outPath += tr;
27902        }
27903        return outPath;
27904      };
27905      URI.prototype.getURI = function (noProtoHost) {
27906        if (noProtoHost === void 0) {
27907          noProtoHost = false;
27908        }
27909        var s;
27910        if (!this.source || noProtoHost) {
27911          s = '';
27912          if (!noProtoHost) {
27913            if (this.protocol) {
27914              s += this.protocol + '://';
27915            } else {
27916              s += '//';
27917            }
27918            if (this.userInfo) {
27919              s += this.userInfo + '@';
27920            }
27921            if (this.host) {
27922              s += this.host;
27923            }
27924            if (this.port) {
27925              s += ':' + this.port;
27926            }
27927          }
27928          if (this.path) {
27929            s += this.path;
27930          }
27931          if (this.query) {
27932            s += '?' + this.query;
27933          }
27934          if (this.anchor) {
27935            s += '#' + this.anchor;
27936          }
27937          this.source = s;
27938        }
27939        return this.source;
27940      };
27941      return URI;
27942    }();
27943
27944    var DOM$9 = DOMUtils$1.DOM;
27945    var extend$3 = Tools.extend, each$i = Tools.each;
27946    var resolve$3 = Tools.resolve;
27947    var ie$1 = Env.ie;
27948    var Editor = function () {
27949      function Editor(id, settings, editorManager) {
27950        var _this = this;
27951        this.plugins = {};
27952        this.contentCSS = [];
27953        this.contentStyles = [];
27954        this.loadedCSS = {};
27955        this.isNotDirty = false;
27956        this.editorManager = editorManager;
27957        this.documentBaseUrl = editorManager.documentBaseURL;
27958        extend$3(this, EditorObservable);
27959        this.settings = getEditorSettings(this, id, this.documentBaseUrl, editorManager.defaultSettings, settings);
27960        if (this.settings.suffix) {
27961          editorManager.suffix = this.settings.suffix;
27962        }
27963        this.suffix = editorManager.suffix;
27964        if (this.settings.base_url) {
27965          editorManager._setBaseUrl(this.settings.base_url);
27966        }
27967        this.baseUri = editorManager.baseURI;
27968        if (this.settings.referrer_policy) {
27969          ScriptLoader.ScriptLoader._setReferrerPolicy(this.settings.referrer_policy);
27970          DOMUtils$1.DOM.styleSheetLoader._setReferrerPolicy(this.settings.referrer_policy);
27971        }
27972        AddOnManager$1.languageLoad = this.settings.language_load;
27973        AddOnManager$1.baseURL = editorManager.baseURL;
27974        this.id = id;
27975        this.setDirty(false);
27976        this.documentBaseURI = new URI(this.settings.document_base_url, { base_uri: this.baseUri });
27977        this.baseURI = this.baseUri;
27978        this.inline = !!this.settings.inline;
27979        this.shortcuts = new Shortcuts(this);
27980        this.editorCommands = new EditorCommands(this);
27981        if (this.settings.cache_suffix) {
27982          Env.cacheSuffix = this.settings.cache_suffix.replace(/^[\?\&]+/, '');
27983        }
27984        this.ui = {
27985          registry: registry(),
27986          styleSheetLoader: undefined,
27987          show: noop,
27988          hide: noop
27989        };
27990        var self = this;
27991        var modeInstance = create$5(self);
27992        this.mode = modeInstance;
27993        this.setMode = modeInstance.set;
27994        editorManager.fire('SetupEditor', { editor: this });
27995        this.execCallback('setup', this);
27996        this.$ = DomQuery.overrideDefaults(function () {
27997          return {
27998            context: _this.inline ? _this.getBody() : _this.getDoc(),
27999            element: _this.getBody()
28000          };
28001        });
28002      }
28003      Editor.prototype.render = function () {
28004        render(this);
28005      };
28006      Editor.prototype.focus = function (skipFocus) {
28007        focus$1(this, skipFocus);
28008      };
28009      Editor.prototype.hasFocus = function () {
28010        return hasFocus$1(this);
28011      };
28012      Editor.prototype.execCallback = function (name) {
28013        var x = [];
28014        for (var _i = 1; _i < arguments.length; _i++) {
28015          x[_i - 1] = arguments[_i];
28016        }
28017        var self = this;
28018        var callback = self.settings[name], scope;
28019        if (!callback) {
28020          return;
28021        }
28022        if (self.callbackLookup && (scope = self.callbackLookup[name])) {
28023          callback = scope.func;
28024          scope = scope.scope;
28025        }
28026        if (typeof callback === 'string') {
28027          scope = callback.replace(/\.\w+$/, '');
28028          scope = scope ? resolve$3(scope) : 0;
28029          callback = resolve$3(callback);
28030          self.callbackLookup = self.callbackLookup || {};
28031          self.callbackLookup[name] = {
28032            func: callback,
28033            scope: scope
28034          };
28035        }
28036        return callback.apply(scope || self, x);
28037      };
28038      Editor.prototype.translate = function (text) {
28039        return I18n.translate(text);
28040      };
28041      Editor.prototype.getParam = function (name, defaultVal, type) {
28042        return getParam(this, name, defaultVal, type);
28043      };
28044      Editor.prototype.hasPlugin = function (name, loaded) {
28045        var hasPlugin = contains(getPlugins(this).split(/[ ,]/), name);
28046        if (hasPlugin) {
28047          return loaded ? PluginManager.get(name) !== undefined : true;
28048        } else {
28049          return false;
28050        }
28051      };
28052      Editor.prototype.nodeChanged = function (args) {
28053        this._nodeChangeDispatcher.nodeChanged(args);
28054      };
28055      Editor.prototype.addCommand = function (name, callback, scope) {
28056        this.editorCommands.addCommand(name, callback, scope);
28057      };
28058      Editor.prototype.addQueryStateHandler = function (name, callback, scope) {
28059        this.editorCommands.addQueryStateHandler(name, callback, scope);
28060      };
28061      Editor.prototype.addQueryValueHandler = function (name, callback, scope) {
28062        this.editorCommands.addQueryValueHandler(name, callback, scope);
28063      };
28064      Editor.prototype.addShortcut = function (pattern, desc, cmdFunc, scope) {
28065        this.shortcuts.add(pattern, desc, cmdFunc, scope);
28066      };
28067      Editor.prototype.execCommand = function (cmd, ui, value, args) {
28068        return this.editorCommands.execCommand(cmd, ui, value, args);
28069      };
28070      Editor.prototype.queryCommandState = function (cmd) {
28071        return this.editorCommands.queryCommandState(cmd);
28072      };
28073      Editor.prototype.queryCommandValue = function (cmd) {
28074        return this.editorCommands.queryCommandValue(cmd);
28075      };
28076      Editor.prototype.queryCommandSupported = function (cmd) {
28077        return this.editorCommands.queryCommandSupported(cmd);
28078      };
28079      Editor.prototype.show = function () {
28080        var self = this;
28081        if (self.hidden) {
28082          self.hidden = false;
28083          if (self.inline) {
28084            self.getBody().contentEditable = 'true';
28085          } else {
28086            DOM$9.show(self.getContainer());
28087            DOM$9.hide(self.id);
28088          }
28089          self.load();
28090          self.fire('show');
28091        }
28092      };
28093      Editor.prototype.hide = function () {
28094        var self = this, doc = self.getDoc();
28095        if (!self.hidden) {
28096          if (ie$1 && doc && !self.inline) {
28097            doc.execCommand('SelectAll');
28098          }
28099          self.save();
28100          if (self.inline) {
28101            self.getBody().contentEditable = 'false';
28102            if (self === self.editorManager.focusedEditor) {
28103              self.editorManager.focusedEditor = null;
28104            }
28105          } else {
28106            DOM$9.hide(self.getContainer());
28107            DOM$9.setStyle(self.id, 'display', self.orgDisplay);
28108          }
28109          self.hidden = true;
28110          self.fire('hide');
28111        }
28112      };
28113      Editor.prototype.isHidden = function () {
28114        return !!this.hidden;
28115      };
28116      Editor.prototype.setProgressState = function (state, time) {
28117        this.fire('ProgressState', {
28118          state: state,
28119          time: time
28120        });
28121      };
28122      Editor.prototype.load = function (args) {
28123        var self = this;
28124        var elm = self.getElement(), html;
28125        if (self.removed) {
28126          return '';
28127        }
28128        if (elm) {
28129          args = args || {};
28130          args.load = true;
28131          var value = isTextareaOrInput(elm) ? elm.value : elm.innerHTML;
28132          html = self.setContent(value, args);
28133          args.element = elm;
28134          if (!args.no_events) {
28135            self.fire('LoadContent', args);
28136          }
28137          args.element = elm = null;
28138          return html;
28139        }
28140      };
28141      Editor.prototype.save = function (args) {
28142        var self = this;
28143        var elm = self.getElement(), html, form;
28144        if (!elm || !self.initialized || self.removed) {
28145          return;
28146        }
28147        args = args || {};
28148        args.save = true;
28149        args.element = elm;
28150        html = args.content = self.getContent(args);
28151        if (!args.no_events) {
28152          self.fire('SaveContent', args);
28153        }
28154        if (args.format === 'raw') {
28155          self.fire('RawSaveContent', args);
28156        }
28157        html = args.content;
28158        if (!isTextareaOrInput(elm)) {
28159          if (args.is_removing || !self.inline) {
28160            elm.innerHTML = html;
28161          }
28162          if (form = DOM$9.getParent(self.id, 'form')) {
28163            each$i(form.elements, function (elm) {
28164              if (elm.name === self.id) {
28165                elm.value = html;
28166                return false;
28167              }
28168            });
28169          }
28170        } else {
28171          elm.value = html;
28172        }
28173        args.element = elm = null;
28174        if (args.set_dirty !== false) {
28175          self.setDirty(false);
28176        }
28177        return html;
28178      };
28179      Editor.prototype.setContent = function (content, args) {
28180        return setContent$2(this, content, args);
28181      };
28182      Editor.prototype.getContent = function (args) {
28183        return getContent$2(this, args);
28184      };
28185      Editor.prototype.insertContent = function (content, args) {
28186        if (args) {
28187          content = extend$3({ content: content }, args);
28188        }
28189        this.execCommand('mceInsertContent', false, content);
28190      };
28191      Editor.prototype.resetContent = function (initialContent) {
28192        if (initialContent === undefined) {
28193          setContent$2(this, this.startContent, { format: 'raw' });
28194        } else {
28195          setContent$2(this, initialContent);
28196        }
28197        this.undoManager.reset();
28198        this.setDirty(false);
28199        this.nodeChanged();
28200      };
28201      Editor.prototype.isDirty = function () {
28202        return !this.isNotDirty;
28203      };
28204      Editor.prototype.setDirty = function (state) {
28205        var oldState = !this.isNotDirty;
28206        this.isNotDirty = !state;
28207        if (state && state !== oldState) {
28208          this.fire('dirty');
28209        }
28210      };
28211      Editor.prototype.getContainer = function () {
28212        var self = this;
28213        if (!self.container) {
28214          self.container = DOM$9.get(self.editorContainer || self.id + '_parent');
28215        }
28216        return self.container;
28217      };
28218      Editor.prototype.getContentAreaContainer = function () {
28219        return this.contentAreaContainer;
28220      };
28221      Editor.prototype.getElement = function () {
28222        if (!this.targetElm) {
28223          this.targetElm = DOM$9.get(this.id);
28224        }
28225        return this.targetElm;
28226      };
28227      Editor.prototype.getWin = function () {
28228        var self = this;
28229        var elm;
28230        if (!self.contentWindow) {
28231          elm = self.iframeElement;
28232          if (elm) {
28233            self.contentWindow = elm.contentWindow;
28234          }
28235        }
28236        return self.contentWindow;
28237      };
28238      Editor.prototype.getDoc = function () {
28239        var self = this;
28240        var win;
28241        if (!self.contentDocument) {
28242          win = self.getWin();
28243          if (win) {
28244            self.contentDocument = win.document;
28245          }
28246        }
28247        return self.contentDocument;
28248      };
28249      Editor.prototype.getBody = function () {
28250        var doc = this.getDoc();
28251        return this.bodyElement || (doc ? doc.body : null);
28252      };
28253      Editor.prototype.convertURL = function (url, name, elm) {
28254        var self = this, settings = self.settings;
28255        if (settings.urlconverter_callback) {
28256          return self.execCallback('urlconverter_callback', url, elm, true, name);
28257        }
28258        if (!settings.convert_urls || elm && elm.nodeName === 'LINK' || url.indexOf('file:') === 0 || url.length === 0) {
28259          return url;
28260        }
28261        if (settings.relative_urls) {
28262          return self.documentBaseURI.toRelative(url);
28263        }
28264        url = self.documentBaseURI.toAbsolute(url, settings.remove_script_host);
28265        return url;
28266      };
28267      Editor.prototype.addVisual = function (elm) {
28268        var self = this;
28269        var settings = self.settings;
28270        var dom = self.dom;
28271        var cls;
28272        elm = elm || self.getBody();
28273        if (self.hasVisual === undefined) {
28274          self.hasVisual = settings.visual;
28275        }
28276        each$i(dom.select('table,a', elm), function (elm) {
28277          var value;
28278          switch (elm.nodeName) {
28279          case 'TABLE':
28280            cls = settings.visual_table_class || 'mce-item-table';
28281            value = dom.getAttrib(elm, 'border');
28282            if ((!value || value === '0') && self.hasVisual) {
28283              dom.addClass(elm, cls);
28284            } else {
28285              dom.removeClass(elm, cls);
28286            }
28287            return;
28288          case 'A':
28289            if (!dom.getAttrib(elm, 'href')) {
28290              value = dom.getAttrib(elm, 'name') || elm.id;
28291              cls = settings.visual_anchor_class || 'mce-item-anchor';
28292              if (value && self.hasVisual) {
28293                dom.addClass(elm, cls);
28294              } else {
28295                dom.removeClass(elm, cls);
28296              }
28297            }
28298            return;
28299          }
28300        });
28301        self.fire('VisualAid', {
28302          element: elm,
28303          hasVisual: self.hasVisual
28304        });
28305      };
28306      Editor.prototype.remove = function () {
28307        remove$7(this);
28308      };
28309      Editor.prototype.destroy = function (automatic) {
28310        destroy(this, automatic);
28311      };
28312      Editor.prototype.uploadImages = function (callback) {
28313        return this.editorUpload.uploadImages(callback);
28314      };
28315      Editor.prototype._scanForImages = function () {
28316        return this.editorUpload.scanForImages();
28317      };
28318      Editor.prototype.addButton = function () {
28319        throw new Error('editor.addButton has been removed in tinymce 5x, use editor.ui.registry.addButton or editor.ui.registry.addToggleButton or editor.ui.registry.addSplitButton instead');
28320      };
28321      Editor.prototype.addSidebar = function () {
28322        throw new Error('editor.addSidebar has been removed in tinymce 5x, use editor.ui.registry.addSidebar instead');
28323      };
28324      Editor.prototype.addMenuItem = function () {
28325        throw new Error('editor.addMenuItem has been removed in tinymce 5x, use editor.ui.registry.addMenuItem instead');
28326      };
28327      Editor.prototype.addContextToolbar = function () {
28328        throw new Error('editor.addContextToolbar has been removed in tinymce 5x, use editor.ui.registry.addContextToolbar instead');
28329      };
28330      return Editor;
28331    }();
28332
28333    var DOM$a = DOMUtils$1.DOM;
28334    var explode$4 = Tools.explode, each$j = Tools.each, extend$4 = Tools.extend;
28335    var instanceCounter = 0, boundGlobalEvents = false;
28336    var beforeUnloadDelegate;
28337    var legacyEditors = [];
28338    var editors = [];
28339    var isValidLegacyKey = function (id) {
28340      return id !== 'length';
28341    };
28342    var globalEventDelegate = function (e) {
28343      var type = e.type;
28344      each$j(EditorManager.get(), function (editor) {
28345        switch (type) {
28346        case 'scroll':
28347          editor.fire('ScrollWindow', e);
28348          break;
28349        case 'resize':
28350          editor.fire('ResizeWindow', e);
28351          break;
28352        }
28353      });
28354    };
28355    var toggleGlobalEvents = function (state) {
28356      if (state !== boundGlobalEvents) {
28357        if (state) {
28358          DomQuery(window).on('resize scroll', globalEventDelegate);
28359        } else {
28360          DomQuery(window).off('resize scroll', globalEventDelegate);
28361        }
28362        boundGlobalEvents = state;
28363      }
28364    };
28365    var removeEditorFromList = function (targetEditor) {
28366      var oldEditors = editors;
28367      delete legacyEditors[targetEditor.id];
28368      for (var i = 0; i < legacyEditors.length; i++) {
28369        if (legacyEditors[i] === targetEditor) {
28370          legacyEditors.splice(i, 1);
28371          break;
28372        }
28373      }
28374      editors = filter(editors, function (editor) {
28375        return targetEditor !== editor;
28376      });
28377      if (EditorManager.activeEditor === targetEditor) {
28378        EditorManager.activeEditor = editors.length > 0 ? editors[0] : null;
28379      }
28380      if (EditorManager.focusedEditor === targetEditor) {
28381        EditorManager.focusedEditor = null;
28382      }
28383      return oldEditors.length !== editors.length;
28384    };
28385    var purgeDestroyedEditor = function (editor) {
28386      if (editor && editor.initialized && !(editor.getContainer() || editor.getBody()).parentNode) {
28387        removeEditorFromList(editor);
28388        editor.unbindAllNativeEvents();
28389        editor.destroy(true);
28390        editor.removed = true;
28391        editor = null;
28392      }
28393      return editor;
28394    };
28395    var isQuirksMode = document.compatMode !== 'CSS1Compat';
28396    var EditorManager = __assign(__assign({}, Observable), {
28397      baseURI: null,
28398      baseURL: null,
28399      defaultSettings: {},
28400      documentBaseURL: null,
28401      suffix: null,
28402      $: DomQuery,
28403      majorVersion: '5',
28404      minorVersion: '5.1',
28405      releaseDate: '2020-10-01',
28406      editors: legacyEditors,
28407      i18n: I18n,
28408      activeEditor: null,
28409      focusedEditor: null,
28410      settings: {},
28411      setup: function () {
28412        var self = this;
28413        var baseURL, documentBaseURL, suffix = '';
28414        documentBaseURL = URI.getDocumentBaseUrl(document.location);
28415        if (/^[^:]+:\/\/\/?[^\/]+\//.test(documentBaseURL)) {
28416          documentBaseURL = documentBaseURL.replace(/[\?#].*$/, '').replace(/[\/\\][^\/]+$/, '');
28417          if (!/[\/\\]$/.test(documentBaseURL)) {
28418            documentBaseURL += '/';
28419          }
28420        }
28421        var preInit = window.tinymce || window.tinyMCEPreInit;
28422        if (preInit) {
28423          baseURL = preInit.base || preInit.baseURL;
28424          suffix = preInit.suffix;
28425        } else {
28426          var scripts = document.getElementsByTagName('script');
28427          for (var i = 0; i < scripts.length; i++) {
28428            var src = scripts[i].src || '';
28429            if (src === '') {
28430              continue;
28431            }
28432            var srcScript = src.substring(src.lastIndexOf('/'));
28433            if (/tinymce(\.full|\.jquery|)(\.min|\.dev|)\.js/.test(src)) {
28434              if (srcScript.indexOf('.min') !== -1) {
28435                suffix = '.min';
28436              }
28437              baseURL = src.substring(0, src.lastIndexOf('/'));
28438              break;
28439            }
28440          }
28441          if (!baseURL && document.currentScript) {
28442            var src = document.currentScript.src;
28443            if (src.indexOf('.min') !== -1) {
28444              suffix = '.min';
28445            }
28446            baseURL = src.substring(0, src.lastIndexOf('/'));
28447          }
28448        }
28449        self.baseURL = new URI(documentBaseURL).toAbsolute(baseURL);
28450        self.documentBaseURL = documentBaseURL;
28451        self.baseURI = new URI(self.baseURL);
28452        self.suffix = suffix;
28453        setup$2(self);
28454      },
28455      overrideDefaults: function (defaultSettings) {
28456        var baseUrl = defaultSettings.base_url;
28457        if (baseUrl) {
28458          this._setBaseUrl(baseUrl);
28459        }
28460        var suffix = defaultSettings.suffix;
28461        if (defaultSettings.suffix) {
28462          this.suffix = suffix;
28463        }
28464        this.defaultSettings = defaultSettings;
28465        var pluginBaseUrls = defaultSettings.plugin_base_urls;
28466        if (pluginBaseUrls !== undefined) {
28467          each$1(pluginBaseUrls, function (pluginBaseUrl, pluginName) {
28468            AddOnManager$1.PluginManager.urls[pluginName] = pluginBaseUrl;
28469          });
28470        }
28471      },
28472      init: function (settings) {
28473        var self = this;
28474        var result;
28475        var invalidInlineTargets = Tools.makeMap('area base basefont br col frame hr img input isindex link meta param embed source wbr track ' + 'colgroup option table tbody tfoot thead tr th td script noscript style textarea video audio iframe object menu', ' ');
28476        var isInvalidInlineTarget = function (settings, elm) {
28477          return settings.inline && elm.tagName.toLowerCase() in invali
28477dInlineTargets;
28478        };
28479        var createId = function (elm) {
28480          var id = elm.id;
28481          if (!id) {
28482            id = get(elm, 'name').filter(function (name) {
28483              return !DOM$a.get(name);
28484            }).getOrThunk(DOM$a.uniqueId);
28485            elm.setAttribute('id', id);
28486          }
28487          return id;
28488        };
28489        var execCallback = function (name) {
28490          var callback = settings[name];
28491          if (!callback) {
28492            return;
28493          }
28494          return callback.apply(self, Array.prototype.slice.call(arguments, 2));
28495        };
28496        var hasClass = function (elm, className) {
28497          return className.constructor === RegExp ? className.test(elm.className) : DOM$a.hasClass(elm, className);
28498        };
28499        var findTargets = function (settings) {
28500          var targets = [];
28501          if (Env.browser.isIE() && Env.browser.version.major < 11) {
28502            initError('TinyMCE does not support the browser you are using. For a list of supported' + ' browsers please see: https://www.tinymce.com/docs/get-started/system-requirements/');
28503            return [];
28504          } else if (isQuirksMode) {
28505            initError('Failed to initialize the editor as the document is not in standards mode. ' + 'TinyMCE requires standards mode.');
28506            return [];
28507          }
28508          if (settings.types) {
28509            each$j(settings.types, function (type) {
28510              targets = targets.concat(DOM$a.select(type.selector));
28511            });
28512            return targets;
28513          } else if (settings.selector) {
28514            return DOM$a.select(settings.selector);
28515          } else if (settings.target) {
28516            return [settings.target];
28517          }
28518          switch (settings.mode) {
28519          case 'exact':
28520            var l = settings.elements || '';
28521            if (l.length > 0) {
28522              each$j(explode$4(l), function (id) {
28523                var elm = DOM$a.get(id);
28524                if (elm) {
28525                  targets.push(elm);
28526                } else {
28527                  each$j(document.forms, function (f) {
28528                    each$j(f.elements, function (e) {
28529                      if (e.name === id) {
28530                        id = 'mce_editor_' + instanceCounter++;
28531                        DOM$a.setAttrib(e, 'id', id);
28532                        targets.push(e);
28533                      }
28534                    });
28535                  });
28536                }
28537              });
28538            }
28539            break;
28540          case 'textareas':
28541          case 'specific_textareas':
28542            each$j(DOM$a.select('textarea'), function (elm) {
28543              if (settings.editor_deselector && hasClass(elm, settings.editor_deselector)) {
28544                return;
28545              }
28546              if (!settings.editor_selector || hasClass(elm, settings.editor_selector)) {
28547                targets.push(elm);
28548              }
28549            });
28550            break;
28551          }
28552          return targets;
28553        };
28554        var provideResults = function (editors) {
28555          result = editors;
28556        };
28557        var initEditors = function () {
28558          var initCount = 0;
28559          var editors = [];
28560          var targets;
28561          var createEditor = function (id, settings, targetElm) {
28562            var editor = new Editor(id, settings, self);
28563            editors.push(editor);
28564            editor.on('init', function () {
28565              if (++initCount === targets.length) {
28566                provideResults(editors);
28567              }
28568            });
28569            editor.targetElm = editor.targetElm || targetElm;
28570            editor.render();
28571          };
28572          DOM$a.unbind(window, 'ready', initEditors);
28573          execCallback('onpageload');
28574          targets = DomQuery.unique(findTargets(settings));
28575          if (settings.types) {
28576            each$j(settings.types, function (type) {
28577              Tools.each(targets, function (elm) {
28578                if (DOM$a.is(elm, type.selector)) {
28579                  createEditor(createId(elm), extend$4({}, settings, type), elm);
28580                  return false;
28581                }
28582                return true;
28583              });
28584            });
28585            return;
28586          }
28587          Tools.each(targets, function (elm) {
28588            purgeDestroyedEditor(self.get(elm.id));
28589          });
28590          targets = Tools.grep(targets, function (elm) {
28591            return !self.get(elm.id);
28592          });
28593          if (targets.length === 0) {
28594            provideResults([]);
28595          } else {
28596            each$j(targets, function (elm) {
28597              if (isInvalidInlineTarget(settings, elm)) {
28598                initError('Could not initialize inline editor on invalid inline target element', elm);
28599              } else {
28600                createEditor(createId(elm), settings, elm);
28601              }
28602            });
28603          }
28604        };
28605        self.settings = settings;
28606        DOM$a.bind(window, 'ready', initEditors);
28607        return new promiseObj(function (resolve) {
28608          if (result) {
28609            resolve(result);
28610          } else {
28611            provideResults = function (editors) {
28612              resolve(editors);
28613            };
28614          }
28615        });
28616      },
28617      get: function (id) {
28618        if (arguments.length === 0) {
28619          return editors.slice(0);
28620        } else if (isString(id)) {
28621          return find(editors, function (editor) {
28622            return editor.id === id;
28623          }).getOr(null);
28624        } else if (isNumber(id)) {
28625          return editors[id] ? editors[id] : null;
28626        } else {
28627          return null;
28628        }
28629      },
28630      add: function (editor) {
28631        var self = this;
28632        var existingEditor = legacyEditors[editor.id];
28633        if (existingEditor === editor) {
28634          return editor;
28635        }
28636        if (self.get(editor.id) === null) {
28637          if (isValidLegacyKey(editor.id)) {
28638            legacyEditors[editor.id] = editor;
28639          }
28640          legacyEditors.push(editor);
28641          editors.push(editor);
28642        }
28643        toggleGlobalEvents(true);
28644        self.activeEditor = editor;
28645        self.fire('AddEditor', { editor: editor });
28646        if (!beforeUnloadDelegate) {
28647          beforeUnloadDelegate = function (e) {
28648            var event = self.fire('BeforeUnload');
28649            if (event.returnValue) {
28650              e.preventDefault();
28651              e.returnValue = event.returnValue;
28652              return event.returnValue;
28653            }
28654          };
28655          window.addEventListener('beforeunload', beforeUnloadDelegate);
28656        }
28657        return editor;
28658      },
28659      createEditor: function (id, settings) {
28660        return this.add(new Editor(id, settings, this));
28661      },
28662      remove: function (selector) {
28663        var self = this;
28664        var i, editor;
28665        if (!selector) {
28666          for (i = editors.length - 1; i >= 0; i--) {
28667            self.remove(editors[i]);
28668          }
28669          return;
28670        }
28671        if (isString(selector)) {
28672          each$j(DOM$a.select(selector), function (elm) {
28673            editor = self.get(elm.id);
28674            if (editor) {
28675              self.remove(editor);
28676            }
28677          });
28678          return;
28679        }
28680        editor = selector;
28681        if (isNull(self.get(editor.id))) {
28682          return null;
28683        }
28684        if (removeEditorFromList(editor)) {
28685          self.fire('RemoveEditor', { editor: editor });
28686        }
28687        if (editors.length === 0) {
28688          window.removeEventListener('beforeunload', beforeUnloadDelegate);
28689        }
28690        editor.remove();
28691        toggleGlobalEvents(editors.length > 0);
28692        return editor;
28693      },
28694      execCommand: function (cmd, ui, value) {
28695        var self = this, editor = self.get(value);
28696        switch (cmd) {
28697        case 'mceAddEditor':
28698          if (!self.get(value)) {
28699            new Editor(value, self.settings, self).render();
28700          }
28701          return true;
28702        case 'mceRemoveEditor':
28703          if (editor) {
28704            editor.remove();
28705          }
28706          return true;
28707        case 'mceToggleEditor':
28708          if (!editor) {
28709            self.execCommand('mceAddEditor', 0, value);
28710            return true;
28711          }
28712          if (editor.isHidden()) {
28713            editor.show();
28714          } else {
28715            editor.hide();
28716          }
28717          return true;
28718        }
28719        if (self.activeEditor) {
28720          return self.activeEditor.execCommand(cmd, ui, value);
28721        }
28722        return false;
28723      },
28724      triggerSave: function () {
28725        each$j(editors, function (editor) {
28726          editor.save();
28727        });
28728      },
28729      addI18n: function (code, items) {
28730        I18n.add(code, items);
28731      },
28732      translate: function (text) {
28733        return I18n.translate(text);
28734      },
28735      setActive: function (editor) {
28736        var activeEditor = this.activeEditor;
28737        if (this.activeEditor !== editor) {
28738          if (activeEditor) {
28739            activeEditor.fire('deactivate', { relatedTarget: editor });
28740          }
28741          editor.fire('activate', { relatedTarget: activeEditor });
28742        }
28743        this.activeEditor = editor;
28744      },
28745      _setBaseUrl: function (baseUrl) {
28746        this.baseURL = new URI(this.documentBaseURL).toAbsolute(baseUrl.replace(/\/+$/, ''));
28747        this.baseURI = new URI(this.baseURL);
28748      }
28749    });
28750    EditorManager.setup();
28751
28752    var min = Math.min, max = Math.max, round$1 = Math.round;
28753    var relativePosition = function (rect, targetRect, rel) {
28754      var x = targetRect.x;
28755      var y = targetRect.y;
28756      var w = rect.w;
28757      var h = rect.h;
28758      var targetW = targetRect.w;
28759      var targetH = targetRect.h;
28760      var relChars = (rel || '').split('');
28761      if (relChars[0] === 'b') {
28762        y += targetH;
28763      }
28764      if (relChars[1] === 'r') {
28765        x += targetW;
28766      }
28767      if (relChars[0] === 'c') {
28768        y += round$1(targetH / 2);
28769      }
28770      if (relChars[1] === 'c') {
28771        x += round$1(targetW / 2);
28772      }
28773      if (relChars[3] === 'b') {
28774        y -= h;
28775      }
28776      if (relChars[4] === 'r') {
28777        x -= w;
28778      }
28779      if (relChars[3] === 'c') {
28780        y -= round$1(h / 2);
28781      }
28782      if (relChars[4] === 'c') {
28783        x -= round$1(w / 2);
28784      }
28785      return create$7(x, y, w, h);
28786    };
28787    var findBestRelativePosition = function (rect, targetRect, constrainRect, rels) {
28788      var pos, i;
28789      for (i = 0; i < rels.length; i++) {
28790        pos = relativePosition(rect, targetRect, rels[i]);
28791        if (pos.x >= constrainRect.x && pos.x + pos.w <= constrainRect.w + constrainRect.x && pos.y >= constrainRect.y && pos.y + pos.h <= constrainRect.h + constrainRect.y) {
28792          return rels[i];
28793        }
28794      }
28795      return null;
28796    };
28797    var inflate = function (rect, w, h) {
28798      return create$7(rect.x - w, rect.y - h, rect.w + w * 2, rect.h + h * 2);
28799    };
28800    var intersect = function (rect, cropRect) {
28801      var x1 = max(rect.x, cropRect.x);
28802      var y1 = max(rect.y, cropRect.y);
28803      var x2 = min(rect.x + rect.w, cropRect.x + cropRect.w);
28804      var y2 = min(rect.y + rect.h, cropRect.y + cropRect.h);
28805      if (x2 - x1 < 0 || y2 - y1 < 0) {
28806        return null;
28807      }
28808      return create$7(x1, y1, x2 - x1, y2 - y1);
28809    };
28810    var clamp$1 = function (rect, clampRect, fixedSize) {
28811      var x1 = rect.x;
28812      var y1 = rect.y;
28813      var x2 = rect.x + rect.w;
28814      var y2 = rect.y + rect.h;
28815      var cx2 = clampRect.x + clampRect.w;
28816      var cy2 = clampRect.y + clampRect.h;
28817      var underflowX1 = max(0, clampRect.x - x1);
28818      var underflowY1 = max(0, clampRect.y - y1);
28819      var overflowX2 = max(0, x2 - cx2);
28820      var overflowY2 = max(0, y2 - cy2);
28821      x1 += underflowX1;
28822      y1 += underflowY1;
28823      if (fixedSize) {
28824        x2 += underflowX1;
28825        y2 += underflowY1;
28826        x1 -= overflowX2;
28827        y1 -= overflowY2;
28828      }
28829      x2 -= overflowX2;
28830      y2 -= overflowY2;
28831      return create$7(x1, y1, x2 - x1, y2 - y1);
28832    };
28833    var create$7 = function (x, y, w, h) {
28834      return {
28835        x: x,
28836        y: y,
28837        w: w,
28838        h: h
28839      };
28840    };
28841    var fromClientRect = function (clientRect) {
28842      return create$7(clientRect.left, clientRect.top, clientRect.width, clientRect.height);
28843    };
28844    var Rect = {
28845      inflate: inflate,
28846      relativePosition: relativePosition,
28847      findBestRelativePosition: findBestRelativePosition,
28848      intersect: intersect,
28849      clamp: clamp$1,
28850      create: create$7,
28851      fromClientRect: fromClientRect
28852    };
28853
28854    var awaiter = function (resolveCb, rejectCb, timeout) {
28855      if (timeout === void 0) {
28856        timeout = 1000;
28857      }
28858      var done = false;
28859      var timer = null;
28860      var complete = function (completer) {
28861        return function () {
28862          var args = [];
28863          for (var _i = 0; _i < arguments.length; _i++) {
28864            args[_i] = arguments[_i];
28865          }
28866          if (!done) {
28867            done = true;
28868            if (timer !== null) {
28869              clearTimeout(timer);
28870              timer = null;
28871            }
28872            completer.apply(null, args);
28873          }
28874        };
28875      };
28876      var resolve = complete(resolveCb);
28877      var reject = complete(rejectCb);
28878      var start = function () {
28879        var args = [];
28880        for (var _i = 0; _i < arguments.length; _i++) {
28881          args[_i] = arguments[_i];
28882        }
28883        if (!done && timer === null) {
28884          timer = setTimeout(function () {
28885            return reject.apply(null, args);
28886          }, timeout);
28887        }
28888      };
28889      return {
28890        start: start,
28891        resolve: resolve,
28892        reject: reject
28893      };
28894    };
28895    var create$8 = function () {
28896      var tasks = {};
28897      var resultFns = {};
28898      var load = function (id, url) {
28899        var loadErrMsg = 'Script at URL "' + url + '" failed to load';
28900        var runErrMsg = 'Script at URL "' + url + '" did not call `tinymce.Resource.add(\'' + id + '\', data)` within 1 second';
28901        if (tasks[id] !== undefined) {
28902          return tasks[id];
28903        } else {
28904          var task = new promiseObj(function (resolve, reject) {
28905            var waiter = awaiter(resolve, reject);
28906            resultFns[id] = waiter.resolve;
28907            ScriptLoader.ScriptLoader.loadScript(url, function () {
28908              return waiter.start(runErrMsg);
28909            }, function () {
28910              return waiter.reject(loadErrMsg);
28911            });
28912          });
28913          tasks[id] = task;
28914          return task;
28915        }
28916      };
28917      var add = function (id, data) {
28918        if (resultFns[id] !== undefined) {
28919          resultFns[id](data);
28920          delete resultFns[id];
28921        }
28922        tasks[id] = promiseObj.resolve(data);
28923      };
28924      return {
28925        load: load,
28926        add: add
28927      };
28928    };
28929    var Resource = create$8();
28930
28931    var each$k = Tools.each, extend$5 = Tools.extend;
28932    var extendClass, initializing;
28933    var Class = function () {
28934    };
28935    Class.extend = extendClass = function (props) {
28936      var self = this;
28937      var _super = self.prototype;
28938      var Class = function () {
28939        var i, mixins, mixin;
28940        var self = this;
28941        if (!initializing) {
28942          if (self.init) {
28943            self.init.apply(self, arguments);
28944          }
28945          mixins = self.Mixins;
28946          if (mixins) {
28947            i = mixins.length;
28948            while (i--) {
28949              mixin = mixins[i];
28950              if (mixin.init) {
28951                mixin.init.apply(self, arguments);
28952              }
28953            }
28954          }
28955        }
28956      };
28957      var dummy = function () {
28958        return this;
28959      };
28960      var createMethod = function (name, fn) {
28961        return function () {
28962          var self = this;
28963          var tmp = self._super;
28964          self._super = _super[name];
28965          var ret = fn.apply(self, arguments);
28966          self._super = tmp;
28967          return ret;
28968        };
28969      };
28970      initializing = true;
28971      var prototype = new self();
28972      initializing = false;
28973      if (props.Mixins) {
28974        each$k(props.Mixins, function (mixin) {
28975          for (var name_1 in mixin) {
28976            if (name_1 !== 'init') {
28977              props[name_1] = mixin[name_1];
28978            }
28979          }
28980        });
28981        if (_super.Mixins) {
28982          props.Mixins = _super.Mixins.concat(props.Mixins);
28983        }
28984      }
28985      if (props.Methods) {
28986        each$k(props.Methods.split(','), function (name) {
28987          props[name] = dummy;
28988        });
28989      }
28990      if (props.Properties) {
28991        each$k(props.Properties.split(','), function (name) {
28992          var fieldName = '_' + name;
28993          props[name] = function (value) {
28994            var self = this;
28995            if (value !== undefined) {
28996              self[fieldName] = value;
28997              return self;
28998            }
28999            return self[fieldName];
29000          };
29001        });
29002      }
29003      if (props.Statics) {
29004        each$k(props.Statics, function (func, name) {
29005          Class[name] = func;
29006        });
29007      }
29008      if (props.Defaults && _super.Defaults) {
29009        props.Defaults = extend$5({}, _super.Defaults, props.Defaults);
29010      }
29011      each$1(props, function (member, name) {
29012        if (typeof member === 'function' && _super[name]) {
29013          prototype[name] = createMethod(name, member);
29014        } else {
29015          prototype[name] = member;
29016        }
29017      });
29018      Class.prototype = prototype;
29019      Class.constructor = Class;
29020      Class.extend = extendClass;
29021      return Class;
29022    };
29023
29024    var min$1 = Math.min, max$1 = Math.max, round$2 = Math.round;
29025    var Color = function (value) {
29026      var self = {};
29027      var r = 0, g = 0, b = 0;
29028      var rgb2hsv = function (r, g, b) {
29029        var h, s, v;
29030        h = 0;
29031        s = 0;
29032        v = 0;
29033        r = r / 255;
29034        g = g / 255;
29035        b = b / 255;
29036        var minRGB = min$1(r, min$1(g, b));
29037        var maxRGB = max$1(r, max$1(g, b));
29038        if (minRGB === maxRGB) {
29039          v = minRGB;
29040          return {
29041            h: 0,
29042            s: 0,
29043            v: v * 100
29044          };
29045        }
29046        var d = r === minRGB ? g - b : b === minRGB ? r - g : b - r;
29047        h = r === minRGB ? 3 : b === minRGB ? 1 : 5;
29048        h = 60 * (h - d / (maxRGB - minRGB));
29049        s = (maxRGB - minRGB) / maxRGB;
29050        v = maxRGB;
29051        return {
29052          h: round$2(h),
29053          s: round$2(s * 100),
29054          v: round$2(v * 100)
29055        };
29056      };
29057      var hsvToRgb = function (hue, saturation, brightness) {
29058        hue = (parseInt(hue, 10) || 0) % 360;
29059        saturation = parseInt(saturation, 10) / 100;
29060        brightness = parseInt(brightness, 10) / 100;
29061        saturation = max$1(0, min$1(saturation, 1));
29062        brightness = max$1(0, min$1(brightness, 1));
29063        if (saturation === 0) {
29064          r = g = b = round$2(255 * brightness);
29065          return;
29066        }
29067        var side = hue / 60;
29068        var chroma = brightness * saturation;
29069        var x = chroma * (1 - Math.abs(side % 2 - 1));
29070        var match = brightness - chroma;
29071        switch (Math.floor(side)) {
29072        case 0:
29073          r = chroma;
29074          g = x;
29075          b = 0;
29076          break;
29077        case 1:
29078          r = x;
29079          g = chroma;
29080          b = 0;
29081          break;
29082        case 2:
29083          r = 0;
29084          g = chroma;
29085          b = x;
29086          break;
29087        case 3:
29088          r = 0;
29089          g = x;
29090          b = chroma;
29091          break;
29092        case 4:
29093          r = x;
29094          g = 0;
29095          b = chroma;
29096          break;
29097        case 5:
29098          r = chroma;
29099          g = 0;
29100          b = x;
29101          break;
29102        default:
29103          r = g = b = 0;
29104        }
29105        r = round$2(255 * (r + match));
29106        g = round$2(255 * (g + match));
29107        b = round$2(255 * (b + match));
29108      };
29109      var toHex = function () {
29110        var hex = function (val) {
29111          val = parseInt(val, 10).toString(16);
29112          return val.length > 1 ? val : '0' + val;
29113        };
29114        return '#' + hex(r) + hex(g) + hex(b);
29115      };
29116      var toRgb = function () {
29117        return {
29118          r: r,
29119          g: g,
29120          b: b
29121        };
29122      };
29123      var toHsv = function () {
29124        return rgb2hsv(r, g, b);
29125      };
29126      var parse = function (value) {
29127        var matches;
29128        if (typeof value === 'object') {
29129          if ('r' in value) {
29130            r = value.r;
29131            g = value.g;
29132            b = value.b;
29133          } else if ('v' in value) {
29134            hsvToRgb(value.h, value.s, value.v);
29135          }
29136        } else {
29137          if (matches = /rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)[^\)]*\)/gi.exec(value)) {
29138            r = parseInt(matches[1], 10);
29139            g = parseInt(matches[2], 10);
29140            b = parseInt(matches[3], 10);
29141          } else if (matches = /#([0-F]{2})([0-F]{2})([0-F]{2})/gi.exec(value)) {
29142            r = parseInt(matches[1], 16);
29143            g = parseInt(matches[2], 16);
29144            b = parseInt(matches[3], 16);
29145          } else if (matches = /#([0-F])([0-F])([0-F])/gi.exec(value)) {
29146            r = parseInt(matches[1] + matches[1], 16);
29147            g = parseInt(matches[2] + matches[2], 16);
29148            b = parseInt(matches[3] + matches[3], 16);
29149          }
29150        }
29151        r = r < 0 ? 0 : r >
29151 255 ? 255 : r;
29152        g = g < 0 ? 0 : g > 255 ? 255 : g;
29153        b = b < 0 ? 0 : b > 255 ? 255 : b;
29154        return self;
29155      };
29156      if (value) {
29157        parse(value);
29158      }
29159      self.toRgb = toRgb;
29160      self.toHsv = toHsv;
29161      self.toHex = toHex;
29162      self.parse = parse;
29163      return self;
29164    };
29165
29166    var serialize = function (obj) {
29167      var data = JSON.stringify(obj);
29168      if (!isString(data)) {
29169        return data;
29170      }
29171      return data.replace(/[\u0080-\uFFFF]/g, function (match) {
29172        var hexCode = match.charCodeAt(0).toString(16);
29173        return '\\u' + '0000'.substring(hexCode.length) + hexCode;
29174      });
29175    };
29176    var JSONUtils = {
29177      serialize: serialize,
29178      parse: function (text) {
29179        try {
29180          return JSON.parse(text);
29181        } catch (ex) {
29182        }
29183      }
29184    };
29185
29186    var JSONP = {
29187      callbacks: {},
29188      count: 0,
29189      send: function (settings) {
29190        var self = this, dom = DOMUtils$1.DOM, count = settings.count !== undefined ? settings.count : self.count;
29191        var id = 'tinymce_jsonp_' + count;
29192        self.callbacks[count] = function (json) {
29193          dom.remove(id);
29194          delete self.callbacks[count];
29195          settings.callback(json);
29196        };
29197        dom.add(dom.doc.body, 'script', {
29198          id: id,
29199          src: settings.url,
29200          type: 'text/javascript'
29201        });
29202        self.count++;
29203      }
29204    };
29205
29206    var XHR = __assign(__assign({}, Observable), {
29207      send: function (settings) {
29208        var xhr, count = 0;
29209        var ready = function () {
29210          if (!settings.async || xhr.readyState === 4 || count++ > 10000) {
29211            if (settings.success && count < 10000 && xhr.status === 200) {
29212              settings.success.call(settings.success_scope, '' + xhr.responseText, xhr, settings);
29213            } else if (settings.error) {
29214              settings.error.call(settings.error_scope, count > 10000 ? 'TIMED_OUT' : 'GENERAL', xhr, settings);
29215            }
29216            xhr = null;
29217          } else {
29218            Delay.setTimeout(ready, 10);
29219          }
29220        };
29221        settings.scope = settings.scope || this;
29222        settings.success_scope = settings.success_scope || settings.scope;
29223        settings.error_scope = settings.error_scope || settings.scope;
29224        settings.async = settings.async !== false;
29225        settings.data = settings.data || '';
29226        XHR.fire('beforeInitialize', { settings: settings });
29227        xhr = new XMLHttpRequest();
29228        if (xhr.overrideMimeType) {
29229          xhr.overrideMimeType(settings.content_type);
29230        }
29231        xhr.open(settings.type || (settings.data ? 'POST' : 'GET'), settings.url, settings.async);
29232        if (settings.crossDomain) {
29233          xhr.withCredentials = true;
29234        }
29235        if (settings.content_type) {
29236          xhr.setRequestHeader('Content-Type', settings.content_type);
29237        }
29238        if (settings.requestheaders) {
29239          Tools.each(settings.requestheaders, function (header) {
29240            xhr.setRequestHeader(header.key, header.value);
29241          });
29242        }
29243        xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
29244        xhr = XHR.fire('beforeSend', {
29245          xhr: xhr,
29246          settings: settings
29247        }).xhr;
29248        xhr.send(settings.data);
29249        if (!settings.async) {
29250          return ready();
29251        }
29252        Delay.setTimeout(ready, 10);
29253      }
29254    });
29255
29256    var extend$6 = Tools.extend;
29257    var JSONRequest = function () {
29258      function JSONRequest(settings) {
29259        this.settings = extend$6({}, settings);
29260        this.count = 0;
29261      }
29262      JSONRequest.sendRPC = function (o) {
29263        return new JSONRequest().send(o);
29264      };
29265      JSONRequest.prototype.send = function (args) {
29266        var ecb = args.error, scb = args.success;
29267        var xhrArgs = extend$6(this.settings, args);
29268        xhrArgs.success = function (c, x) {
29269          c = JSONUtils.parse(c);
29270          if (typeof c === 'undefined') {
29271            c = { error: 'JSON Parse error.' };
29272          }
29273          if (c.error) {
29274            ecb.call(xhrArgs.error_scope || xhrArgs.scope, c.error, x);
29275          } else {
29276            scb.call(xhrArgs.success_scope || xhrArgs.scope, c.result);
29277          }
29278        };
29279        xhrArgs.error = function (ty, x) {
29280          if (ecb) {
29281            ecb.call(xhrArgs.error_scope || xhrArgs.scope, ty, x);
29282          }
29283        };
29284        xhrArgs.data = JSONUtils.serialize({
29285          id: args.id || 'c' + this.count++,
29286          method: args.method,
29287          params: args.params
29288        });
29289        xhrArgs.content_type = 'application/json';
29290        XHR.send(xhrArgs);
29291      };
29292      return JSONRequest;
29293    }();
29294
29295    var create$9 = function () {
29296      return function () {
29297        var data = {};
29298        var keys = [];
29299        var storage = {
29300          getItem: function (key) {
29301            var item = data[key];
29302            return item ? item : null;
29303          },
29304          setItem: function (key, value) {
29305            keys.push(key);
29306            data[key] = String(value);
29307          },
29308          key: function (index) {
29309            return keys[index];
29310          },
29311          removeItem: function (key) {
29312            keys = keys.filter(function (k) {
29313              return k === key;
29314            });
29315            delete data[key];
29316          },
29317          clear: function () {
29318            keys = [];
29319            data = {};
29320          },
29321          length: 0
29322        };
29323        Object.defineProperty(storage, 'length', {
29324          get: function () {
29325            return keys.length;
29326          },
29327          configurable: false,
29328          enumerable: false
29329        });
29330        return storage;
29331      }();
29332    };
29333
29334    var localStorage;
29335    try {
29336      var test = '__storage_test__';
29337      localStorage = window.localStorage;
29338      localStorage.setItem(test, test);
29339      localStorage.removeItem(test);
29340    } catch (e) {
29341      localStorage = create$9();
29342    }
29343    var LocalStorage = localStorage;
29344
29345    var publicApi = {
29346      geom: { Rect: Rect },
29347      util: {
29348        Promise: promiseObj,
29349        Delay: Delay,
29350        Tools: Tools,
29351        VK: VK,
29352        URI: URI,
29353        Class: Class,
29354        EventDispatcher: EventDispatcher,
29355        Observable: Observable,
29356        I18n: I18n,
29357        XHR: XHR,
29358        JSON: JSONUtils,
29359        JSONRequest: JSONRequest,
29360        JSONP: JSONP,
29361        LocalStorage: LocalStorage,
29362        Color: Color
29363      },
29364      dom: {
29365        EventUtils: EventUtils,
29366        Sizzle: Sizzle,
29367        DomQuery: DomQuery,
29368        TreeWalker: DomTreeWalker,
29369        TextSeeker: TextSeeker,
29370        DOMUtils: DOMUtils$1,
29371        ScriptLoader: ScriptLoader,
29372        RangeUtils: RangeUtils$1,
29373        Serializer: DomSerializer,
29374        StyleSheetLoader: StyleSheetLoader,
29375        ControlSelection: ControlSelection,
29376        BookmarkManager: BookmarkManager$1,
29377        Selection: EditorSelection,
29378        Event: EventUtils.Event
29379      },
29380      html: {
29381        Styles: Styles,
29382        Entities: Entities,
29383        Node: AstNode,
29384        Schema: Schema,
29385        SaxParser: SaxParser$1,
29386        DomParser: DomParser,
29387        Writer: Writer,
29388        Serializer: HtmlSerializer
29389      },
29390      Env: Env,
29391      AddOnManager: AddOnManager$1,
29392      Annotator: Annotator,
29393      Formatter: Formatter,
29394      UndoManager: UndoManager,
29395      EditorCommands: EditorCommands,
29396      WindowManager: WindowManager,
29397      NotificationManager: NotificationManager,
29398      EditorObservable: EditorObservable,
29399      Shortcuts: Shortcuts,
29400      Editor: Editor,
29401      FocusManager: FocusManager,
29402      EditorManager: EditorManager,
29403      DOM: DOMUtils$1.DOM,
29404      ScriptLoader: ScriptLoader.ScriptLoader,
29405      PluginManager: PluginManager,
29406      ThemeManager: ThemeManager,
29407      IconManager: IconManager,
29408      Resource: Resource,
29409      trim: Tools.trim,
29410      isArray: Tools.isArray,
29411      is: Tools.is,
29412      toArray: Tools.toArray,
29413      makeMap: Tools.makeMap,
29414      each: Tools.each,
29415      map: Tools.map,
29416      grep: Tools.grep,
29417      inArray: Tools.inArray,
29418      extend: Tools.extend,
29419      create: Tools.create,
29420      walk: Tools.walk,
29421      createNS: Tools.createNS,
29422      resolve: Tools.resolve,
29423      explode: Tools.explode,
29424      _addCacheSuffix: Tools._addCacheSuffix,
29425      isOpera: Env.opera,
29426      isWebKit: Env.webkit,
29427      isIE: Env.ie,
29428      isGecko: Env.gecko,
29429      isMac: Env.mac
29430    };
29431    var tinymce = Tools.extend(EditorManager, publicApi);
29432
29433    var exportToModuleLoaders = function (tinymce) {
29434      if (typeof module === 'object') {
29435        try {
29436          module.exports = tinymce;
29437        } catch (_) {
29438        }
29439      }
29440    };
29441    var exportToWindowGlobal = function (tinymce) {
29442      window.tinymce = tinymce;
29443      window.tinyMCE = tinymce;
29444    };
29445    exportToWindowGlobal(tinymce);
29446    exportToModuleLoaders(tinymce);
29447
29448}());

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.