PageSourceSearch

https://www.mapcon.com/lib/tinymce/plugins/lists/plugin.ni0mkqthwk.js

js mapcon.com collected 2026-09-24 11:35:02 UTC 104,127 bytes, 2,544 lines download raw bytes

vendor: 7,545 bytes, lines 1-203
1/**
2 * TinyMCE version 7.9.1 (2025-05-29)
3 */
4
5(function () {
6    'use strict';
7
8    var global$7 = tinymce.util.Tools.resolve('tinymce.PluginManager');
9
10    /* eslint-disable @typescript-eslint/no-wrapper-object-types */
11    const hasProto = (v, constructor, predicate) => {
12        var _a;
13        if (predicate(v, constructor.prototype)) {
14            return true;
15        }
16        else {
17            // String-based fallback time
18            return ((_a = v.constructor) === null || _a === void 0 ? void 0 : _a.name) === constructor.name;
19        }
20    };
21    const typeOf = (x) => {
22        const t = typeof x;
23        if (x === null) {
24            return 'null';
25        }
26        else if (t === 'object' && Array.isArray(x)) {
27            return 'array';
28        }
29        else if (t === 'object' && hasProto(x, String, (o, proto) => proto.isPrototypeOf(o))) {
30            return 'string';
31        }
32        else {
33            return t;
34        }
35    };
36    const isType$1 = (type) => (value) => typeOf(value) === type;
37    const isSimpleType = (type) => (value) => typeof value === type;
38    const isString = isType$1('string');
39    const isObject = isType$1('object');
40    const isArray = isType$1('array');
41    const isBoolean = isSimpleType('boolean');
42    const isNullable = (a) => a === null || a === undefined;
43    const isNonNullable = (a) => !isNullable(a);
44    const isFunction = isSimpleType('function');
45    const isNumber = isSimpleType('number');
46
47    const noop = () => { };
48    /** Compose two unary functions. Similar to compose, but avoids using Function.prototype.apply. */
49    const compose1 = (fbc, fab) => (a) => fbc(fab(a));
50    const constant = (value) => {
51        return () => {
52            return value;
53        };
54    };
55    const tripleEquals = (a, b) => {
56        return a === b;
57    };
58    // eslint-disable-next-line prefer-arrow/prefer-arrow-functions
59    function curry(fn, ...initialArgs) {
60        return (...restArgs) => {
61            const all = initialArgs.concat(restArgs);
62            return fn.apply(null, all);
63        };
64    }
65    const not = (f) => (t) => !f(t);
66    const never = constant(false);
67
68    /**
69     * The `Optional` type represents a value (of any type) that potentially does
70     * not exist. Any `Optional<T>` can either be a `Some<T>` (in which case the
71     * value does exist) or a `None` (in which case the value does not exist). This
72     * module defines a whole lot of FP-inspired utility functions for dealing with
73     * `Optional` objects.
74     *
75     * Comparison with null or undefined:
76     * - We don't get fancy null coalescing operators with `Optional`
77     * - We do get fancy helper functions with `Optional`
78     * - `Optional` support nesting, and allow for the type to still be nullable (or
79     * another `Optional`)
80     * - There is no option to turn off strict-optional-checks like there is for
81     * strict-null-checks
82     */
83    class Optional {
84        // The internal representation has a `tag` and a `value`, but both are
85        // private: able to be console.logged, but not able to be accessed by code
86        constructor(tag, value) {
87            this.tag = tag;
88            this.value = value;
89        }
90        // --- Identities ---
91        /**
92         * Creates a new `Optional<T>` that **does** contain a value.
93         */
94        static some(value) {
95            return new Optional(true, value);
96        }
97        /**
98         * Create a new `Optional<T>` that **does not** contain a value. `T` can be
99         * any type because we don't actually have a `T`.
100         */
101        static none() {
102            return Optional.singletonNone;
103        }
104        /**
105         * Perform a transform on an `Optional` type. Regardless of whether this
106         * `Optional` contains a value or not, `fold` will return a value of type `U`.
107         * If this `Optional` does not contain a value, the `U` will be created by
108         * calling `onNone`. If this `Optional` does contain a value, the `U` will be
109         * created by calling `onSome`.
110         *
111         * For the FP enthusiasts in the room, this function:
112         * 1. Could be used to implement all of the functions below
113         * 2. Forms a catamorphism
114         */
115        fold(onNone, onSome) {
116            if (this.tag) {
117                return onSome(this.value);
118            }
119            else {
120                return onNone();
121            }
122        }
123        /**
124         * Determine if this `Optional` object contains a value.
125         */
126        isSome() {
127            return this.tag;
128        }
129        /**
130         * Determine if this `Optional` object **does not** contain a value.
131         */
132        isNone() {
133            return !this.tag;
134        }
135        // --- Functor (name stolen from Haskell / maths) ---
136        /**
137         * Perform a transform on an `Optional` object, **if** there is a value. If
138         * you provide a function to turn a T into a U, this is the function you use
139         * to turn an `Optional<T>` into an `Optional<U>`. If this **does** contain
140         * a value then the output will also contain a value (that value being the
141         * output of `mapper(this.value)`), and if this **does not** contain a value
142         * then neither will the output.
143         */
144        map(mapper) {
145            if (this.tag) {
146                return Optional.some(mapper(this.value));
147            }
148            else {
149                return Optional.none();
150            }
151        }
152        // --- Monad (name stolen from Haskell / maths) ---
153        /**
154         * Perform a transform on an `Optional` object, **if** there is a value.
155         * Unlike `map`, here the transform itself also returns an `Optional`.
156         */
157        bind(binder) {
158            if (this.tag) {
159                return binder(this.value);
160            }
161            else {
162                return Optional.none();
163            }
164        }
165        // --- Traversable (name stolen from Haskell / maths) ---
166        /**
167         * For a given predicate, this function finds out if there **exists** a value
168         * inside this `Optional` object that meets the predicate. In practice, this
169         * means that for `Optional`s that do not contain a value it returns false (as
170         * no predicate-meeting value exists).
171         */
172        exists(predicate) {
173            return this.tag && predicate(this.value);
174        }
175        /**
176         * For a given predicate, this function finds out if **all** the values inside
177         * this `Optional` object meet the predicate. In practice, this means that
178         * for `Optional`s that do not contain a value it returns true (as all 0
179         * objects do meet the predicate).
180         */
181        forall(predicate) {
182            return !this.tag || predicate(this.value);
183        }
184        filter(predicate) {
185            if (!this.tag || predicate(this.value)) {
186                return this;
187            }
188            else {
189                return Optional.none();
190            }
191        }
192        // --- Getters ---
193        /**
194         * Get the value out of the inside of the `Optional` object, using a default
195         * `replacement` value if the provided `Optional` object does not contain a
196         * value.
197         */
198        getOr(replacement) {
199            return this.tag ? this.value : replacement;
200        }
201        /**
202         * Get the value out of the inside of the `Optional` object, using a default
203         * `replacement` value if the provided `Optional` object does not contain a
204         * value.  Unlike `getOr`, in this method the `replacement` object is also
205         * `Optional` - meaning that this method will always return an `Optional`.
206         */
207        or(replacement) {
208            return this.tag ? this : replacement;
209        }
210        /**
211         * Get the value out of the inside of the `Optional` object, using a default
212         * `replacement` value if the provided `Optional` object does not contain a
213         * value. Unlike `getOr`, in this method the `replacement` value is
214         * "thunked" - that is to say that you don't pass a value to `getOrThunk`, you
215         * pass a function which (if called) will **return** the `value` you want to
216         * use.
217         */
218        getOrThunk(thunk) {
219            return this.tag ? this.value : thunk();
220        }
221        /**
222         * Get the value out of the inside of the `Optional` object, using a default
223         * `replacement` value if the provided Optional object does not contain a
224         * value.
225         *
226         * Unlike `or`, in this method the `replacement` value is "thunked" - that is
227         * to say that you don't pass a value to `orThunk`, you pass a function which
228         * (if called) will **return** the `value` you want to use.
229         *
230         * Unlike `getOrThunk`, in this method the `replacement` value is also
231         * `Optional`, meaning that this method will always return an `Optional`.
232         */
233        orThunk(thunk) {
234            return this.tag ? this : thunk();
235        }
236        /**
237         * Get the value out of the inside of the `Optional` object, throwing an
238         * exception if the provided `Optional` object does not contain a value.
239         *
240         * WARNING:
241         * You should only be using this function if you know that the `Optional`
242         * object **is not** empty (otherwise you're throwing exceptions in production
243         * code, which is bad).
244         *
245         * In tests this is more acceptable.
246         *
247         * Prefer other methods to this, such as `.each`.
248         */
249        getOrDie(message) {
250            if (!this.tag) {
251                throw new Error(message !== null && message !== void 0 ? message : 'Called getOrDie on None');
252            }
253            else {
254                return this.value;
255            }
256        }
257        // --- Interop with null and undefined ---
258        /**
vendor: 49,934 bytes, lines 259-1476
259         * Creates an `Optional` value from a nullable (or undefined-able) input.
260         * Null, or undefined, is converted to `None`, and anything else is converted
261         * to `Some`.
262         */
263        static from(value) {
264            return isNonNullable(value) ? Optional.some(value) : Optional.none();
265        }
266        /**
267         * Converts an `Optional` to a nullable type, by getting the value if it
268         * exists, or returning `null` if it does not.
269         */
270        getOrNull() {
271            return this.tag ? this.value : null;
272        }
273        /**
274         * Converts an `Optional` to an undefined-able type, by getting the value if
275         * it exists, or returning `undefined` if it does not.
276         */
277        getOrUndefined() {
278            return this.value;
279        }
280        // --- Utilities ---
281        /**
282         * If the `Optional` contains a value, perform an action on that value.
283         * Unlike the rest of the methods on this type, `.each` has side-effects. If
284         * you want to transform an `Optional<T>` **into** something, then this is not
285         * the method for you. If you want to use an `Optional<T>` to **do**
286         * something, then this is the method for you - provided you're okay with not
287         * doing anything in the case where the `Optional` doesn't have a value inside
288         * it. If you're not sure whether your use-case fits into transforming
289         * **into** something or **doing** something, check whether it has a return
290         * value. If it does, you should be performing a transform.
291         */
292        each(worker) {
293            if (this.tag) {
294                worker(this.value);
295            }
296        }
297        /**
298         * Turn the `Optional` object into an array that contains all of the values
299         * stored inside the `Optional`. In practice, this means the output will have
300         * either 0 or 1 elements.
301         */
302        toArray() {
303            return this.tag ? [this.value] : [];
304        }
305        /**
306         * Turn the `Optional` object into a string for debugging or printing. Not
307         * recommended for production code, but good for debugging. Also note that
308         * these days an `Optional` object can be logged to the console directly, and
309         * its inner value (if it exists) will be visible.
310         */
311        toString() {
312            return this.tag ? `some(${this.value})` : 'none()';
313        }
314    }
315    // Sneaky optimisation: every instance of Optional.none is identical, so just
316    // reuse the same object
317    Optional.singletonNone = new Optional(false);
318
319    /* eslint-disable @typescript-eslint/unbound-method */
320    const nativeSlice = Array.prototype.slice;
321    const nativeIndexOf = Array.prototype.indexOf;
322    const nativePush = Array.prototype.push;
323    /* eslint-enable */
324    const rawIndexOf = (ts, t) => nativeIndexOf.call(ts, t);
325    const contains$1 = (xs, x) => rawIndexOf(xs, x) > -1;
326    const exists = (xs, pred) => {
327        for (let i = 0, len = xs.length; i < len; i++) {
328            const x = xs[i];
329            if (pred(x, i)) {
330                return true;
331            }
332        }
333        return false;
334    };
335    const map = (xs, f) => {
336        // pre-allocating array size when it's guaranteed to be known
337        // http://jsperf.com/push-allocated-vs-dynamic/22
338        const len = xs.length;
339        const r = new Array(len);
340        for (let i = 0; i < len; i++) {
341            const x = xs[i];
342            r[i] = f(x, i);
343        }
344        return r;
345    };
346    // Unwound implementing other functions in terms of each.
347    // The code size is roughly the same, and it should allow for better optimisation.
348    // const each = function<T, U>(xs: T[], f: (x: T, i?: number, xs?: T[]) => void): void {
349    const each$1 = (xs, f) => {
350        for (let i = 0, len = xs.length; i < len; i++) {
351            const x = xs[i];
352            f(x, i);
353        }
354    };
355    const filter$1 = (xs, pred) => {
356        const r = [];
357        for (let i = 0, len = xs.length; i < len; i++) {
358            const x = xs[i];
359            if (pred(x, i)) {
360                r.push(x);
361            }
362        }
363        return r;
364    };
365    /*
366     * Groups an array into contiguous arrays of like elements. Whether an element is like or not depends on f.
367     *
368     * f is a function that derives a value from an element - e.g. true or false, or a string.
369     * Elements are like if this function generates the same value for them (according to ===).
370     *
371     *
372     * Order of the elements is preserved. Arr.flatten() on the result will return the original list, as with Haskell groupBy function.
373     *  For a good explanation, see the group function (which is a special case of groupBy)
374     *  http://hackage.haskell.org/package/base-4.7.0.0/docs/Data-List.html#v:group
375     */
376    const groupBy = (xs, f) => {
377        if (xs.length === 0) {
378            return [];
379        }
380        else {
381            let wasType = f(xs[0]); // initial case for matching
382            const r = [];
383            let group = [];
384            for (let i = 0, len = xs.length; i < len; i++) {
385                const x = xs[i];
386                const type = f(x);
387                if (type !== wasType) {
388                    r.push(group);
389                    group = [];
390                }
391                wasType = type;
392                group.push(x);
393            }
394            if (group.length !== 0) {
395                r.push(group);
396            }
397            return r;
398        }
399    };
400    const foldl = (xs, f, acc) => {
401        each$1(xs, (x, i) => {
402            acc = f(acc, x, i);
403        });
404        return acc;
405    };
406    const findUntil = (xs, pred, until) => {
407        for (let i = 0, len = xs.length; i < len; i++) {
408            const x = xs[i];
409            if (pred(x, i)) {
410                return Optional.some(x);
411            }
412            else if (until(x, i)) {
413                break;
414            }
415        }
416        return Optional.none();
417    };
418    const find = (xs, pred) => {
419        return findUntil(xs, pred, never);
420    };
421    const flatten = (xs) => {
422        // Note, this is possible because push supports multiple arguments:
423        // http://jsperf.com/concat-push/6
424        // Note that in the past, concat() would silently work (very slowly) for array-like objects.
425        // With this change it will throw an error.
426        const r = [];
427        for (let i = 0, len = xs.length; i < len; ++i) {
428            // Ensure that each value is an array itself
429            if (!isArray(xs[i])) {
430                throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs);
431            }
432            nativePush.apply(r, xs[i]);
433        }
434        return r;
435    };
436    const bind = (xs, f) => flatten(map(xs, f));
437    const reverse = (xs) => {
438        const r = nativeSlice.call(xs, 0);
439        r.reverse();
440        return r;
441    };
442    const get$1 = (xs, i) => i >= 0 && i < xs.length ? Optional.some(xs[i]) : Optional.none();
443    const head = (xs) => get$1(xs, 0);
444    const last = (xs) => get$1(xs, xs.length - 1);
445    const unique = (xs, comparator) => {
446        const r = [];
447        const isDuplicated = isFunction(comparator) ?
448            (x) => exists(r, (i) => comparator(i, x)) :
449            (x) => contains$1(r, x);
450        for (let i = 0, len = xs.length; i < len; i++) {
451            const x = xs[i];
452            if (!isDuplicated(x)) {
453                r.push(x);
454            }
455        }
456        return r;
457    };
458
459    // There are many variations of Object iteration that are faster than the 'for-in' style:
460    // http://jsperf.com/object-keys-iteration/107
461    //
462    // Use the native keys if it is available (IE9+), otherwise fall back to manually filtering
463    const keys = Object.keys;
464    const each = (obj, f) => {
465        const props = keys(obj);
466        for (let k = 0, len = props.length; k < len; k++) {
467            const i = props[k];
468            const x = obj[i];
469            f(x, i);
470        }
471    };
472    const objAcc = (r) => (x, i) => {
473        r[i] = x;
474    };
475    const internalFilter = (obj, pred, onTrue, onFalse) => {
476        each(obj, (x, i) => {
477            (pred(x, i) ? onTrue : onFalse)(x, i);
478        });
479    };
480    const filter = (obj, pred) => {
481        const t = {};
482        internalFilter(obj, pred, objAcc(t), noop);
483        return t;
484    };
485
486    const Cell = (initial) => {
487        let value = initial;
488        const get = () => {
489            return value;
490        };
491        const set = (v) => {
492            value = v;
493        };
494        return {
495            get,
496            set
497        };
498    };
499
500    // Use window object as the global if it's available since CSP will block script evals
501    // eslint-disable-next-line @typescript-eslint/no-implied-eval
502    const Global = typeof window !== 'undefined' ? window : Function('return this;')();
503
504    /**
505     * **Is** the value stored inside this Optional object equal to `rhs`?
506     */
507    const is$2 = (lhs, rhs, comparator = tripleEquals) => lhs.exists((left) => comparator(left, rhs));
508    /**
509     * Are these two Optional objects equal? Equality here means either they're both
510     * `Some` (and the values are equal under the comparator) or they're both `None`.
511     */
512    const equals = (lhs, rhs, comparator = tripleEquals) => lift2(lhs, rhs, comparator).getOr(lhs.isNone() && rhs.isNone());
513    /*
514    Notes on the lift functions:
515    - We used to have a generic liftN, but we were concerned about its type-safety, and the below variants were faster in microbenchmarks.
516    - The getOrDie calls are partial functions, but are checked beforehand. This is faster and more convenient (but less safe) than folds.
517    - && is used instead of a loop for simplicity and performance.
518    */
519    const lift2 = (oa, ob, f) => oa.isSome() && ob.isSome() ? Optional.some(f(oa.getOrDie(), ob.getOrDie())) : Optional.none();
520
521    /** path :: ([String], JsObj?) -> JsObj */
522    const path = (parts, scope) => {
523        let o = scope !== undefined && scope !== null ? scope : Global;
524        for (let i = 0; i < parts.length && o !== undefined && o !== null; ++i) {
525            o = o[parts[i]];
526        }
527        return o;
528    };
529    /** resolve :: (String, JsObj?) -> JsObj */
530    const resolve = (p, scope) => {
531        const parts = p.split('.');
532        return path(parts, scope);
533    };
534
535    const blank = (r) => (s) => s.replace(r, '');
536    /** removes all leading and trailing spaces */
537    const trim = blank(/^\s+|\s+$/g);
538    const isNotEmpty = (s) => s.length > 0;
539    const isEmpty$2 = (s) => !isNotEmpty(s);
540
541    const zeroWidth = '\uFEFF';
542    const isZwsp = (char) => char === zeroWidth;
543
544    const fromHtml = (html, scope) => {
545        const doc = scope || document;
546        const div = doc.createElement('div');
547        div.innerHTML = html;
548        if (!div.hasChildNodes() || div.childNodes.length > 1) {
549            const message = 'HTML does not have a single root node';
550            // eslint-disable-next-line no-console
551            console.error(message, html);
552            throw new Error(message);
553        }
554        return fromDom$1(div.childNodes[0]);
555    };
556    const fromTag = (tag, scope) => {
557        const doc = scope || document;
558        const node = doc.createElement(tag);
559        return fromDom$1(node);
560    };
561    const fromText = (text, scope) => {
562        const doc = scope || document;
563        const node = doc.createTextNode(text);
564        return fromDom$1(node);
565    };
566    const fromDom$1 = (node) => {
567        // TODO: Consider removing this check, but left atm for safety
568        if (node === null || node === undefined) {
569            throw new Error('Node cannot be null or undefined');
570        }
571        return {
572            dom: node
573        };
574    };
575    const fromPoint = (docElm, x, y) => Optional.from(docElm.dom.elementFromPoint(x, y)).map(fromDom$1);
576    // tslint:disable-next-line:variable-name
577    const SugarElement = {
578        fromHtml,
579        fromTag,
580        fromText,
581        fromDom: fromDom$1,
582        fromPoint
583    };
584
585    const COMMENT = 8;
586    const DOCUMENT_FRAGMENT = 11;
587    const ELEMENT = 1;
588    const TEXT = 3;
589
590    const is$1 = (element, selector) => {
591        const dom = element.dom;
592        if (dom.nodeType !== ELEMENT) {
593            return false;
594        }
595        else {
596            const elem = dom;
597            if (elem.matches !== undefined) {
598                return elem.matches(selector);
599            }
600            else if (elem.msMatchesSelector !== undefined) {
601                return elem.msMatchesSelector(selector);
602            }
603            else if (elem.webkitMatchesSelector !== undefined) {
604                return elem.webkitMatchesSelector(selector);
605            }
606            else if (elem.mozMatchesSelector !== undefined) {
607                // cast to any as mozMatchesSelector doesn't exist in TS DOM lib
608                return elem.mozMatchesSelector(selector);
609            }
610            else {
611                throw new Error('Browser lacks native selectors');
612            } // unfortunately we can't throw this on startup :(
613        }
614    };
615
616    const eq = (e1, e2) => e1.dom === e2.dom;
617    // Returns: true if node e1 contains e2, otherwise false.
618    // (returns false if e1===e2: A node does not contain itself).
619    const contains = (e1, e2) => {
620        const d1 = e1.dom;
621        const d2 = e2.dom;
622        return d1 === d2 ? false : d1.contains(d2);
623    };
624    const is = is$1;
625
626    const unsafe = (name, scope) => {
627        return resolve(name, scope);
628    };
629    const getOrDie = (name, scope) => {
630        const actual = unsafe(name, scope);
631        if (actual === undefined || actual === null) {
632            throw new Error(name + ' not available on this browser');
633        }
634        return actual;
635    };
636
637    const getPrototypeOf = Object.getPrototypeOf;
638    /*
639     * IE9 and above
640     *
641     * MDN no use on this one, but here's the link anyway:
642     * https://developer.mozilla.org/en/docs/Web/API/HTMLElement
643     */
644    const sandHTMLElement = (scope) => {
645        return getOrDie('HTMLElement', scope);
646    };
647    const isPrototypeOf = (x) => {
648        // use Resolve to get the window object for x and just return undefined if it can't find it.
649        // undefined scope later triggers using the global window.
650        const scope = resolve('ownerDocument.defaultView', x);
651        // TINY-7374: We can't rely on looking at the owner window HTMLElement as the element may have
652        // been constructed in a different window and then appended to the current window document.
653        return isObject(x) && (sandHTMLElement(scope).prototype.isPrototypeOf(x) || /^HTML\w*Element$/.test(getPrototypeOf(x).constructor.name));
654    };
655
656    const name = (element) => {
657        const r = element.dom.nodeName;
658        return r.toLowerCase();
659    };
660    const type = (element) => element.dom.nodeType;
661    const isType = (t) => (element) => type(element) === t;
662    const isComment = (element) => type(element) === COMMENT || name(element) === '#comment';
663    const isHTMLElement = (element) => isElement$1(element) && isPrototypeOf(element.dom);
664    const isElement$1 = isType(ELEMENT);
665    const isText = isType(TEXT);
666    const isDocumentFragment = isType(DOCUMENT_FRAGMENT);
667    const isTag = (tag) => (e) => isElement$1(e) && name(e) === tag;
668
669    const parent = (element) => Optional.from(element.dom.parentNode).map(SugarElement.fromDom);
670    const parentElement = (element) => Optional.from(element.dom.parentElement).map(SugarElement.fromDom);
671    const nextSibling = (element) => Optional.from(element.dom.nextSibling).map(SugarElement.fromDom);
672    const children = (element) => map(element.dom.childNodes, SugarElement.fromDom);
673    const child = (element, index) => {
674        const cs = element.dom.childNodes;
675        return Optional.from(cs[index]).map(SugarElement.fromDom);
676    };
677    const firstChild = (element) => child(element, 0);
678    const lastChild = (element) => child(element, element.dom.childNodes.length - 1);
679
680    /**
681     * Is the element a ShadowRoot?
682     *
683     * Note: this is insufficient to test if any element is a shadow root, but it is sufficient to differentiate between
684     * a Document and a ShadowRoot.
685     */
686    const isShadowRoot = (dos) => isDocumentFragment(dos) && isNonNullable(dos.dom.host);
687    const getRootNode = (e) => SugarElement.fromDom(e.dom.getRootNode());
688    /** If this element is in a ShadowRoot, return it. */
689    const getShadowRoot = (e) => {
690        const r = getRootNode(e);
691        return isShadowRoot(r) ? Optional.some(r) : Optional.none();
692    };
693    /** Return the host of a ShadowRoot.
694     *
695     * This function will throw if Shadow DOM is unsupported in the browser, or if the host is null.
696     * If you actually have a ShadowRoot, this shouldn't happen.
697     */
698    const getShadowHost = (e) => SugarElement.fromDom(e.dom.host);
699
700    const before$1 = (marker, element) => {
701        const parent$1 = parent(marker);
702        parent$1.each((v) => {
703            v.dom.insertBefore(element.dom, marker.dom);
704        });
705    };
706    const after = (marker, element) => {
707        const sibling = nextSibling(marker);
708        sibling.fold(() => {
709            const parent$1 = parent(marker);
710            parent$1.each((v) => {
711                append$1(v, element);
712            });
713        }, (v) => {
714            before$1(v, element);
715        });
716    };
717    const prepend = (parent, element) => {
718        const firstChild$1 = firstChild(parent);
719        firstChild$1.fold(() => {
720            append$1(parent, element);
721        }, (v) => {
722            parent.dom.insertBefore(element.dom, v.dom);
723        });
724    };
725    const append$1 = (parent, element) => {
726        parent.dom.appendChild(element.dom);
727    };
728
729    const before = (marker, elements) => {
730        each$1(elements, (x) => {
731            before$1(marker, x);
732        });
733    };
734    const append = (parent, elements) => {
735        each$1(elements, (x) => {
736            append$1(parent, x);
737        });
738    };
739
740    const rawSet = (dom, key, value) => {
741        /*
742         * JQuery coerced everything to a string, and silently did nothing on text node/null/undefined.
743         *
744         * We fail on those invalid cases, only allowing numbers and booleans.
745         */
746        if (isString(value) || isBoolean(value) || isNumber(value)) {
747            dom.setAttribute(key, value + '');
748        }
749        else {
750            // eslint-disable-next-line no-console
751            console.error('Invalid call to Attribute.set. Key ', key, ':: Value ', value, ':: Element ', dom);
752            throw new Error('Attribute value was not simple');
753        }
754    };
755    const setAll = (element, attrs) => {
756        const dom = element.dom;
757        each(attrs, (v, k) => {
758            rawSet(dom, k, v);
759        });
760    };
761    const clone$1 = (element) => foldl(element.dom.attributes, (acc, attr) => {
762        acc[attr.name] = attr.value;
763        return acc;
764    }, {});
765
766    const empty = (element) => {
767        // shortcut "empty node" trick. Requires IE 9.
768        element.dom.textContent = '';
769        // If the contents was a single empty text node, the above doesn't remove it. But, it's still faster in general
770        // than removing every child node manually.
771        // The following is (probably) safe for performance as 99.9% of the time the trick works and
772        // Traverse.children will return an empty array.
773        each$1(children(element), (rogue) => {
774            remove(rogue);
775        });
776    };
777    const remove = (element) => {
778        const dom = element.dom;
779        if (dom.parentNode !== null) {
780            dom.parentNode.removeChild(dom);
781        }
782    };
783
784    const clone = (original, isDeep) => SugarElement.fromDom(original.dom.cloneNode(isDeep));
785    /** Deep clone - everything copied including children */
786    const deep = (original) => clone(original, true);
787    /** Shallow clone, with a new tag */
788    const shallowAs = (original, tag) => {
789        const nu = SugarElement.fromTag(tag);
790        const attributes = clone$1(original);
791        setAll(nu, attributes);
792        return nu;
793    };
794    /** Change the tag name, but keep all children */
795    const mutate = (original, tag) => {
796        const nu = shallowAs(original, tag);
797        after(original, nu);
798        const children$1 = children(original);
799        append(nu, children$1);
800        remove(original);
801        return nu;
802    };
803
804    const fromDom = (nodes) => map(nodes, SugarElement.fromDom);
805
806    // some elements, such as mathml, don't have style attributes
807    // others, such as angular elements, have style attributes that aren't a CSSStyleDeclaration
808    const isSupported = (dom) => 
809    // eslint-disable-next-line @typescript-eslint/unbound-method
810    dom.style !== undefined && isFunction(dom.style.getPropertyValue);
811
812    // Node.contains() is very, very, very good performance
813    // http://jsperf.com/closest-vs-contains/5
814    const inBody = (element) => {
815        // Technically this is only required on IE, where contains() returns false for text nodes.
816        // But it's cheap enough to run everywhere and Sugar doesn't have platform detection (yet).
817        const dom = isText(element) ? element.dom.parentNode : element.dom;
818        // use ownerDocument.body to ensure this works inside iframes.
819        // Normally contains is bad because an element "contains" itself, but here we want that.
820        if (dom === undefined || dom === null || dom.ownerDocument === null) {
821            return false;
822        }
823        const doc = dom.ownerDocument;
824        return getShadowRoot(SugarElement.fromDom(dom)).fold(() => doc.body.contains(dom), compose1(inBody, getShadowHost));
825    };
826
827    const internalSet = (dom, property, value) => {
828        // This is going to hurt. Apologies.
829        // JQuery coerces numbers to pixels for certain property names, and other times lets numbers through.
830        // we're going to be explicit; strings only.
831        if (!isString(value)) {
832            // eslint-disable-next-line no-console
833            console.error('Invalid call to CSS.set. Property ', property, ':: Value ', value, ':: Element ', dom);
834            throw new Error('CSS value must be a string: ' + value);
835        }
836        // removed: support for dom().style[property] where prop is camel case instead of normal property name
837        if (isSupported(dom)) {
838            dom.style.setProperty(property, value);
839        }
840    };
841    const set = (element, property, value) => {
842        const dom = element.dom;
843        internalSet(dom, property, value);
844    };
845
846    const fromElements = (elements, scope) => {
847        const doc = scope || document;
848        const fragment = doc.createDocumentFragment();
849        each$1(elements, (element) => {
850            fragment.appendChild(element.dom);
851        });
852        return SugarElement.fromDom(fragment);
853    };
854
855    var ClosestOrAncestor = (is, ancestor, scope, a, isRoot) => {
856        if (is(scope, a)) {
857            return Optional.some(scope);
858        }
859        else if (isFunction(isRoot) && isRoot(scope)) {
860            return Optional.none();
861        }
862        else {
863            return ancestor(scope, a, isRoot);
864        }
865    };
866
867    const ancestor$3 = (scope, predicate, isRoot) => {
868        let element = scope.dom;
869        const stop = isFunction(isRoot) ? isRoot : never;
870        while (element.parentNode) {
871            element = element.parentNode;
872            const el = SugarElement.fromDom(element);
873            if (predicate(el)) {
874                return Optional.some(el);
875            }
876            else if (stop(el)) {
877                break;
878            }
879        }
880        return Optional.none();
881    };
882    const closest$2 = (scope, predicate, isRoot) => {
883        // This is required to avoid ClosestOrAncestor passing the predicate to itself
884        const is = (s, test) => test(s);
885        return ClosestOrAncestor(is, ancestor$3, scope, predicate, isRoot);
886    };
887
888    const ancestor$2 = (scope, selector, isRoot) => ancestor$3(scope, (e) => is$1(e, selector), isRoot);
889    // Returns Some(closest ancestor element (sugared)) matching 'selector' up to isRoot, or None() otherwise
890    const closest$1 = (scope, selector, isRoot) => {
891        const is = (element, selector) => is$1(element, selector);
892        return ClosestOrAncestor(is, ancestor$2, scope, selector, isRoot);
893    };
894
895    const closest = (target) => closest$1(target, '[contenteditable]');
896    const isEditable = (element, assumeEditable = false) => {
897        if (inBody(element)) {
898            return element.dom.isContentEditable;
899        }
900        else {
901            // Find the closest contenteditable element and check if it's editable
902            return closest(element).fold(constant(assumeEditable), (editable) => getRaw(editable) === 'true');
903        }
904    };
905    const getRaw = (element) => element.dom.contentEditable;
906
907    const ancestor$1 = (scope, predicate, isRoot) => ancestor$3(scope, predicate, isRoot).isSome();
908
909    const ancestor = (element, target) => ancestor$1(element, curry(eq, target));
910
911    var global$6 = tinymce.util.Tools.resolve('tinymce.dom.RangeUtils');
912
913    var global$5 = tinymce.util.Tools.resolve('tinymce.dom.TreeWalker');
914
915    var global$4 = tinymce.util.Tools.resolve('tinymce.util.VK');
916
917    var global$3 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils');
918
919    var global$2 = tinymce.util.Tools.resolve('tinymce.util.Tools');
920
921    const matchNodeName = (name) => (node) => isNonNullable(node) && node.nodeName.toLowerCase() === name;
922    const matchNodeNames = (regex) => (node) => isNonNullable(node) && regex.test(node.nodeName);
923    const isTextNode$1 = (node) => isNonNullable(node) && node.nodeType === 3;
924    const isElement = (node) => isNonNullable(node) && node.nodeType === 1;
925    const isListNode = matchNodeNames(/^(OL|UL|DL)$/);
926    const isOlUlNode = matchNodeNames(/^(OL|UL)$/);
927    const isOlNode = matchNodeName('ol');
928    const isListItemNode = matchNodeNames(/^(LI|DT|DD)$/);
929    const isDlItemNode = matchNodeNames(/^(DT|DD)$/);
930    const isTableCellNode = matchNodeNames(/^(TH|TD)$/);
931    const isBr = matchNodeName('br');
932    const isFirstChild = (node) => { var _a; return ((_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.firstChild) === node; };
933    const isTextBlock = (editor, node) => isNonNullable(node) && node.nodeName in editor.schema.getTextBlockElements();
934    const isBlock = (node, blockElements) => isNonNullable(node) && node.nodeName in blockElements;
935    const isVoid = (editor, node) => isNonNullable(node) && node.nodeName in editor.schema.getVoidElements();
936    const isBogusBr = (dom, node) => {
937        if (!isBr(node)) {
938            return false;
939        }
940        return dom.isBlock(node.nextSibling) && !isBr(node.previousSibling);
941    };
942    const isEmpty$1 = (dom, elm, keepBookmarks) => {
943        const empty = dom.isEmpty(elm);
944        if (keepBookmarks && dom.select('span[data-mce-type=bookmark]', elm).length > 0) {
945            return false;
946        }
947        return empty;
948    };
949    const isChildOfBody = (dom, elm) => dom.isChildOf(elm, dom.getRoot());
950
951    const option = (name) => (editor) => editor.options.get(name);
952    const register$3 = (editor) => {
953        const registerOption = editor.options.register;
954        registerOption('lists_indent_on_tab', {
955            processor: 'boolean',
956            default: true
957        });
958    };
959    const shouldIndentOnTab = option('lists_indent_on_tab');
960    const getForcedRootBlock = option('forced_root_block');
961    const getForcedRootBlockAttrs = option('forced_root_block_attrs');
962
963    const createTextBlock = (editor, contentNode, attrs = {}) => {
964        const dom = editor.dom;
965        const blockElements = editor.schema.getBlockElements();
966        const fragment = dom.createFragment();
967        const blockName = getForcedRootBlock(editor);
968        const blockAttrs = getForcedRootBlockAttrs(editor);
969        let node;
970        let textBlock;
971        let hasContentNode = false;
972        textBlock = dom.create(blockName, {
973            ...blockAttrs,
974            ...(attrs.style ? { style: attrs.style } : {})
975        });
976        if (!isBlock(contentNode.firstChild, blockElements)) {
977            fragment.appendChild(textBlock);
978        }
979        while ((node = contentNode.firstChild)) {
980            const nodeName = node.nodeName;
981            if (!hasContentNode && (nodeName !== 'SPAN' || node.getAttribute('data-mce-type') !== 'bookmark')) {
982                hasContentNode = true;
983            }
984            if (isBlock(node, blockElements)) {
985                fragment.appendChild(node);
986                textBlock = null;
987            }
988            else {
989                if (!textBlock) {
990                    textBlock = dom.create(blockName, blockAttrs);
991                    fragment.appendChild(textBlock);
992                }
993                textBlock.appendChild(node);
994            }
995        }
996        // BR is needed in empty blocks
997        if (!hasContentNode && textBlock) {
998            textBlock.appendChild(dom.create('br', { 'data-mce-bogus': '1' }));
999        }
1000        return fragment;
1001    };
1002
1003    const DOM$2 = global$3.DOM;
1004    const splitList = (editor, list, li) => {
1005        const removeAndKeepBookmarks = (targetNode) => {
1006            const parent = targetNode.parentNode;
1007            if (parent) {
1008                global$2.each(bookmarks, (node) => {
1009                    parent.insertBefore(node, li.parentNode);
1010                });
1011            }
1012            DOM$2.remove(targetNode);
1013        };
1014        const bookmarks = DOM$2.select('span[data-mce-type="bookmark"]', list);
1015        const newBlock = createTextBlock(editor, li);
1016        const tmpRng = DOM$2.createRng();
1017        tmpRng.setStartAfter(li);
1018        tmpRng.setEndAfter(list);
1019        const fragment = tmpRng.extractContents();
1020        for (let node = fragment.firstChild; node; node = node.firstChild) {
1021            if (node.nodeName === 'LI' && editor.dom.isEmpty(node)) {
1022                DOM$2.remove(node);
1023                break;
1024            }
1025        }
1026        if (!editor.dom.isEmpty(fragment)) {
1027            DOM$2.insertAfter(fragment, list);
1028        }
1029        DOM$2.insertAfter(newBlock, list);
1030        const parent = li.parentElement;
1031        if (parent && isEmpty$1(editor.dom, parent)) {
1032            removeAndKeepBookmarks(parent);
1033        }
1034        DOM$2.remove(li);
1035        if (isEmpty$1(editor.dom, list)) {
1036            DOM$2.remove(list);
1037        }
1038    };
1039
1040    const isDescriptionDetail = isTag('dd');
1041    const isDescriptionTerm = isTag('dt');
1042    const outdentDlItem = (editor, item) => {
1043        if (isDescriptionDetail(item)) {
1044            mutate(item, 'dt');
1045        }
1046        else if (isDescriptionTerm(item)) {
1047            parentElement(item).each((dl) => splitList(editor, dl.dom, item.dom));
1048        }
1049    };
1050    const indentDlItem = (item) => {
1051        if (isDescriptionTerm(item)) {
1052            mutate(item, 'dd');
1053        }
1054    };
1055    const dlIndentation = (editor, indentation, dlItems) => {
1056        if (indentation === "Indent" /* Indentation.Indent */) {
1057            each$1(dlItems, indentDlItem);
1058        }
1059        else {
1060            each$1(dlItems, (item) => outdentDlItem(editor, item));
1061        }
1062    };
1063
1064    const getNormalizedPoint = (container, offset) => {
1065        if (isTextNode$1(container)) {
1066            return { container, offset };
1067        }
1068        const node = global$6.getNode(container, offset);
1069        if (isTextNode$1(node)) {
1070            return {
1071                container: node,
1072                offset: offset >= container.childNodes.length ? node.data.length : 0
1073            };
1074        }
1075        else if (node.previousSibling && isTextNode$1(node.previousSibling)) {
1076            return {
1077                container: node.previousSibling,
1078                offset: node.previousSibling.data.length
1079            };
1080        }
1081        else if (node.nextSibling && isTextNode$1(node.nextSibling)) {
1082            return {
1083                container: node.nextSibling,
1084                offset: 0
1085            };
1086        }
1087        return { container, offset };
1088    };
1089    const normalizeRange = (rng) => {
1090        const outRng = rng.cloneRange();
1091        const rangeStart = getNormalizedPoint(rng.startContainer, rng.startOffset);
1092        outRng.setStart(rangeStart.container, rangeStart.offset);
1093        const rangeEnd = getNormalizedPoint(rng.endContainer, rng.endOffset);
1094        outRng.setEnd(rangeEnd.container, rangeEnd.offset);
1095        return outRng;
1096    };
1097
1098    const listNames = ['OL', 'UL', 'DL'];
1099    const listSelector = listNames.join(',');
1100    const getParentList = (editor, node) => {
1101        const selectionStart = node || editor.selection.getStart(true);
1102        return editor.dom.getParent(selectionStart, listSelector, getClosestListHost(editor, selectionStart));
1103    };
1104    const isParentListSelected = (parentList, selectedBlocks) => isNonNullable(parentList) && selectedBlocks.length === 1 && selectedBlocks[0] === parentList;
1105    const findSubLists = (parentList) => filter$1(parentList.querySelectorAll(listSelector), isListNode);
1106    const getSelectedSubLists = (editor) => {
1107        const parentList = getParentList(editor);
1108        const selectedBlocks = editor.selection.getSelectedBlocks();
1109        if (isParentListSelected(parentList, selectedBlocks)) {
1110            return findSubLists(parentList);
1111        }
1112        else {
1113            return filter$1(selectedBlocks, (elm) => {
1114                return isListNode(elm) && parentList !== elm;
1115            });
1116        }
1117    };
1118    const findParentListItemsNodes = (editor, elms) => {
1119        const listItemsElms = global$2.map(elms, (elm) => {
1120            const parentLi = editor.dom.getParent(elm, 'li,dd,dt', getClosestListHost(editor, elm));
1121            return parentLi ? parentLi : elm;
1122        });
1123        return unique(listItemsElms);
1124    };
1125    const getSelectedListItems = (editor) => {
1126        const selectedBlocks = editor.selection.getSelectedBlocks();
1127        return filter$1(findParentListItemsNodes(editor, selectedBlocks), isListItemNode);
1128    };
1129    const getSelectedDlItems = (editor) => filter$1(getSelectedListItems(editor), isDlItemNode);
1130    const getClosestEditingHost = (editor, elm) => {
1131        const parentTableCell = editor.dom.getParents(elm, 'TD,TH');
1132        return parentTableCell.length > 0 ? parentTableCell[0] : editor.getBody();
1133    };
1134    const isListHost = (schema, node) => !isListNode(node) && !isListItemNode(node) && exists(listNames, (listName) => schema.isValidChild(node.nodeName, listName));
1135    const getClosestListHost = (editor, elm) => {
1136        const parentBlocks = editor.dom.getParents(elm, editor.dom.isBlock);
1137        const isNotForcedRootBlock = (elm) => elm.nodeName.toLowerCase() !== getForcedRootBlock(editor);
1138        const parentBlock = find(parentBlocks, (elm) => isNotForcedRootBlock(elm) && isListHost(editor.schema, elm));
1139        return parentBlock.getOr(editor.getBody());
1140    };
1141    const isListInsideAnLiWithFirstAndLastNotListElement = (list) => parent(list).exists((parent) => isListItemNode(parent.dom)
1142        && firstChild(parent).exists((firstChild) => !isListNode(firstChild.dom))
1143        && lastChild(parent).exists((lastChild) => !isListNode(lastChild.dom)));
1144    const findLastParentListNode = (editor, elm) => {
1145        const parentLists = editor.dom.getParents(elm, 'ol,ul', getClosestListHost(editor, elm));
1146        return last(parentLists);
1147    };
1148    const getSelectedLists = (editor) => {
1149        const firstList = findLastParentListNode(editor, editor.selection.getStart());
1150        const subsequentLists = filter$1(editor.selection.getSelectedBlocks(), isOlUlNode);
1151        return firstList.toArray().concat(subsequentLists);
1152    };
1153    const getParentLists = (editor) => {
1154        const elm = editor.selection.getStart();
1155        return editor.dom.getParents(elm, 'ol,ul', getClosestListHost(editor, elm));
1156    };
1157    const getSelectedListRoots = (editor) => {
1158        const selectedLists = getSelectedLists(editor);
1159        const parentLists = getParentLists(editor);
1160        return find(parentLists, (p) => isListInsideAnLiWithFirstAndLastNotListElement(SugarElement.fromDom(p))).fold(() => getUniqueListRoots(editor, selectedLists), (l) => [l]);
1161    };
1162    const getUniqueListRoots = (editor, lists) => {
1163        const listRoots = map(lists, (list) => findLastParentListNode(editor, list).getOr(list));
1164        return unique(listRoots);
1165    };
1166
1167    const isCustomList = (list) => /\btox\-/.test(list.className);
1168    const inList = (parents, listName) => findUntil(parents, isListNode, isTableCellNode)
1169        .exists((list) => list.nodeName === listName && !isCustomList(list));
1170    // Advlist/core/ListUtils.ts - Duplicated in Advlist plugin
1171    const isWithinNonEditable = (editor, element) => element !== null && !editor.dom.isEditable(element);
1172    const selectionIsWithinNonEditableList = (editor) => {
1173        const parentList = getParentList(editor);
1174        return isWithinNonEditable(editor, parentList) || !editor.selection.isEditable();
1175    };
1176    const isWithinNonEditableList = (editor, element) => {
1177        const parentList = editor.dom.getParent(element, 'ol,ul,dl');
1178        return isWithinNonEditable(editor, parentList) || !editor.selection.isEditable();
1179    };
1180    const setNodeChangeHandler = (editor, nodeChangeHandler) => {
1181        const initialNode = editor.selection.getNode();
1182        // Set the initial state
1183        nodeChangeHandler({
1184            parents: editor.dom.getParents(initialNode),
1185            element: initialNode
1186        });
1187        editor.on('NodeChange', nodeChangeHandler);
1188        return () => editor.off('NodeChange', nodeChangeHandler);
1189    };
1190
1191    const fireListEvent = (editor, action, element) => editor.dispatch('ListMutation', { action, element });
1192
1193    const isList = (el) => is(el, 'OL,UL');
1194    const isListItem = (el) => is(el, 'LI');
1195    const hasFirstChildList = (el) => firstChild(el).exists(isList);
1196    const hasLastChildList = (el) => lastChild(el).exists(isList);
1197
1198    const isEntryList = (entry) => 'listAttributes' in entry;
1199    const isEntryComment = (entry) => 'isComment' in entry;
1200    const isEntryFragment = (entry) => 'isFragment' in entry;
1201    const isIndented = (entry) => entry.depth > 0;
1202    const isSelected = (entry) => entry.isSelected;
1203    const cloneItemContent = (li) => {
1204        const children$1 = children(li);
1205        const content = hasLastChildList(li) ? children$1.slice(0, -1) : children$1;
1206        return map(content, deep);
1207    };
1208    const createEntry = (li, depth, isSelected) => parent(li).filter(isElement$1).map((list) => ({
1209        depth,
1210        dirty: false,
1211        isSelected,
1212        content: cloneItemContent(li),
1213        itemAttributes: clone$1(li),
1214        listAttributes: clone$1(list),
1215        listType: name(list),
1216        isInPreviousLi: false
1217    }));
1218
1219    const joinSegment = (parent, child) => {
1220        append$1(parent.item, child.list);
1221    };
1222    const joinSegments = (segments) => {
1223        for (let i = 1; i < segments.length; i++) {
1224            joinSegment(segments[i - 1], segments[i]);
1225        }
1226    };
1227    const appendSegments = (head$1, tail) => {
1228        lift2(last(head$1), head(tail), joinSegment);
1229    };
1230    const createSegment = (scope, listType) => {
1231        const segment = {
1232            list: SugarElement.fromTag(listType, scope),
1233            item: SugarElement.fromTag('li', scope)
1234        };
1235        append$1(segment.list, segment.item);
1236        return segment;
1237    };
1238    const createSegments = (scope, entry, size) => {
1239        const segments = [];
1240        for (let i = 0; i < size; i++) {
1241            segments.push(createSegment(scope, isEntryList(entry) ? entry.listType : entry.parentListType));
1242        }
1243        return segments;
1244    };
1245    const populateSegments = (segments, entry) => {
1246        for (let i = 0; i < segments.length - 1; i++) {
1247            set(segments[i].item, 'list-style-type', 'none');
1248        }
1249        last(segments).each((segment) => {
1250            if (isEntryList(entry)) {
1251                setAll(segment.list, entry.listAttributes);
1252                setAll(segment.item, entry.itemAttributes);
1253            }
1254            append(segment.item, entry.content);
1255        });
1256    };
1257    const normalizeSegment = (segment, entry) => {
1258        if (name(segment.list) !== entry.listType) {
1259            segment.list = mutate(segment.list, entry.listType);
1260        }
1261        setAll(segment.list, entry.listAttributes);
1262    };
1263    const createItem = (scope, attr, content) => {
1264        const item = SugarElement.fromTag('li', scope);
1265        setAll(item, attr);
1266        append(item, content);
1267        return item;
1268    };
1269    const appendItem = (segment, item) => {
1270        append$1(segment.list, item);
1271        segment.item = item;
1272    };
1273    const writeShallow = (scope, cast, entry) => {
1274        const newCast = cast.slice(0, entry.depth);
1275        last(newCast).each((segment) => {
1276            if (isEntryList(entry)) {
1277                const item = createItem(scope, entry.itemAttributes, entry.content);
1278                appendItem(segment, item);
1279                normalizeSegment(segment, entry);
1280            }
1281            else if (isEntryFragment(entry)) {
1282                append(segment.item, entry.content);
1283            }
1284            else {
1285                const item = SugarElement.fromHtml(`<!--${entry.content}-->`);
1286                append$1(segment.list, item);
1287            }
1288        });
1289        return newCast;
1290    };
1291    const writeDeep = (scope, cast, entry) => {
1292        const segments = createSegments(scope, entry, entry.depth - cast.length);
1293        joinSegments(segments);
1294        populateSegments(segments, entry);
1295        appendSegments(cast, segments);
1296        return cast.concat(segments);
1297    };
1298    const composeList = (scope, entries) => {
1299        let firstCommentEntryOpt = Optional.none();
1300        const cast = foldl(entries, (cast, entry, i) => {
1301            if (!isEntryComment(entry)) {
1302                return entry.depth > cast.length ? writeDeep(scope, cast, entry) : writeShallow(scope, cast, entry);
1303            }
1304            else {
1305                // this is needed becuase if the first element of the list is a comment we would not have the data to create the new list
1306                if (i === 0) {
1307                    firstCommentEntryOpt = Optional.some(entry);
1308                    return cast;
1309                }
1310                return writeShallow(scope, cast, entry);
1311            }
1312        }, []);
1313        firstCommentEntryOpt.each((firstCommentEntry) => {
1314            const item = SugarElement.fromHtml(`<!--${firstCommentEntry.content}-->`);
1315            head(cast).each((fistCast) => {
1316                prepend(fistCast.list, item);
1317            });
1318        });
1319        return head(cast).map((segment) => segment.list);
1320    };
1321
1322    const indentEntry = (indentation, entry) => {
1323        switch (indentation) {
1324            case "Indent" /* Indentation.Indent */:
1325                entry.depth++;
1326                break;
1327            case "Outdent" /* Indentation.Outdent */:
1328                entry.depth--;
1329                break;
1330            case "Flatten" /* Indentation.Flatten */:
1331                entry.depth = 0;
1332        }
1333        entry.dirty = true;
1334    };
1335
1336    const cloneListProperties = (target, source) => {
1337        if (isEntryList(target) && isEntryList(source)) {
1338            target.listType = source.listType;
1339            target.listAttributes = { ...source.listAttributes };
1340        }
1341    };
1342    const cleanListProperties = (entry) => {
1343        // Remove the start attribute if generating a new list
1344        entry.listAttributes = filter(entry.listAttributes, (_value, key) => key !== 'start');
1345    };
1346    // Closest entry above/below in the same list
1347    const closestSiblingEntry = (entries, start) => {
1348        const depth = entries[start].depth;
1349        // Ignore dirty items as they've been moved and won't have the right list data yet
1350        const matches = (entry) => entry.depth === depth && !entry.dirty;
1351        const until = (entry) => entry.depth < depth;
1352        // Check in reverse to see if there's an entry as the same depth before the current entry
1353        // but if not, then try to walk forwards as well
1354        return findUntil(reverse(entries.slice(0, start)), matches, until)
1355            .orThunk(() => findUntil(entries.slice(start + 1), matches, until));
1356    };
1357    const normalizeEntries = (entries) => {
1358        each$1(entries, (entry, i) => {
1359            closestSiblingEntry(entries, i).fold(() => {
1360                if (entry.dirty && isEntryList(entry)) {
1361                    cleanListProperties(entry);
1362                }
1363            }, (matchingEntry) => cloneListProperties(entry, matchingEntry));
1364        });
1365        return entries;
1366    };
1367
1368    const parseSingleItem = (depth, itemSelection, selectionState, item) => {
1369        var _a;
1370        if (isComment(item)) {
1371            return [{
1372                    depth: depth + 1,
1373                    content: (_a = item.dom.nodeValue) !== null && _a !== void 0 ? _a : '',
1374                    dirty: false,
1375                    isSelected: false,
1376                    isComment: true
1377                }];
1378        }
1379        itemSelection.each((selection) => {
1380            if (eq(selection.start, item)) {
1381                selectionState.set(true);
1382            }
1383        });
1384        const currentItemEntry = createEntry(item, depth, selectionState.get());
1385        // Update selectionState (end)
1386        itemSelection.each((selection) => {
1387            if (eq(selection.end, item)) {
1388                selectionState.set(false);
1389            }
1390        });
1391        const childListEntries = lastChild(item)
1392            .filter(isList)
1393            .map((list) => parseList(depth, itemSelection, selectionState, list))
1394            .getOr([]);
1395        return currentItemEntry.toArray().concat(childListEntries);
1396    };
1397    const parseItem = (depth, itemSelection, selectionState, item) => firstChild(item).filter(isList).fold(() => parseSingleItem(depth, itemSelection, selectionState, item), (list) => {
1398        const parsedSiblings = foldl(children(item), (acc, liChild, i) => {
1399            if (i === 0) {
1400                return acc;
1401            }
1402            else {
1403                if (isListItem(liChild)) {
1404                    return acc.concat(parseSingleItem(depth, itemSelection, selectionState, liChild));
1405                }
1406                else {
1407                    const fragment = {
1408                        isFragment: true,
1409                        depth,
1410                        content: [liChild],
1411                        isSelected: false,
1412                        dirty: false,
1413                        parentListType: name(list)
1414                    };
1415                    return acc.concat(fragment);
1416                }
1417            }
1418        }, []);
1419        return parseList(depth, itemSelection, selectionState, list).concat(parsedSiblings);
1420    });
1421    const parseList = (depth, itemSelection, selectionState, list) => bind(children(list), (element) => {
1422        const parser = isList(element) ? parseList : parseItem;
1423        const newDepth = depth + 1;
1424        return parser(newDepth, itemSelection, selectionState, element);
1425    });
1426    const parseLists = (lists, itemSelection) => {
1427        const selectionState = Cell(false);
1428        const initialDepth = 0;
1429        return map(lists, (list) => ({
1430            sourceList: list,
1431            entries: parseList(initialDepth, itemSelection, selectionState, list)
1432        }));
1433    };
1434
1435    const outdentedComposer = (editor, entries) => {
1436        const normalizedEntries = normalizeEntries(entries);
1437        return map(normalizedEntries, (entry) => {
1438            const content = !isEntryComment(entry)
1439                ? fromElements(entry.content)
1440                : fromElements([SugarElement.fromHtml(`<!--${entry.content}-->`)]);
1441            const listItemAttrs = isEntryList(entry) ? entry.itemAttributes : {};
1442            return SugarElement.fromDom(createTextBlock(editor, content.dom, listItemAttrs));
1443        });
1444    };
1445    const indentedComposer = (editor, entries) => {
1446        const normalizedEntries = normalizeEntries(entries);
1447        return composeList(editor.contentDocument, normalizedEntries).toArray();
1448    };
1449    const composeEntries = (editor, entries) => bind(groupBy(entries, isIndented), (entries) => {
1450        const groupIsIndented = head(entries).exists(isIndented);
1451        return groupIsIndented ? indentedComposer(editor, entries) : outdentedComposer(editor, entries);
1452    });
1453    const indentSelectedEntries = (entries, indentation) => {
1454        each$1(filter$1(entries, isSelected), (entry) => indentEntry(indentation, entry));
1455    };
1456    const getItemSelection = (editor) => {
1457        const selectedListItems = map(getSelectedListItems(editor), SugarElement.fromDom);
1458        return lift2(find(selectedListItems, not(hasFirstChildList)), find(reverse(selectedListItems), not(hasFirstChildList)), (start, end) => ({ start, end }));
1459    };
1460    const listIndentation = (editor, lists, indentation) => {
1461        const entrySets = parseLists(lists, getItemSelection(editor));
1462        each$1(entrySets, (entrySet) => {
1463            indentSelectedEntries(entrySet.entries, indentation);
1464            const composedLists = composeEntries(editor, entrySet.entries);
1465            each$1(composedLists, (composedList) => {
1466                fireListEvent(editor, indentation === "Indent" /* Indentation.Indent */ ? "IndentList" /* ListAction.IndentList */ : "OutdentList" /* ListAction.OutdentList */, composedList.dom);
1467            });
1468            before(entrySet.sourceList, composedLists);
1469            remove(entrySet.sourceList);
1470        });
1471    };
1472
1473    const selectionIndentation = (editor, indentation) => {
1474        const lists = fromDom(getSelectedListRoots(editor));
1475        const dlItems = fromDom(getSelectedDlItems(editor));
1476        let isHandled = false;
1477        if (lists.length || dlItems.length) {
1478            const bookmark = editor.selection.getBookmark();
1479            listIndentation(editor, lists, indentation);
1480            dlIndentation(editor, indentation, dlItems);
1481            editor.selection.moveToBookmark(bookmark);
1482            editor.selection.setRng(normalizeRange(editor.selection.getRng()));
1483            editor.nodeChanged();
1484            isHandled = true;
1485        }
1486        return isHandled;
1487    };
1488    const handleIndentation = (editor, indentation) => !selectionIsWithinNonEditableList(editor) && selectionIndentation(editor, indentation);
1489    const indentListSelection = (editor) => handleIndentation(editor, "Indent" /* Indentation.Indent */);
1490    const outdentListSelection = (editor) => handleIndentation(editor, "Outdent" /* Indentation.Outdent */);
1491    const flattenListSelection = (editor) => handleIndentation(editor, "Flatten" /* Indentation.Flatten */);
1492
1493    var global$1 = tinymce.util.Tools.resolve('tinymce.dom.BookmarkManager');
1494
1495    const DOM$1 = global$3.DOM;
1496    /**
1497     * Returns a range bookmark. This will convert indexed bookmarks into temporary span elements with
1498     * index 0 so that they can be restored properly after the DOM has been modified. Text bookmarks will not have spans
1499     * added to them since they can be restored after a dom operation.
1500     *
1501     * So this: <p><b>|</b><b>|</b></p>
1502     * becomes: <p><b><span data-mce-type="bookmark">|</span></b><b data-mce-type="bookmark">|</span></b></p>
1503     *
1504     * @param  {DOMRange} rng DOM Range to get bookmark on.
1505     * @return {Object} Bookmark object.
1506     */
1507    const createBookmark = (rng) => {
1508        const bookmark = {};
1509        const setupEndPoint = (start) => {
1510            let container = rng[start ? 'startContainer' : 'endContainer'];
1511            let offset = rng[start ? 'startOffset' : 'endOffset'];
1512            if (isElement(container)) {
1513                const offsetNode = DOM$1.create('span', { 'data-mce-type': 'bookmark' });
1514                if (container.hasChildNodes()) {
1515                    offset = Math.min(offset, container.childNodes.length - 1);
1516                    if (start) {
1517                        container.insertBefore(offsetNode, container.childNodes[offset]);
1518                    }
1519                    else {
1520                        DOM$1.insertAfter(offsetNode, container.childNodes[offset]);
1521                    }
1522                }
1523                else {
1524                    container.appendChild(offsetNode);
1525                }
1526                container = offsetNode;
1527                offset = 0;
1528            }
1529            bookmark[start ? 'startContainer' : 'endContainer'] = container;
1530            bookmark[start ? 'startOffset' : 'endOffset'] = offset;
1531        };
1532        setupEndPoint(true);
1533        if (!rng.collapsed) {
1534            setupEndPoint();
1535        }
1536        return bookmark;
1537    };
1538    const resolveBookmark = (bookmark) => {
1539        const restoreEndPoint = (start) => {
1540            const nodeIndex = (container) => {
1541                var _a;
1542                let node = (_a = container.parentNode) === null || _a === void 0 ? void 0 : _a.firstChild;
1543                let idx = 0;
1544                while (node) {
1545                    if (node === container) {
1546                        return idx;
1547                    }
1548                    // Skip data-mce-type=bookmark nodes
1549                    if (!isElement(node) || node.getAttribute('data-mce-type') !== 'bookmark') {
1550                        idx++;
1551                    }
1552                    node = node.nextSibling;
1553                }
1554                return -1;
1555            };
1556            let container = bookmark[start ? 'startContainer' : 'endContainer'];
1557            let offset = bookmark[start ? 'startOffset' : 'endOffset'];
1558            if (!container) {
1559                return;
1560            }
1561            if (isElement(container) && container.parentNode) {
1562                const node = container;
1563                offset = nodeIndex(container);
1564                container = container.parentNode;
1565                DOM$1.remove(node);
1566                if (!container.hasChildNodes() && DOM$1.isBlock(container)) {
1567                    container.appendChild(DOM$1.create('br'));
1568                }
1569            }
1570            bookmark[start ? 'startContainer' : 'endContainer'] = container;
1571            bookmark[start ? 'startOffset' : 'endOffset'] = offset;
1572        };
1573        restoreEndPoint(true);
1574        restoreEndPoint();
1575        const rng = DOM$1.createRng();
1576        rng.setStart(bookmark.startContainer, bookmark.startOffset);
1577        if (bookmark.endContainer) {
1578            rng.setEnd(bookmark.endContainer, bookmark.endOffset);
1579        }
1580        return normalizeRange(rng);
1581    };
1582
1583    const listToggleActionFromListName = (listName) => {
1584        switch (listName) {
1585            case 'UL': return "ToggleUlList" /* ListAction.ToggleUlList */;
1586            case 'OL': return "ToggleOlList" /* ListAction.ToggleOlList */;
1587            case 'DL': return "ToggleDLList" /* ListAction.ToggleDLList */;
1588        }
1589    };
1590
1591    const updateListStyle = (dom, el, detail) => {
1592        const type = detail['list-style-type'] ? detail['list-style-type'] : null;
1593        dom.setStyle(el, 'list-style-type', type);
1594    };
1595    const setAttribs = (elm, attrs) => {
1596        global$2.each(attrs, (value, key) => {
1597            elm.setAttribute(key, value);
1598        });
1599    };
1600    const updateListAttrs = (dom, el, detail) => {
1601        setAttribs(el, detail['list-attributes']);
1602        global$2.each(dom.select('li', el), (li) => {
1603            setAttribs(li, detail['list-item-attributes']);
1604        });
1605    };
1606    const updateListWithDetails = (dom, el, detail) => {
1607        updateListStyle(dom, el, detail);
1608        updateListAttrs(dom, el, detail);
1609    };
1610    const removeStyles = (dom, element, styles) => {
1611        global$2.each(styles, (style) => dom.setStyle(element, style, ''));
1612    };
1613    const isInline = (editor, node) => isNonNullable(node) && !isBlock(node, editor.schema.getBlockElements());
1614    const getEndPointNode = (editor, rng, start, root) => {
1615        let container = rng[start ? 'startContainer' : 'endContainer'];
1616        const offset = rng[start ? 'startOffset' : 'endOffset'];
1617        // Resolve node index
1618        if (isElement(container)) {
1619            container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container;
1620        }
1621        if (!start && isBr(container.nextSibling)) {
1622            container = container.nextSibling;
1623        }
vendor: 24,589 bytes, lines 1624-2174
1624        const findBlockAncestor = (node) => {
1625            while (!editor.dom.isBlock(node) && node.parentNode && root !== node) {
1626                node = node.parentNode;
1627            }
1628            return node;
1629        };
1630        // The reason why the next two if statements exist is because when the root node is a table cell (possibly some other node types)
1631        // then the highest we can go up the dom hierarchy is one level below the table cell.
1632        // So what happens when we have a bunch of inline nodes and text nodes in the table cell
1633        // and when the selection is collapsed inside one of the inline nodes then only that inline node (or text node) will be included
1634        // in the created list because that would be one level below td node and the other inline nodes won't be included.
1635        // So the fix proposed is to traverse left when looking for start node (and traverse right when looking for end node)
1636        // and keep traversing as long as we have an inline or text node (same for traversing right).
1637        // This way we end up including all the inline elements in the created list.
1638        // For more info look at #TINY-6853
1639        const findBetterContainer = (container, forward) => {
1640            var _a;
1641            const walker = new global$5(container, findBlockAncestor(container));
1642            const dir = forward ? 'next' : 'prev';
1643            let node;
1644            while ((node = walker[dir]())) {
1645                if (!(isVoid(editor, node) || isZwsp(node.textContent) || ((_a = node.textContent) === null || _a === void 0 ? void 0 : _a.length) === 0)) {
1646                    return Optional.some(node);
1647                }
1648            }
1649            return Optional.none();
1650        };
1651        // Traverse left to include inline/text nodes
1652        if (start && isTextNode$1(container)) {
1653            if (isZwsp(container.textContent)) {
1654                container = findBetterContainer(container, false).getOr(container);
1655            }
1656            else {
1657                if (container.parentNode !== null && isInline(editor, container.parentNode)) {
1658                    container = container.parentNode;
1659                }
1660                while (container.previousSibling !== null && (isInline(editor, container.previousSibling) || isTextNode$1(container.previousSibling))) {
1661                    container = container.previousSibling;
1662                }
1663            }
1664        }
1665        // Traverse right to include inline/text nodes
1666        if (!start && isTextNode$1(container)) {
1667            if (isZwsp(container.textContent)) {
1668                container = findBetterContainer(container, true).getOr(container);
1669            }
1670            else {
1671                if (container.parentNode !== null && isInline(editor, container.parentNode)) {
1672                    container = container.parentNode;
1673                }
1674                while (container.nextSibling !== null && (isInline(editor, container.nextSibling) || isTextNode$1(container.nextSibling))) {
1675                    container = container.nextSibling;
1676                }
1677            }
1678        }
1679        while (container.parentNode !== root) {
1680            const parent = container.parentNode;
1681            if (isTextBlock(editor, container)) {
1682                return container;
1683            }
1684            if (/^(TD|TH)$/.test(parent.nodeName)) {
1685                return container;
1686            }
1687            container = parent;
1688        }
1689        return container;
1690    };
1691    const getSelectedTextBlocks = (editor, rng, root) => {
1692        const textBlocks = [];
1693        const dom = editor.dom;
1694        const startNode = getEndPointNode(editor, rng, true, root);
1695        const endNode = getEndPointNode(editor, rng, false, root);
1696        let block;
1697        const siblings = [];
1698        for (let node = startNode; node; node = node.nextSibling) {
1699            siblings.push(node);
1700            if (node === endNode) {
1701                break;
1702            }
1703        }
1704        global$2.each(siblings, (node) => {
1705            var _a;
1706            if (isTextBlock(editor, node)) {
1707                textBlocks.push(node);
1708                block = null;
1709                return;
1710            }
1711            if (dom.isBlock(node) || isBr(node)) {
1712                if (isBr(node)) {
1713                    dom.remove(node);
1714                }
1715                block = null;
1716                return;
1717            }
1718            const nextSibling = node.nextSibling;
1719            if (global$1.isBookmarkNode(node)) {
1720                if (isListNode(nextSibling) || isTextBlock(editor, nextSibling) || (!nextSibling && node.parentNode === root)) {
1721                    block = null;
1722                    return;
1723                }
1724            }
1725            if (!block) {
1726                block = dom.create('p');
1727                (_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.insertBefore(block, node);
1728                textBlocks.push(block);
1729            }
1730            block.appendChild(node);
1731        });
1732        return textBlocks;
1733    };
1734    const hasCompatibleStyle = (dom, sib, detail) => {
1735        const sibStyle = dom.getStyle(sib, 'list-style-type');
1736        let detailStyle = detail ? detail['list-style-type'] : '';
1737        detailStyle = detailStyle === null ? '' : detailStyle;
1738        return sibStyle === detailStyle;
1739    };
1740    /*
1741      Find the first element we would transform into a li-element if given no constraints.
1742      If the common ancestor is higher up than that provide it as the starting-point for the search for the root instead of the first selected element.
1743      This helps avoid issues with divs that should become li-elements are detected as the root when they should not be.
1744    */
1745    const getRootSearchStart = (editor, range) => {
1746        const start = editor.selection.getStart(true);
1747        const startPoint = getEndPointNode(editor, range, true, editor.getBody());
1748        if (ancestor(SugarElement.fromDom(startPoint), SugarElement.fromDom(range.commonAncestorContainer))) {
1749            return range.commonAncestorContainer;
1750        }
1751        else {
1752            return start;
1753        }
1754    };
1755    const applyList = (editor, listName, detail) => {
1756        const rng = editor.selection.getRng();
1757        let listItemName = 'LI';
1758        const root = getClosestListHost(editor, getRootSearchStart(editor, rng));
1759        const dom = editor.dom;
1760        if (dom.getContentEditable(editor.selection.getNode()) === 'false') {
1761            return;
1762        }
1763        listName = listName.toUpperCase();
1764        if (listName === 'DL') {
1765            listItemName = 'DT';
1766        }
1767        const bookmark = createBookmark(rng);
1768        const selectedTextBlocks = filter$1(getSelectedTextBlocks(editor, rng, root), editor.dom.isEditable);
1769        global$2.each(selectedTextBlocks, (block) => {
1770            let listBlock;
1771            const sibling = block.previousSibling;
1772            const parent = block.parentNode;
1773            if (!isListItemNode(parent)) {
1774                if (sibling && isListNode(sibling) && sibling.nodeName === listName && hasCompatibleStyle(dom, sibling, detail)) {
1775                    listBlock = sibling;
1776                    block = dom.rename(block, listItemName);
1777                    sibling.appendChild(block);
1778                }
1779                else {
1780                    listBlock = dom.create(listName);
1781                    parent.insertBefore(listBlock, block);
1782                    listBlock.appendChild(block);
1783                    block = dom.rename(block, listItemName);
1784                }
1785                removeStyles(dom, block, [
1786                    'margin', 'margin-right', 'margin-bottom', 'margin-left', 'margin-top',
1787                    'padding', 'padding-right', 'padding-bottom', 'padding-left', 'padding-top'
1788                ]);
1789                updateListWithDetails(dom, listBlock, detail);
1790                mergeWithAdjacentLists(editor.dom, listBlock);
1791            }
1792        });
1793        editor.selection.setRng(resolveBookmark(bookmark));
1794    };
1795    const isValidLists = (list1, list2) => {
1796        return isListNode(list1) && list1.nodeName === (list2 === null || list2 === void 0 ? void 0 : list2.nodeName);
1797    };
1798    const hasSameListStyle = (dom, list1, list2) => {
1799        const targetStyle = dom.getStyle(list1, 'list-style-type', true);
1800        const style = dom.getStyle(list2, 'list-style-type', true);
1801        return targetStyle === style;
1802    };
1803    const hasSameClasses = (elm1, elm2) => {
1804        return elm1.className === elm2.className;
1805    };
1806    const shouldMerge = (dom, list1, list2) => {
1807        return isValidLists(list1, list2) &&
1808            // Note: isValidLists will ensure list1 and list2 are a HTMLElement. Unfortunately TypeScript doesn't
1809            // support type guards on multiple variables. See https://github.com/microsoft/TypeScript/issues/26916
1810            hasSameListStyle(dom, list1, list2) &&
1811            hasSameClasses(list1, list2);
1812    };
1813    const mergeWithAdjacentLists = (dom, listBlock) => {
1814        let node;
1815        let sibling = listBlock.nextSibling;
1816        if (shouldMerge(dom, listBlock, sibling)) {
1817            const liSibling = sibling;
1818            while ((node = liSibling.firstChild)) {
1819                listBlock.appendChild(node);
1820            }
1821            dom.remove(liSibling);
1822        }
1823        sibling = listBlock.previousSibling;
1824        if (shouldMerge(dom, listBlock, sibling)) {
1825            const liSibling = sibling;
1826            while ((node = liSibling.lastChild)) {
1827                listBlock.insertBefore(node, listBlock.firstChild);
1828            }
1829            dom.remove(liSibling);
1830        }
1831    };
1832    const updateList$1 = (editor, list, listName, detail) => {
1833        if (list.nodeName !== listName) {
1834            const newList = editor.dom.rename(list, listName);
1835            updateListWithDetails(editor.dom, newList, detail);
1836            fireListEvent(editor, listToggleActionFromListName(listName), newList);
1837        }
1838        else {
1839            updateListWithDetails(editor.dom, list, detail);
1840            fireListEvent(editor, listToggleActionFromListName(listName), list);
1841        }
1842    };
1843    const updateCustomList = (editor, list, listName, detail) => {
1844        list.classList.forEach((cls, _, classList) => {
1845            if (cls.startsWith('tox-')) {
1846                classList.remove(cls);
1847                if (classList.length === 0) {
1848                    list.removeAttribute('class');
1849                }
1850            }
1851        });
1852        if (list.nodeName !== listName) {
1853            const newList = editor.dom.rename(list, listName);
1854            updateListWithDetails(editor.dom, newList, detail);
1855            fireListEvent(editor, listToggleActionFromListName(listName), newList);
1856        }
1857        else {
1858            updateListWithDetails(editor.dom, list, detail);
1859            fireListEvent(editor, listToggleActionFromListName(listName), list);
1860        }
1861    };
1862    const toggleMultipleLists = (editor, parentList, lists, listName, detail) => {
1863        const parentIsList = isListNode(parentList);
1864        if (parentIsList && parentList.nodeName === listName && !hasListStyleDetail(detail) && !isCustomList(parentList)) {
1865            flattenListSelection(editor);
1866        }
1867        else {
1868            applyList(editor, listName, detail);
1869            const bookmark = createBookmark(editor.selection.getRng());
1870            const allLists = parentIsList ? [parentList, ...lists] : lists;
1871            const updateFunction = (parentIsList && isCustomList(parentList)) ? updateCustomList : updateList$1;
1872            global$2.each(allLists, (elm) => {
1873                updateFunction(editor, elm, listName, detail);
1874            });
1875            editor.selection.setRng(resolveBookmark(bookmark));
1876        }
1877    };
1878    const hasListStyleDetail = (detail) => {
1879        return 'list-style-type' in detail;
1880    };
1881    const toggleSingleList = (editor, parentList, listName, detail) => {
1882        if (parentList === editor.getBody()) {
1883            return;
1884        }
1885        if (parentList) {
1886            if (parentList.nodeName === listName && !hasListStyleDetail(detail) && !isCustomList(parentList)) {
1887                flattenListSelection(editor);
1888            }
1889            else {
1890                const bookmark = createBookmark(editor.selection.getRng());
1891                if (isCustomList(parentList)) {
1892                    parentList.classList.forEach((cls, _, classList) => {
1893                        if (cls.startsWith('tox-')) {
1894                            classList.remove(cls);
1895                            if (classList.length === 0) {
1896                                parentList.removeAttribute('class');
1897                            }
1898                        }
1899                    });
1900                }
1901                updateListWithDetails(editor.dom, parentList, detail);
1902                const newList = editor.dom.rename(parentList, listName);
1903                mergeWithAdjacentLists(editor.dom, newList);
1904                editor.selection.setRng(resolveBookmark(bookmark));
1905                applyList(editor, listName, detail);
1906                fireListEvent(editor, listToggleActionFromListName(listName), newList);
1907            }
1908        }
1909        else {
1910            applyList(editor, listName, detail);
1911            fireListEvent(editor, listToggleActionFromListName(listName), parentList);
1912        }
1913    };
1914    const toggleList = (editor, listName, _detail) => {
1915        const parentList = getParentList(editor);
1916        if (isWithinNonEditableList(editor, parentList)) {
1917            return;
1918        }
1919        const selectedSubLists = getSelectedSubLists(editor);
1920        const detail = isObject(_detail) ? _detail : {};
1921        if (selectedSubLists.length > 0) {
1922            toggleMultipleLists(editor, parentList, selectedSubLists, listName, detail);
1923        }
1924        else {
1925            toggleSingleList(editor, parentList, listName, detail);
1926        }
1927    };
1928
1929    const DOM = global$3.DOM;
1930    const normalizeList = (dom, list) => {
1931        const parentNode = list.parentElement;
1932        // Move UL/OL to previous LI if it's the only child of a LI
1933        if (parentNode && parentNode.nodeName === 'LI' && parentNode.firstChild === list) {
1934            const sibling = parentNode.previousSibling;
1935            if (sibling && sibling.nodeName === 'LI') {
1936                sibling.appendChild(list);
1937                if (isEmpty$1(dom, parentNode)) {
1938                    DOM.remove(parentNode);
1939                }
1940            }
1941            else {
1942                DOM.setStyle(parentNode, 'listStyleType', 'none');
1943            }
1944        }
1945        // Append OL/UL to previous LI if it's in a parent OL/UL i.e. old HTML4
1946        if (isListNode(parentNode)) {
1947            const sibling = parentNode.previousSibling;
1948            if (sibling && sibling.nodeName === 'LI') {
1949                sibling.appendChild(list);
1950            }
1951        }
1952    };
1953    const normalizeLists = (dom, element) => {
1954        const lists = global$2.grep(dom.select('ol,ul', element));
1955        global$2.each(lists, (list) => {
1956            normalizeList(dom, list);
1957        });
1958    };
1959
1960    const findNextCaretContainer = (editor, rng, isForward, root) => {
1961        let node = rng.startContainer;
1962        const offset = rng.startOffset;
1963        if (isTextNode$1(node) && (isForward ? offset < node.data.length : offset > 0)) {
1964            return node;
1965        }
1966        const nonEmptyBlocks = editor.schema.getNonEmptyElements();
1967        if (isElement(node)) {
1968            node = global$6.getNode(node, offset);
1969        }
1970        const walker = new global$5(node, root);
1971        // Delete at <li>|<br></li> then jump over the bogus br
1972        if (isForward) {
1973            if (isBogusBr(editor.dom, node)) {
1974                walker.next();
1975            }
1976        }
1977        const walkFn = isForward ? walker.next.bind(walker) : walker.prev2.bind(walker);
1978        while ((node = walkFn())) {
1979            if (node.nodeName === 'LI' && !node.hasChildNodes()) {
1980                return node;
1981            }
1982            if (nonEmptyBlocks[node.nodeName]) {
1983                return node;
1984            }
1985            if (isTextNode$1(node) && node.data.length > 0) {
1986                return node;
1987            }
1988        }
1989        return null;
1990    };
1991    const hasOnlyOneBlockChild = (dom, elm) => {
1992        const childNodes = elm.childNodes;
1993        return childNodes.length === 1 && !isListNode(childNodes[0]) && dom.isBlock(childNodes[0]);
1994    };
1995    const isUnwrappable = (node) => Optional.from(node)
1996        .map(SugarElement.fromDom)
1997        .filter(isHTMLElement)
1998        .exists((el) => isEditable(el) && !contains$1(['details'], name(el)));
1999    const unwrapSingleBlockChild = (dom, elm) => {
2000        if (hasOnlyOneBlockChild(dom, elm) && isUnwrappable(elm.firstChild)) {
2001            dom.remove(elm.firstChild, true);
2002        }
2003    };
2004    const moveChildren = (dom, fromElm, toElm) => {
2005        let node;
2006        const targetElm = hasOnlyOneBlockChild(dom, toElm) ? toElm.firstChild : toElm;
2007        unwrapSingleBlockChild(dom, fromElm);
2008        if (!isEmpty$1(dom, fromElm, true)) {
2009            while ((node = fromElm.firstChild)) {
2010                targetElm.appendChild(node);
2011            }
2012        }
2013    };
2014    const mergeLiElements = (dom, fromElm, toElm) => {
2015        let listNode;
2016        const ul = fromElm.parentNode;
2017        if (!isChildOfBody(dom, fromElm) || !isChildOfBody(dom, toElm)) {
2018            return;
2019        }
2020        if (isListNode(toElm.lastChild)) {
2021            listNode = toElm.lastChild;
2022        }
2023        if (ul === toElm.lastChild) {
2024            if (isBr(ul.previousSibling)) {
2025                dom.remove(ul.previousSibling);
2026            }
2027        }
2028        const node = toElm.lastChild;
2029        if (node && isBr(node) && fromElm.hasChildNodes()) {
2030            dom.remove(node);
2031        }
2032        if (isEmpty$1(dom, toElm, true)) {
2033            empty(SugarElement.fromDom(toElm));
2034        }
2035        moveChildren(dom, fromElm, toElm);
2036        if (listNode) {
2037            toElm.appendChild(listNode);
2038        }
2039        const contains$1 = contains(SugarElement.fromDom(toElm), SugarElement.fromDom(fromElm));
2040        const nestedLists = contains$1 ? dom.getParents(fromElm, isListNode, toElm) : [];
2041        dom.remove(fromElm);
2042        each$1(nestedLists, (list) => {
2043            if (isEmpty$1(dom, list) && list !== dom.getRoot()) {
2044                dom.remove(list);
2045            }
2046        });
2047    };
2048    const mergeIntoEmptyLi = (editor, fromLi, toLi) => {
2049        empty(SugarElement.fromDom(toLi));
2050        mergeLiElements(editor.dom, fromLi, toLi);
2051        editor.selection.setCursorLocation(toLi, 0);
2052    };
2053    const mergeForward = (editor, rng, fromLi, toLi) => {
2054        const dom = editor.dom;
2055        if (dom.isEmpty(toLi)) {
2056            mergeIntoEmptyLi(editor, fromLi, toLi);
2057        }
2058        else {
2059            const bookmark = createBookmark(rng);
2060            mergeLiElements(dom, fromLi, toLi);
2061            editor.selection.setRng(resolveBookmark(bookmark));
2062        }
2063    };
2064    const mergeBackward = (editor, rng, fromLi, toLi) => {
2065        const bookmark = createBookmark(rng);
2066        mergeLiElements(editor.dom, fromLi, toLi);
2067        const resolvedBookmark = resolveBookmark(bookmark);
2068        editor.selection.setRng(resolvedBookmark);
2069    };
2070    const backspaceDeleteFromListToListCaret = (editor, isForward) => {
2071        const dom = editor.dom, selection = editor.selection;
2072        const selectionStartElm = selection.getStart();
2073        const root = getClosestEditingHost(editor, selectionStartElm);
2074        const li = dom.getParent(selection.getStart(), 'LI', root);
2075        if (li) {
2076            const ul = li.parentElement;
2077            if (ul === editor.getBody() && isEmpty$1(dom, ul)) {
2078                return true;
2079            }
2080            const rng = normalizeRange(selection.getRng());
2081            const otherLi = dom.getParent(findNextCaretContainer(editor, rng, isForward, root), 'LI', root);
2082            const willMergeParentIntoChild = otherLi && (isForward ? dom.isChildOf(li, otherLi) : dom.isChildOf(otherLi, li));
2083            if (otherLi && otherLi !== li && !willMergeParentIntoChild) {
2084                editor.undoManager.transact(() => {
2085                    if (isForward) {
2086                        mergeForward(editor, rng, otherLi, li);
2087                    }
2088                    else {
2089                        if (isFirstChild(li)) {
2090                            outdentListSelection(editor);
2091                        }
2092                        else {
2093                            mergeBackward(editor, rng, li, otherLi);
2094                        }
2095                    }
2096                });
2097                return true;
2098            }
2099            else if (willMergeParentIntoChild && !isForward && otherLi !== li) {
2100                const commonAncestorParent = rng.commonAncestorContainer.parentElement;
2101                if (!commonAncestorParent || dom.isChildOf(otherLi, commonAncestorParent)) {
2102                    return false;
2103                }
2104                editor.undoManager.transact(() => {
2105                    const bookmark = createBookmark(rng);
2106                    moveChildren(dom, commonAncestorParent, otherLi);
2107                    commonAncestorParent.remove();
2108                    const resolvedBookmark = resolveBookmark(bookmark);
2109                    editor.selection.setRng(resolvedBookmark);
2110                });
2111                return true;
2112            }
2113            else if (!otherLi) {
2114                if (!isForward && rng.startOffset === 0 && rng.endOffset === 0) {
2115                    editor.undoManager.transact(() => {
2116                        flattenListSelection(editor);
2117                    });
2118                    return true;
2119                }
2120            }
2121        }
2122        return false;
2123    };
2124    const removeBlock = (dom, block, root) => {
2125        const parentBlock = dom.getParent(block.parentNode, dom.isBlock, root);
2126        dom.remove(block);
2127        if (parentBlock && dom.isEmpty(parentBlock)) {
2128            dom.remove(parentBlock);
2129        }
2130    };
2131    const backspaceDeleteIntoListCaret = (editor, isForward) => {
2132        const dom = editor.dom;
2133        const selectionStartElm = editor.selection.getStart();
2134        const root = getClosestEditingHost(editor, selectionStartElm);
2135        const block = dom.getParent(selectionStartElm, dom.isBlock, root);
2136        if (block && dom.isEmpty(block, undefined, { checkRootAsContent: true })) {
2137            const rng = normalizeRange(editor.selection.getRng());
2138            const nextCaretContainer = findNextCaretContainer(editor, rng, isForward, root);
2139            const otherLi = dom.getParent(nextCaretContainer, 'LI', root);
2140            if (nextCaretContainer && otherLi) {
2141                const findValidElement = (element) => contains$1(['td', 'th', 'caption'], name(element));
2142                const findRoot = (node) => node.dom === root;
2143                const otherLiCell = closest$2(SugarElement.fromDom(otherLi), findValidElement, findRoot);
2144                const caretCell = closest$2(SugarElement.fromDom(rng.startContainer), findValidElement, findRoot);
2145                if (!equals(otherLiCell, caretCell, eq)) {
2146                    return false;
2147                }
2148                editor.undoManager.transact(() => {
2149                    const parentNode = otherLi.parentNode;
2150                    removeBlock(dom, block, root);
2151                    mergeWithAdjacentLists(dom, parentNode);
2152                    editor.selection.select(nextCaretContainer, true);
2153                    editor.selection.collapse(isForward);
2154                });
2155                return true;
2156            }
2157        }
2158        return false;
2159    };
2160    const backspaceDeleteCaret = (editor, isForward) => {
2161        return backspaceDeleteFromListToListCaret(editor, isForward) || backspaceDeleteIntoListCaret(editor, isForward);
2162    };
2163    const hasListSelection = (editor) => {
2164        const selectionStartElm = editor.selection.getStart();
2165        const root = getClosestEditingHost(editor, selectionStartElm);
2166        const startListParent = editor.dom.getParent(selectionStartElm, 'LI,DT,DD', root);
2167        return startListParent || getSelectedListItems(editor).length > 0;
2168    };
2169    const backspaceDeleteRange = (editor) => {
2170        if (hasListSelection(editor)) {
2171            editor.undoManager.transact(() => {
2172                // Some delete actions may prevent the input event from being fired. If we do not detect it, we fire it ourselves.
2173                let shouldFireInput = true;
2174                const inputHandler = () => shouldFireInput = false;
2175                editor.on('input', inputHandler);
2176                editor.execCommand('Delete');
2177                editor.off('input', inputHandler);
2178                if (shouldFireInput) {
2179                    editor.dispatch('input');
2180                }
2181                normalizeLists(editor.dom, editor.getBody());
2182            });
2183            return true;
2184        }
2185        return false;
2186    };
2187    const backspaceDelete = (editor, isForward) => {
2188        const selection = editor.selection;
2189        return !isWithinNonEditableList(editor, selection.getNode()) && (selection.isCollapsed() ?
2190            backspaceDeleteCaret(editor, isForward) : backspaceDeleteRange(editor));
2191    };
2192    const setup$2 = (editor) => {
2193        editor.on('ExecCommand', (e) => {
2194            const cmd = e.command.toLowerCase();
2195            if ((cmd === 'delete' || cmd === 'forwarddelete') && hasListSelection(editor)) {
2196                normalizeLists(editor.dom, editor.getBody());
2197            }
2198        });
2199        editor.on('keydown', (e) => {
2200            if (e.keyCode === global$4.BACKSPACE) {
2201                if (backspaceDelete(editor, false)) {
2202                    e.preventDefault();
2203                }
2204            }
2205            else if (e.keyCode === global$4.DELETE) {
2206                if (backspaceDelete(editor, true)) {
2207                    e.preventDefault();
2208                }
2209            }
2210        });
2211    };
2212
2213    const get = (editor) => ({
2214        backspaceDelete: (isForward) => {
2215            backspaceDelete(editor, isForward);
2216        }
2217    });
2218
2219    const updateList = (editor, update) => {
2220        const parentList = getParentList(editor);
2221        if (parentList === null || isWithinNonEditableList(editor, parentList)) {
2222            return;
2223        }
2224        editor.undoManager.transact(() => {
2225            if (isObject(update.styles)) {
2226                editor.dom.setStyles(parentList, update.styles);
2227            }
2228            if (isObject(update.attrs)) {
2229                each(update.attrs, (v, k) => editor.dom.setAttrib(parentList, k, v));
2230            }
2231        });
2232    };
2233
2234    // Example: 'AB' -> 28
2235    const parseAlphabeticBase26 = (str) => {
2236        const chars = reverse(trim(str).split(''));
2237        const values = map(chars, (char, i) => {
2238            const charValue = char.toUpperCase().charCodeAt(0) - 'A'.charCodeAt(0) + 1;
2239            return Math.pow(26, i) * charValue;
2240        });
2241        return foldl(values, (sum, v) => sum + v, 0);
2242    };
2243    // Example: 28 -> 'AB'
2244    const composeAlphabeticBase26 = (value) => {
2245        value--;
2246        if (value < 0) {
2247            return '';
2248        }
2249        else {
2250            const remainder = value % 26;
2251            const quotient = Math.floor(value / 26);
2252            const rest = composeAlphabeticBase26(quotient);
2253            const char = String.fromCharCode('A'.charCodeAt(0) + remainder);
2254            return rest + char;
2255        }
2256    };
2257    const isUppercase = (str) => /^[A-Z]+$/.test(str);
2258    const isLowercase = (str) => /^[a-z]+$/.test(str);
2259    const isNumeric = (str) => /^[0-9]+$/.test(str);
2260    const deduceListType = (start) => {
2261        if (isNumeric(start)) {
2262            return 2 /* ListType.Numeric */;
2263        }
2264        else if (isUppercase(start)) {
2265            return 0 /* ListType.UpperAlpha */;
2266        }
2267        else if (isLowercase(start)) {
2268            return 1 /* ListType.LowerAlpha */;
2269        }
2270        else if (isEmpty$2(start)) {
2271            return 3 /* ListType.None */;
2272        }
2273        else {
2274            return 4 /* ListType.Unknown */;
2275        }
2276    };
2277    const parseStartValue = (start) => {
2278        switch (deduceListType(start)) {
2279            case 2 /* ListType.Numeric */:
2280                return Optional.some({
2281                    listStyleType: Optional.none(),
2282                    start
2283                });
2284            case 0 /* ListType.UpperAlpha */:
2285                return Optional.some({
2286                    listStyleType: Optional.some('upper-alpha'),
2287                    start: parseAlphabeticBase26(start).toString()
2288                });
2289            case 1 /* ListType.LowerAlpha */:
2290                return Optional.some({
2291                    listStyleType: Optional.some('lower-alpha'),
2292                    start: parseAlphabeticBase26(start).toString()
2293                });
2294            case 3 /* ListType.None */:
2295                return Optional.some({
2296                    listStyleType: Optional.none(),
2297                    start: ''
2298                });
2299            case 4 /* ListType.Unknown */:
2300                return Optional.none();
2301        }
2302    };
2303    const parseDetail = (detail) => {
2304        const start = parseInt(detail.start, 10);
2305        if (is$2(detail.listStyleType, 'upper-alpha')) {
2306            return composeAlphabeticBase26(start);
2307        }
2308        else if (is$2(detail.listStyleType, 'lower-alpha')) {
2309            return composeAlphabeticBase26(start).toLowerCase();
2310        }
2311        else {
2312            return detail.start;
2313        }
2314    };
2315
2316    const open = (editor) => {
2317        // Find the current list and skip opening if the selection isn't in an ordered list
2318        const currentList = getParentList(editor);
2319        if (!isOlNode(currentList) || isWithinNonEditableList(editor, currentList)) {
2320            return;
2321        }
2322        editor.windowManager.open({
2323            title: 'List Properties',
2324            body: {
2325                type: 'panel',
2326                items: [
2327                    {
2328                        type: 'input',
2329                        name: 'start',
2330                        label: 'Start list at number',
2331                        inputMode: 'numeric'
2332                    }
2333                ]
2334            },
2335            initialData: {
2336                start: parseDetail({
2337                    start: editor.dom.getAttrib(currentList, 'start', '1'),
2338                    listStyleType: Optional.from(editor.dom.getStyle(currentList, 'list-style-type'))
2339                })
2340            },
2341            buttons: [
2342                {
2343                    type: 'cancel',
2344                    name: 'cancel',
2345                    text: 'Cancel'
2346                },
2347                {
2348                    type: 'submit',
2349                    name: 'save',
2350                    text: 'Save',
2351                    primary: true
2352                }
2353            ],
2354            onSubmit: (api) => {
2355                const data = api.getData();
2356                parseStartValue(data.start).each((detail) => {
2357                    editor.execCommand('mceListUpdate', false, {
2358                        attrs: {
2359                            start: detail.start === '1' ? '' : detail.start
2360                        },
2361                        styles: {
2362                            'list-style-type': detail.listStyleType.getOr('')
2363                        }
2364                    });
2365                });
2366                api.close();
2367            }
2368        });
2369    };
2370
2371    const queryListCommandState = (editor, listName) => () => {
2372        const parentList = getParentList(editor);
2373        return isNonNullable(parentList) && parentList.nodeName === listName;
2374    };
2375    const registerDialog = (editor) => {
2376        editor.addCommand('mceListProps', () => {
2377            open(editor);
2378        });
2379    };
2380    const register$2 = (editor) => {
2381        editor.on('BeforeExecCommand', (e) => {
2382            const cmd = e.command.toLowerCase();
2383            if (cmd === 'indent') {
2384                indentListSelection(editor);
2385            }
2386            else if (cmd === 'outdent') {
2387                outdentListSelection(editor);
2388            }
2389        });
2390        editor.addCommand('InsertUnorderedList', (ui, detail) => {
2391            toggleList(editor, 'UL', detail);
2392        });
2393        editor.addCommand('InsertOrderedList', (ui, detail) => {
2394            toggleList(editor, 'OL', detail);
2395        });
2396        editor.addCommand('InsertDefinitionList', (ui, detail) => {
2397            toggleList(editor, 'DL', detail);
2398        });
2399        editor.addCommand('RemoveList', () => {
2400            flattenListSelection(editor);
2401        });
2402        registerDialog(editor);
2403        editor.addCommand('mceListUpdate', (ui, detail) => {
2404            if (isObject(detail)) {
2405                updateList(editor, detail);
2406            }
2407        });
2408        editor.addQueryStateHandler('InsertUnorderedList', queryListCommandState(editor, 'UL'));
2409        editor.addQueryStateHandler('InsertOrderedList', queryListCommandState(editor, 'OL'));
2410        editor.addQueryStateHandler('InsertDefinitionList', queryListCommandState(editor, 'DL'));
2411    };
2412
2413    var global = tinymce.util.Tools.resolve('tinymce.html.Node');
2414
2415    const isTextNode = (node) => node.type === 3;
2416    const isEmpty = (nodeBuffer) => nodeBuffer.length === 0;
2417    const wrapInvalidChildren = (list) => {
2418        const insertListItem = (buffer, refNode) => {
2419            const li = global.create('li');
2420            each$1(buffer, (node) => li.append(node));
2421            if (refNode) {
2422                list.insert(li, refNode, true);
2423            }
2424            else {
2425                list.append(li);
2426            }
2427        };
2428        const reducer = (buffer, node) => {
2429            if (isTextNode(node)) {
2430                return [...buffer, node];
2431            }
2432            else if (!isEmpty(buffer) && !isTextNode(node)) {
2433                insertListItem(buffer, node);
2434                return [];
2435            }
2436            else {
2437                return buffer;
2438            }
2439        };
2440        const restBuffer = foldl(list.children(), reducer, []);
2441        if (!isEmpty(restBuffer)) {
2442            insertListItem(restBuffer);
2443        }
2444    };
2445    const setup$1 = (editor) => {
2446        editor.on('PreInit', () => {
2447            const { parser } = editor;
2448            parser.addNodeFilter('ul,ol', (nodes) => each$1(nodes, wrapInvalidChildren));
2449        });
2450    };
2451
2452    const setupTabKey = (editor) => {
2453        editor.on('keydown', (e) => {
2454            // Check for tab but not ctrl/cmd+tab since it switches browser tabs
2455            if (e.keyCode !== global$4.TAB || global$4.metaKeyPressed(e)) {
2456                return;
2457            }
2458            editor.undoManager.transact(() => {
2459                if (e.shiftKey ? outdentListSelection(editor) : indentListSelection(editor)) {
2460                    e.preventDefault();
2461                }
2462            });
2463        });
2464    };
2465    const setup = (editor) => {
2466        if (shouldIndentOnTab(editor)) {
2467            setupTabKey(editor);
2468        }
2469        setup$2(editor);
2470    };
2471
2472    const setupToggleButtonHandler = (editor, listName) => (api) => {
2473        const toggleButtonHandler = (e) => {
2474            api.setActive(inList(e.parents, listName));
2475            api.setEnabled(!isWithinNonEditableList(editor, e.element) && editor.selection.isEditable());
2476        };
2477        api.setEnabled(editor.selection.isEditable());
2478        return setNodeChangeHandler(editor, toggleButtonHandler);
2479    };
2480    const register$1 = (editor) => {
2481        const exec = (command) => () => editor.execCommand(command);
2482        if (!editor.hasPlugin('advlist')) {
2483            editor.ui.registry.addToggleButton('numlist', {
2484                icon: 'ordered-list',
2485                active: false,
2486                tooltip: 'Numbered list',
2487                onAction: exec('InsertOrderedList'),
2488                onSetup: setupToggleButtonHandler(editor, 'OL')
2489            });
2490            editor.ui.registry.addToggleButton('bullist', {
2491                icon: 'unordered-list',
2492                active: false,
2493                tooltip: 'Bullet list',
2494                onAction: exec('InsertUnorderedList'),
2495                onSetup: setupToggleButtonHandler(editor, 'UL')
2496            });
2497        }
2498    };
2499
2500    const setupMenuButtonHandler = (editor, listName) => (api) => {
2501        const menuButtonHandler = (e) => api.setEnabled(inList(e.parents, listName) && !isWithinNonEditableList(editor, e.element));
2502        return setNodeChangeHandler(editor, menuButtonHandler);
2503    };
2504    const register = (editor) => {
2505        const listProperties = {
2506            text: 'List properties...',
2507            icon: 'ordered-list',
2508            onAction: () => editor.execCommand('mceListProps'),
2509            onSetup: setupMenuButtonHandler(editor, 'OL')
2510        };
2511        editor.ui.registry.addMenuItem('listprops', listProperties);
2512        editor.ui.registry.addContextMenu('lists', {
2513            update: (node) => {
2514                const parentList = getParentList(editor, node);
2515                return isOlNode(parentList) ? ['listprops'] : [];
2516            }
2517        });
2518    };
2519
2520    var Plugin = () => {
2521        global$7.add('lists', (editor) => {
2522            register$3(editor);
2523            setup$1(editor);
2524            if (!editor.hasPlugin('rtc', true)) {
2525                setup(editor);
2526                register$2(editor);
2527            }
2528            else {
2529                registerDialog(editor);
2530            }
2531            register$1(editor);
2532            register(editor);
2533            return get(editor);
2534        });
2535    };
2536
2537    Plugin();
2538    /** *****
2539     * DO NOT EXPORT ANYTHING
2540     *
2541     * IF YOU DO ROLLUP WILL LEAVE A GLOBAL ON THE PAGE
2542     *******/
2543
2544})();

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.