/*!***************************************************
 * mark.js v9.0.0
 * https://markjs.io/
 * Copyright (c) 2014–2018, Julian Kühnel
 * Released under the MIT license https://git.io/vwTVl
 *****************************************************/

(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined'
        ? (module.exports = factory())
        : typeof define === 'function' && define.amd
          ? define(factory)
          : (global.Mark = factory());
})(this, function () {
    'use strict';

    function _typeof(obj) {
        if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
            _typeof = function (obj) {
                return typeof obj;
            };
        } else {
            _typeof = function (obj) {
                return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype
                    ? 'symbol'
                    : typeof obj;
            };
        }

        return _typeof(obj);
    }

    function _classCallCheck(instance, Constructor) {
        if (!(instance instanceof Constructor)) {
            throw new TypeError('Cannot call a class as a function');
        }
    }

    function _defineProperties(target, props) {
        for (var i = 0; i < props.length; i++) {
            var descriptor = props[i];
            descriptor.enumerable = descriptor.enumerable || false;
            descriptor.configurable = true;
            if ('value' in descriptor) descriptor.writable = true;
            Object.defineProperty(target, descriptor.key, descriptor);
        }
    }

    function _createClass(Constructor, protoProps, staticProps) {
        if (protoProps) _defineProperties(Constructor.prototype, protoProps);
        if (staticProps) _defineProperties(Constructor, staticProps);
        return Constructor;
    }

    function _extends() {
        _extends =
            Object.assign ||
            function (target) {
                for (var i = 1; i < arguments.length; i++) {
                    var source = arguments[i];

                    for (var key in source) {
                        if (Object.prototype.hasOwnProperty.call(source, key)) {
                            target[key] = source[key];
                        }
                    }
                }

                return target;
            };

        return _extends.apply(this, arguments);
    }

    var DOMIterator =
        /*#__PURE__*/
        (function () {
            function DOMIterator(ctx) {
                var iframes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
                var exclude = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
                var iframesTimeout = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 5000;

                _classCallCheck(this, DOMIterator);

                this.ctx = ctx;
                this.iframes = iframes;
                this.exclude = exclude;
                this.iframesTimeout = iframesTimeout;
            }

            _createClass(
                DOMIterator,
                [
                    {
                        key: 'getContexts',
                        value: function getContexts() {
                            var ctx,
                                filteredCtx = [];

                            if (typeof this.ctx === 'undefined' || !this.ctx) {
                                ctx = [];
                            } else if (NodeList.prototype.isPrototypeOf(this.ctx)) {
                                ctx = Array.prototype.slice.call(this.ctx);
                            } else if (Array.isArray(this.ctx)) {
                                ctx = this.ctx;
                            } else if (typeof this.ctx === 'string') {
                                ctx = Array.prototype.slice.call(document.querySelectorAll(this.ctx));
                            } else {
                                ctx = [this.ctx];
                            }

                            ctx.forEach(function (ctx) {
                                var isDescendant =
                                    filteredCtx.filter(function (contexts) {
                                        return contexts.contains(ctx);
                                    }).length > 0;

                                if (filteredCtx.indexOf(ctx) === -1 && !isDescendant) {
                                    filteredCtx.push(ctx);
                                }
                            });
                            return filteredCtx;
                        },
                    },
                    {
                        key: 'getIframeContents',
                        value: function getIframeContents(ifr, successFn) {
                            var errorFn =
                                arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function () {};
                            var doc;

                            try {
                                var ifrWin = ifr.contentWindow;
                                doc = ifrWin.document;

                                if (!ifrWin || !doc) {
                                    throw new Error('iframe inaccessible');
                                }
                            } catch (e) {
                                errorFn();
                            }

                            if (doc) {
                                successFn(doc);
                            }
                        },
                    },
                    {
                        key: 'isIframeBlank',
                        value: function isIframeBlank(ifr) {
                            var bl = 'about:blank',
                                src = ifr.getAttribute('src').trim(),
                                href = ifr.contentWindow.location.href;
                            return href === bl && src !== bl && src;
                        },
                    },
                    {
                        key: 'observeIframeLoad',
                        value: function observeIframeLoad(ifr, successFn, errorFn) {
                            var _this = this;

                            var called = false,
                                tout = null;

                            var listener = function listener() {
                                if (called) {
                                    return;
                                }

                                called = true;
                                clearTimeout(tout);

                                try {
                                    if (!_this.isIframeBlank(ifr)) {
                                        ifr.removeEventListener('load', listener);

                                        _this.getIframeContents(ifr, successFn, errorFn);
                                    }
                                } catch (e) {
                                    errorFn();
                                }
                            };

                            ifr.addEventListener('load', listener);
                            tout = setTimeout(listener, this.iframesTimeout);
                        },
                    },
                    {
                        key: 'onIframeReady',
                        value: function onIframeReady(ifr, successFn, errorFn) {
                            try {
                                if (ifr.contentWindow.document.readyState === 'complete') {
                                    if (this.isIframeBlank(ifr)) {
                                        this.observeIframeLoad(ifr, successFn, errorFn);
                                    } else {
                                        this.getIframeContents(ifr, successFn, errorFn);
                                    }
                                } else {
                                    this.observeIframeLoad(ifr, successFn, errorFn);
                                }
                            } catch (e) {
                                errorFn();
                            }
                        },
                    },
                    {
                        key: 'waitForIframes',
                        value: function waitForIframes(ctx, done) {
                            var _this2 = this;

                            var eachCalled = 0;
                            this.forEachIframe(
                                ctx,
                                function () {
                                    return true;
                                },
                                function (ifr) {
                                    eachCalled++;

                                    _this2.waitForIframes(ifr.querySelector('html'), function () {
                                        if (!--eachCalled) {
                                            done();
                                        }
                                    });
                                },
                                function (handled) {
                                    if (!handled) {
                                        done();
                                    }
                                }
                            );
                        },
                    },
                    {
                        key: 'forEachIframe',
                        value: function forEachIframe(ctx, filter, each) {
                            var _this3 = this;

                            var end =
                                arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : function () {};
                            var ifr = ctx.querySelectorAll('iframe'),
                                open = ifr.length,
                                handled = 0;
                            ifr = Array.prototype.slice.call(ifr);

                            var checkEnd = function checkEnd() {
                                if (--open <= 0) {
                                    end(handled);
                                }
                            };

                            if (!open) {
                                checkEnd();
                            }

                            ifr.forEach(function (ifr) {
                                if (DOMIterator.matches(ifr, _this3.exclude)) {
                                    checkEnd();
                                } else {
                                    _this3.onIframeReady(
                                        ifr,
                                        function (con) {
                                            if (filter(ifr)) {
                                                handled++;
                                                each(con);
                                            }

                                            checkEnd();
                                        },
                                        checkEnd
                                    );
                                }
                            });
                        },
                    },
                    {
                        key: 'createIterator',
                        value: function createIterator(ctx, whatToShow, filter) {
                            return document.createNodeIterator(ctx, whatToShow, filter, false);
                        },
                    },
                    {
                        key: 'createInstanceOnIframe',
                        value: function createInstanceOnIframe(contents) {
                            return new DOMIterator(contents.querySelector('html'), this.iframes);
                        },
                    },
                    {
                        key: 'compareNodeIframe',
                        value: function compareNodeIframe(node, prevNode, ifr) {
                            var compCurr = node.compareDocumentPosition(ifr),
                                prev = Node.DOCUMENT_POSITION_PRECEDING;

                            if (compCurr & prev) {
                                if (prevNode !== null) {
                                    var compPrev = prevNode.compareDocumentPosition(ifr),
                                        after = Node.DOCUMENT_POSITION_FOLLOWING;

                                    if (compPrev & after) {
                                        return true;
                                    }
                                } else {
                                    return true;
                                }
                            }

                            return false;
                        },
                    },
                    {
                        key: 'getIteratorNode',
                        value: function getIteratorNode(itr) {
                            var prevNode = itr.previousNode();
                            var node;

                            if (prevNode === null) {
                                node = itr.nextNode();
                            } else {
                                node = itr.nextNode() && itr.nextNode();
                            }

                            return {
                                prevNode: prevNode,
                                node: node,
                            };
                        },
                    },
                    {
                        key: 'checkIframeFilter',
                        value: function checkIframeFilter(node, prevNode, currIfr, ifr) {
                            var key = false,
                                handled = false;
                            ifr.forEach(function (ifrDict, i) {
                                if (ifrDict.val === currIfr) {
                                    key = i;
                                    handled = ifrDict.handled;
                                }
                            });

                            if (this.compareNodeIframe(node, prevNode, currIfr)) {
                                if (key === false && !handled) {
                                    ifr.push({
                                        val: currIfr,
                                        handled: true,
                                    });
                                } else if (key !== false && !handled) {
                                    ifr[key].handled = true;
                                }

                                return true;
                            }

                            if (key === false) {
                                ifr.push({
                                    val: currIfr,
                                    handled: false,
                                });
                            }

                            return false;
                        },
                    },
                    {
                        key: 'handleOpenIframes',
                        value: function handleOpenIframes(ifr, whatToShow, eCb, fCb) {
                            var _this4 = this;

                            ifr.forEach(function (ifrDict) {
                                if (!ifrDict.handled) {
                                    _this4.getIframeContents(ifrDict.val, function (con) {
                                        _this4.createInstanceOnIframe(con).forEachNode(whatToShow, eCb, fCb);
                                    });
                                }
                            });
                        },
                    },
                    {
                        key: 'iterateThroughNodes',
                        value: function iterateThroughNodes(whatToShow, ctx, eachCb, filterCb, doneCb) {
                            var _this5 = this;

                            var itr = this.createIterator(ctx, whatToShow, filterCb);

                            var ifr = [],
                                elements = [],
                                node,
                                prevNode,
                                retrieveNodes = function retrieveNodes() {
                                    var _this5$getIteratorNod = _this5.getIteratorNode(itr);

                                    prevNode = _this5$getIteratorNod.prevNode;
                                    node = _this5$getIteratorNod.node;
                                    return node;
                                };

                            while (retrieveNodes()) {
                                if (this.iframes) {
                                    this.forEachIframe(
                                        ctx,
                                        function (currIfr) {
                                            return _this5.checkIframeFilter(node, prevNode, currIfr, ifr);
                                        },
                                        function (con) {
                                            _this5.createInstanceOnIframe(con).forEachNode(
                                                whatToShow,
                                                function (ifrNode) {
                                                    return elements.push(ifrNode);
                                                },
                                                filterCb
                                            );
                                        }
                                    );
                                }

                                elements.push(node);
                            }

                            elements.forEach(function (node) {
                                eachCb(node);
                            });

                            if (this.iframes) {
                                this.handleOpenIframes(ifr, whatToShow, eachCb, filterCb);
                            }

                            doneCb();
                        },
                    },
                    {
                        key: 'forEachNode',
                        value: function forEachNode(whatToShow, each, filter) {
                            var _this6 = this;

                            var done =
                                arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : function () {};
                            var contexts = this.getContexts();
                            var open = contexts.length;

                            if (!open) {
                                done();
                            }

                            contexts.forEach(function (ctx) {
                                var ready = function ready() {
                                    _this6.iterateThroughNodes(whatToShow, ctx, each, filter, function () {
                                        if (--open <= 0) {
                                            done();
                                        }
                                    });
                                };

                                if (_this6.iframes) {
                                    _this6.waitForIframes(ctx, ready);
                                } else {
                                    ready();
                                }
                            });
                        },
                    },
                ],
                [
                    {
                        key: 'matches',
                        value: function matches(element, selector) {
                            var selectors = typeof selector === 'string' ? [selector] : selector,
                                fn =
                                    element.matches ||
                                    element.matchesSelector ||
                                    element.msMatchesSelector ||
                                    element.mozMatchesSelector ||
                                    element.oMatchesSelector ||
                                    element.webkitMatchesSelector;

                            if (fn) {
                                var match = false;
                                selectors.every(function (sel) {
                                    if (fn.call(element, sel)) {
                                        match = true;
                                        return false;
                                    }

                                    return true;
                                });
                                return match;
                            } else {
                                return false;
                            }
                        },
                    },
                ]
            );

            return DOMIterator;
        })();

    var RegExpCreator =
        /*#__PURE__*/
        (function () {
            function RegExpCreator(options) {
                _classCallCheck(this, RegExpCreator);

                this.opt = _extends(
                    {},
                    {
                        diacritics: true,
                        synonyms: {},
                        accuracy: 'partially',
                        caseSensitive: false,
                        ignoreJoiners: false,
                        ignorePunctuation: [],
                        wildcards: 'disabled',
                    },
                    options
                );
            }

            _createClass(RegExpCreator, [
                {
                    key: 'create',
                    value: function create(str) {
                        if (this.opt.wildcards !== 'disabled') {
                            str = this.setupWildcardsRegExp(str);
                        }

                        str = this.escapeStr(str);

                        if (Object.keys(this.opt.synonyms).length) {
                            str = this.createSynonymsRegExp(str);
                        }

                        if (this.opt.ignoreJoiners || this.opt.ignorePunctuation.length) {
                            str = this.setupIgnoreJoinersRegExp(str);
                        }

                        if (this.opt.diacritics) {
                            str = this.createDiacriticsRegExp(str);
                        }

                        str = this.createMergedBlanksRegExp(str);

                        if (this.opt.ignoreJoiners || this.opt.ignorePunctuation.length) {
                            str = this.createJoinersRegExp(str);
                        }

                        if (this.opt.wildcards !== 'disabled') {
                            str = this.createWildcardsRegExp(str);
                        }

                        str = this.createAccuracyRegExp(str);
                        return new RegExp(str, 'gm'.concat(this.opt.caseSensitive ? '' : 'i'));
                    },
                },
                {
                    key: 'sortByLength',
                    value: function sortByLength(arry) {
                        return arry.sort(function (a, b) {
                            return a.length === b.length ? (a > b ? 1 : -1) : b.length - a.length;
                        });
                    },
                },
                {
                    key: 'escapeStr',
                    value: function escapeStr(str) {
                        return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
                    },
                },
                {
                    key: 'createSynonymsRegExp',
                    value: function createSynonymsRegExp(str) {
                        var _this = this;

                        var syn = this.opt.synonyms,
                            sens = this.opt.caseSensitive ? '' : 'i',
                            joinerPlaceholder = this.opt.ignoreJoiners || this.opt.ignorePunctuation.length ? '\0' : '';

                        for (var index in syn) {
                            if (syn.hasOwnProperty(index)) {
                                var keys = Array.isArray(syn[index]) ? syn[index] : [syn[index]];
                                keys.unshift(index);
                                keys = this.sortByLength(keys)
                                    .map(function (key) {
                                        if (_this.opt.wildcards !== 'disabled') {
                                            key = _this.setupWildcardsRegExp(key);
                                        }

                                        key = _this.escapeStr(key);
                                        return key;
                                    })
                                    .filter(function (k) {
                                        return k !== '';
                                    });

                                if (keys.length > 1) {
                                    str = str.replace(
                                        new RegExp(
                                            '('.concat(
                                                keys
                                                    .map(function (k) {
                                                        return _this.escapeStr(k);
                                                    })
                                                    .join('|'),
                                                ')'
                                            ),
                                            'gm'.concat(sens)
                                        ),
                                        joinerPlaceholder +
                                            '('.concat(
                                                keys
                                                    .map(function (k) {
                                                        return _this.processSynonyms(k);
                                                    })
                                                    .join('|'),
                                                ')'
                                            ) +
                                            joinerPlaceholder
                                    );
                                }
                            }
                        }

                        return str;
                    },
                },
                {
                    key: 'processSynonyms',
                    value: function processSynonyms(str) {
                        if (this.opt.ignoreJoiners || this.opt.ignorePunctuation.length) {
                            str = this.setupIgnoreJoinersRegExp(str);
                        }

                        return str;
                    },
                },
                {
                    key: 'setupWildcardsRegExp',
                    value: function setupWildcardsRegExp(str) {
                        str = str.replace(/(?:\\)*\?/g, function (val) {
                            return val.charAt(0) === '\\' ? '?' : '\x01';
                        });
                        return str.replace(/(?:\\)*\*/g, function (val) {
                            return val.charAt(0) === '\\' ? '*' : '\x02';
                        });
                    },
                },
                {
                    key: 'createWildcardsRegExp',
                    value: function createWildcardsRegExp(str) {
                        var spaces = this.opt.wildcards === 'withSpaces';
                        return str
                            .replace(/\u0001/g, spaces ? '[\\S\\s]?' : '\\S?')
                            .replace(/\u0002/g, spaces ? '[\\S\\s]*?' : '\\S*');
                    },
                },
                {
                    key: 'setupIgnoreJoinersRegExp',
                    value: function setupIgnoreJoinersRegExp(str) {
                        return str.replace(/[^(|)\\]/g, function (val, indx, original) {
                            var nextChar = original.charAt(indx + 1);

                            if (/[(|)\\]/.test(nextChar) || nextChar === '') {
                                return val;
                            } else {
                                return val + '\0';
                            }
                        });
                    },
                },
                {
                    key: 'createJoinersRegExp',
                    value: function createJoinersRegExp(str) {
                        var joiner = [];
                        var ignorePunctuation = this.opt.ignorePunctuation;

                        if (Array.isArray(ignorePunctuation) && ignorePunctuation.length) {
                            joiner.push(this.escapeStr(ignorePunctuation.join('')));
                        }

                        if (this.opt.ignoreJoiners) {
                            joiner.push('\\u00ad\\u200b\\u200c\\u200d');
                        }

                        return joiner.length ? str.split(/\u0000+/).join('['.concat(joiner.join(''), ']*')) : str;
                    },
                },
                {
                    key: 'createDiacriticsRegExp',
                    value: function createDiacriticsRegExp(str) {
                        var sens = this.opt.caseSensitive ? '' : 'i',
                            dct = this.opt.caseSensitive
                                ? [
                                      'aàáảãạăằắẳẵặâầấẩẫậäåāą',
                                      'AÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ',
                                      'cçćč',
                                      'CÇĆČ',
                                      'dđď',
                                      'DĐĎ',
                                      'eèéẻẽẹêềếểễệëěēę',
                                      'EÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ',
                                      'iìíỉĩịîïī',
                                      'IÌÍỈĨỊÎÏĪ',
                                      'lł',
                                      'LŁ',
                                      'nñňń',
                                      'NÑŇŃ',
                                      'oòóỏõọôồốổỗộơởỡớờợöøō',
                                      'OÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ',
                                      'rř',
                                      'RŘ',
                                      'sšśșş',
                                      'SŠŚȘŞ',
                                      'tťțţ',
                                      'TŤȚŢ',
                                      'uùúủũụưừứửữựûüůū',
                                      'UÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ',
                                      'yýỳỷỹỵÿ',
                                      'YÝỲỶỸỴŸ',
                                      'zžżź',
                                      'ZŽŻŹ',
                                  ]
                                : [
                                      'aàáảãạăằắẳẵặâầấẩẫậäåāąAÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ',
                                      'cçćčCÇĆČ',
                                      'dđďDĐĎ',
                                      'eèéẻẽẹêềếểễệëěēęEÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ',
                                      'iìíỉĩịîïīIÌÍỈĨỊÎÏĪ',
                                      'lłLŁ',
                                      'nñňńNÑŇŃ',
                                      'oòóỏõọôồốổỗộơởỡớờợöøōOÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ',
                                      'rřRŘ',
                                      'sšśșşSŠŚȘŞ',
                                      'tťțţTŤȚŢ',
                                      'uùúủũụưừứửữựûüůūUÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ',
                                      'yýỳỷỹỵÿYÝỲỶỸỴŸ',
                                      'zžżźZŽŻŹ',
                                  ];
                        var handled = [];
                        str.split('').forEach(function (ch) {
                            dct.every(function (dct) {
                                if (dct.indexOf(ch) !== -1) {
                                    if (handled.indexOf(dct) > -1) {
                                        return false;
                                    }

                                    str = str.replace(
                                        new RegExp('['.concat(dct, ']'), 'gm'.concat(sens)),
                                        '['.concat(dct, ']')
                                    );
                                    handled.push(dct);
                                }

                                return true;
                            });
                        });
                        return str;
                    },
                },
                {
                    key: 'createMergedBlanksRegExp',
                    value: function createMergedBlanksRegExp(str) {
                        return str.replace(/[\s]+/gim, '[\\s]+');
                    },
                },
                {
                    key: 'createAccuracyRegExp',
                    value: function createAccuracyRegExp(str) {
                        var _this2 = this;

                        var chars = '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~¡¿';
                        var acc = this.opt.accuracy,
                            val = typeof acc === 'string' ? acc : acc.value,
                            ls = typeof acc === 'string' ? [] : acc.limiters,
                            lsJoin = '';
                        ls.forEach(function (limiter) {
                            lsJoin += '|'.concat(_this2.escapeStr(limiter));
                        });

                        switch (val) {
                            case 'partially':
                            default:
                                return '()('.concat(str, ')');

                            case 'complementary':
                                lsJoin = '\\s' + (lsJoin ? lsJoin : this.escapeStr(chars));
                                return '()([^'.concat(lsJoin, ']*').concat(str, '[^').concat(lsJoin, ']*)');

                            case 'exactly':
                                return '(^|\\s'.concat(lsJoin, ')(').concat(str, ')(?=$|\\s').concat(lsJoin, ')');
                        }
                    },
                },
            ]);

            return RegExpCreator;
        })();

    var Mark =
        /*#__PURE__*/
        (function () {
            function Mark(ctx) {
                _classCallCheck(this, Mark);

                this.ctx = ctx;
                this.ie = false;
                var ua = window.navigator.userAgent;

                if (ua.indexOf('MSIE') > -1 || ua.indexOf('Trident') > -1) {
                    this.ie = true;
                }
            }

            _createClass(Mark, [
                {
                    key: 'log',
                    value: function log(msg) {
                        var level = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'debug';
                        var log = this.opt.log;

                        if (!this.opt.debug) {
                            return;
                        }

                        if (_typeof(log) === 'object' && typeof log[level] === 'function') {
                            log[level]('mark.js: '.concat(msg));
                        }
                    },
                },
                {
                    key: 'getSeparatedKeywords',
                    value: function getSeparatedKeywords(sv) {
                        var _this = this;

                        var stack = [];
                        sv.forEach(function (kw) {
                            if (!_this.opt.separateWordSearch) {
                                if (kw.trim() && stack.indexOf(kw) === -1) {
                                    stack.push(kw);
                                }
                            } else {
                                kw.split(' ').forEach(function (kwSplitted) {
                                    if (kwSplitted.trim() && stack.indexOf(kwSplitted) === -1) {
                                        stack.push(kwSplitted);
                                    }
                                });
                            }
                        });
                        return {
                            keywords: stack.sort(function (a, b) {
                                return b.length - a.length;
                            }),
                            length: stack.length,
                        };
                    },
                },
                {
                    key: 'isNumeric',
                    value: function isNumeric(value) {
                        return Number(parseFloat(value)) == value;
                    },
                },
                {
                    key: 'checkRanges',
                    value: function checkRanges(array) {
                        var _this2 = this;

                        if (!Array.isArray(array) || Object.prototype.toString.call(array[0]) !== '[object Object]') {
                            this.log('markRanges() will only accept an array of objects');
                            this.opt.noMatch(array);
                            return [];
                        }

                        var stack = [];
                        var last = 0;
                        array
                            .sort(function (a, b) {
                                return a.start - b.start;
                            })
                            .forEach(function (item) {
                                var _this2$callNoMatchOnI = _this2.callNoMatchOnInvalidRanges(item, last),
                                    start = _this2$callNoMatchOnI.start,
                                    end = _this2$callNoMatchOnI.end,
                                    valid = _this2$callNoMatchOnI.valid;

                                if (valid) {
                                    item.start = start;
                                    item.length = end - start;
                                    stack.push(item);
                                    last = end;
                                }
                            });
                        return stack;
                    },
                },
                {
                    key: 'callNoMatchOnInvalidRanges',
                    value: function callNoMatchOnInvalidRanges(range, last) {
                        var start,
                            end,
                            valid = false;

                        if (range && typeof range.start !== 'undefined') {
                            start = parseInt(range.start, 10);
                            end = start + parseInt(range.length, 10);

                            if (
                                this.isNumeric(range.start) &&
                                this.isNumeric(range.length) &&
                                end - last > 0 &&
                                end - start > 0
                            ) {
                                valid = true;
                            } else {
                                this.log('Ignoring invalid or overlapping range: ' + ''.concat(JSON.stringify(range)));
                                this.opt.noMatch(range);
                            }
                        } else {
                            this.log('Ignoring invalid range: '.concat(JSON.stringify(range)));
                            this.opt.noMatch(range);
                        }

                        return {
                            start: start,
                            end: end,
                            valid: valid,
                        };
                    },
                },
                {
                    key: 'checkWhitespaceRanges',
                    value: function checkWhitespaceRanges(range, originalLength, string) {
                        var end,
                            valid = true,
                            max = string.length,
                            offset = originalLength - max,
                            start = parseInt(range.start, 10) - offset;
                        start = start > max ? max : start;
                        end = start + parseInt(range.length, 10);

                        if (end > max) {
                            end = max;
                            this.log('End range automatically set to the max value of '.concat(max));
                        }

                        if (start < 0 || end - start < 0 || start > max || end > max) {
                            valid = false;
                            this.log('Invalid range: '.concat(JSON.stringify(range)));
                            this.opt.noMatch(range);
                        } else if (string.substring(start, end).replace(/\s+/g, '') === '') {
                            valid = false;
                            this.log('Skipping whitespace only range: ' + JSON.stringify(range));
                            this.opt.noMatch(range);
                        }

                        return {
                            start: start,
                            end: end,
                            valid: valid,
                        };
                    },
                },
                {
                    key: 'getTextNodes',
                    value: function getTextNodes(cb) {
                        var _this3 = this;

                        var val = '',
                            nodes = [];
                        this.iterator.forEachNode(
                            NodeFilter.SHOW_TEXT,
                            function (node) {
                                nodes.push({
                                    start: val.length,
                                    end: (val += node.textContent).length,
                                    node: node,
                                });
                            },
                            function (node) {
                                if (_this3.matchesExclude(node.parentNode)) {
                                    return NodeFilter.FILTER_REJECT;
                                } else {
                                    return NodeFilter.FILTER_ACCEPT;
                                }
                            },
                            function () {
                                cb({
                                    value: val,
                                    nodes: nodes,
                                });
                            }
                        );
                    },
                },
                {
                    key: 'matchesExclude',
                    value: function matchesExclude(el) {
                        return DOMIterator.matches(
                            el,
                            this.opt.exclude.concat(['script', 'style', 'title', 'head', 'html'])
                        );
                    },
                },
                {
                    key: 'wrapRangeInTextNode',
                    value: function wrapRangeInTextNode(node, start, end) {
                        var hEl = !this.opt.element ? 'mark' : this.opt.element,
                            startNode = node.splitText(start),
                            ret = startNode.splitText(end - start);
                        var repl = document.createElement(hEl);
                        repl.setAttribute('data-markjs', 'true');

                        if (this.opt.className) {
                            repl.setAttribute('class', this.opt.className);
                        }

                        repl.textContent = startNode.textContent;
                        startNode.parentNode.replaceChild(repl, startNode);
                        return ret;
                    },
                },
                {
                    key: 'wrapRangeInMappedTextNode',
                    value: function wrapRangeInMappedTextNode(dict, start, end, filterCb, eachCb) {
                        var _this4 = this;

                        dict.nodes.every(function (n, i) {
                            var sibl = dict.nodes[i + 1];

                            if (typeof sibl === 'undefined' || sibl.start > start) {
                                if (!filterCb(n.node)) {
                                    return false;
                                }

                                var s = start - n.start,
                                    e = (end > n.end ? n.end : end) - n.start,
                                    startStr = dict.value.substr(0, n.start),
                                    endStr = dict.value.substr(e + n.start);
                                n.node = _this4.wrapRangeInTextNode(n.node, s, e);
                                dict.value = startStr + endStr;
                                dict.nodes.forEach(function (k, j) {
                                    if (j >= i) {
                                        if (dict.nodes[j].start > 0 && j !== i) {
                                            dict.nodes[j].start -= e;
                                        }

                                        dict.nodes[j].end -= e;
                                    }
                                });
                                end -= e;
                                eachCb(n.node.previousSibling, n.start);

                                if (end > n.end) {
                                    start = n.end;
                                } else {
                                    return false;
                                }
                            }

                            return true;
                        });
                    },
                },
                {
                    key: 'wrapGroups',
                    value: function wrapGroups(node, pos, len, eachCb) {
                        node = this.wrapRangeInTextNode(node, pos, pos + len);
                        eachCb(node.previousSibling);
                        return node;
                    },
                },
                {
                    key: 'separateGroups',
                    value: function separateGroups(node, match, matchIdx, filterCb, eachCb) {
                        var matchLen = match.length;

                        for (var i = 1; i < matchLen; i++) {
                            var pos = node.textContent.indexOf(match[i]);

                            if (match[i] && pos > -1 && filterCb(match[i], node)) {
                                node = this.wrapGroups(node, pos, match[i].length, eachCb);
                            }
                        }

                        return node;
                    },
                },
                {
                    key: 'wrapMatches',
                    value: function wrapMatches(regex, ignoreGroups, filterCb, eachCb, endCb) {
                        var _this5 = this;

                        var matchIdx = ignoreGroups === 0 ? 0 : ignoreGroups + 1;
                        this.getTextNodes(function (dict) {
                            dict.nodes.forEach(function (node) {
                                node = node.node;
                                var match;

                                while ((match = regex.exec(node.textContent)) !== null && match[matchIdx] !== '') {
                                    if (_this5.opt.separateGroups) {
                                        node = _this5.separateGroups(node, match, matchIdx, filterCb, eachCb);
                                    } else {
                                        if (!filterCb(match[matchIdx], node)) {
                                            continue;
                                        }

                                        var pos = match.index;

                                        if (matchIdx !== 0) {
                                            for (var i = 1; i < matchIdx; i++) {
                                                pos += match[i].length;
                                            }
                                        }

                                        node = _this5.wrapGroups(node, pos, match[matchIdx].length, eachCb);
                                    }

                                    regex.lastIndex = 0;
                                }
                            });
                            endCb();
                        });
                    },
                },
                {
                    key: 'wrapMatchesAcrossElements',
                    value: function wrapMatchesAcrossElements(regex, ignoreGroups, filterCb, eachCb, endCb) {
                        var _this6 = this;

                        var matchIdx = ignoreGroups === 0 ? 0 : ignoreGroups + 1;
                        this.getTextNodes(function (dict) {
                            var match;

                            while ((match = regex.exec(dict.value)) !== null && match[matchIdx] !== '') {
                                var start = match.index;

                                if (matchIdx !== 0) {
                                    for (var i = 1; i < matchIdx; i++) {
                                        start += match[i].length;
                                    }
                                }

                                var end = start + match[matchIdx].length;

                                _this6.wrapRangeInMappedTextNode(
                                    dict,
                                    start,
                                    end,
                                    function (node) {
                                        return filterCb(match[matchIdx], node);
                                    },
                                    function (node, lastIndex) {
                                        regex.lastIndex = lastIndex;
                                        eachCb(node);
                                    }
                                );
                            }

                            endCb();
                        });
                    },
                },
                {
                    key: 'wrapRangeFromIndex',
                    value: function wrapRangeFromIndex(ranges, filterCb, eachCb, endCb) {
                        var _this7 = this;

                        this.getTextNodes(function (dict) {
                            var originalLength = dict.value.length;
                            ranges.forEach(function (range, counter) {
                                var _this7$checkWhitespac = _this7.checkWhitespaceRanges(
                                        range,
                                        originalLength,
                                        dict.value
                                    ),
                                    start = _this7$checkWhitespac.start,
                                    end = _this7$checkWhitespac.end,
                                    valid = _this7$checkWhitespac.valid;

                                if (valid) {
                                    _this7.wrapRangeInMappedTextNode(
                                        dict,
                                        start,
                                        end,
                                        function (node) {
                                            return filterCb(node, range, dict.value.substring(start, end), counter);
                                        },
                                        function (node) {
                                            eachCb(node, range);
                                        }
                                    );
                                }
                            });
                            endCb();
                        });
                    },
                },
                {
                    key: 'unwrapMatches',
                    value: function unwrapMatches(node) {
                        var parent = node.parentNode;
                        var docFrag = document.createDocumentFragment();

                        while (node.firstChild) {
                            docFrag.appendChild(node.removeChild(node.firstChild));
                        }

                        parent.replaceChild(docFrag, node);

                        if (!this.ie) {
                            parent.normalize();
                        } else {
                            this.normalizeTextNode(parent);
                        }
                    },
                },
                {
                    key: 'normalizeTextNode',
                    value: function normalizeTextNode(node) {
                        if (!node) {
                            return;
                        }

                        if (node.nodeType === 3) {
                            while (node.nextSibling && node.nextSibling.nodeType === 3) {
                                node.nodeValue += node.nextSibling.nodeValue;
                                node.parentNode.removeChild(node.nextSibling);
                            }
                        } else {
                            this.normalizeTextNode(node.firstChild);
                        }

                        this.normalizeTextNode(node.nextSibling);
                    },
                },
                {
                    key: 'markRegExp',
                    value: function markRegExp(regexp, opt) {
                        var _this8 = this;

                        this.opt = opt;
                        this.log('Searching with expression "'.concat(regexp, '"'));
                        var totalMatches = 0,
                            fn = 'wrapMatches';

                        var eachCb = function eachCb(element) {
                            totalMatches++;

                            _this8.opt.each(element);
                        };

                        if (this.opt.acrossElements) {
                            fn = 'wrapMatchesAcrossElements';
                        }

                        this[fn](
                            regexp,
                            this.opt.ignoreGroups,
                            function (match, node) {
                                return _this8.opt.filter(node, match, totalMatches);
                            },
                            eachCb,
                            function () {
                                if (totalMatches === 0) {
                                    _this8.opt.noMatch(regexp);
                                }

                                _this8.opt.done(totalMatches);
                            }
                        );
                    },
                },
                {
                    key: 'mark',
                    value: function mark(sv, opt) {
                        var _this9 = this;

                        this.opt = opt;
                        var totalMatches = 0,
                            fn = 'wrapMatches';

                        var _this$getSeparatedKey = this.getSeparatedKeywords(typeof sv === 'string' ? [sv] : sv),
                            kwArr = _this$getSeparatedKey.keywords,
                            kwArrLen = _this$getSeparatedKey.length,
                            handler = function handler(kw) {
                                var regex = new RegExpCreator(_this9.opt).create(kw);
                                var matches = 0;

                                _this9.log('Searching with expression "'.concat(regex, '"'));

                                _this9[fn](
                                    regex,
                                    1,
                                    function (term, node) {
                                        return _this9.opt.filter(node, kw, totalMatches, matches);
                                    },
                                    function (element) {
                                        matches++;
                                        totalMatches++;

                                        _this9.opt.each(element);
                                    },
                                    function () {
                                        if (matches === 0) {
                                            _this9.opt.noMatch(kw);
                                        }

                                        if (kwArr[kwArrLen - 1] === kw) {
                                            _this9.opt.done(totalMatches);
                                        } else {
                                            handler(kwArr[kwArr.indexOf(kw) + 1]);
                                        }
                                    }
                                );
                            };

                        if (this.opt.acrossElements) {
                            fn = 'wrapMatchesAcrossElements';
                        }

                        if (kwArrLen === 0) {
                            this.opt.done(totalMatches);
                        } else {
                            handler(kwArr[0]);
                        }
                    },
                },
                {
                    key: 'markRanges',
                    value: function markRanges(rawRanges, opt) {
                        var _this10 = this;

                        this.opt = opt;
                        var totalMatches = 0,
                            ranges = this.checkRanges(rawRanges);

                        if (ranges && ranges.length) {
                            this.log('Starting to mark with the following ranges: ' + JSON.stringify(ranges));
                            this.wrapRangeFromIndex(
                                ranges,
                                function (node, range, match, counter) {
                                    return _this10.opt.filter(node, range, match, counter);
                                },
                                function (element, range) {
                                    totalMatches++;

                                    _this10.opt.each(element, range);
                                },
                                function () {
                                    _this10.opt.done(totalMatches);
                                }
                            );
                        } else {
                            this.opt.done(totalMatches);
                        }
                    },
                },
                {
                    key: 'unmark',
                    value: function unmark(opt) {
                        var _this11 = this;

                        this.opt = opt;
                        var sel = this.opt.element ? this.opt.element : '*';
                        sel += '[data-markjs]';

                        if (this.opt.className) {
                            sel += '.'.concat(this.opt.className);
                        }

                        this.log('Removal selector "'.concat(sel, '"'));
                        this.iterator.forEachNode(
                            NodeFilter.SHOW_ELEMENT,
                            function (node) {
                                _this11.unwrapMatches(node);
                            },
                            function (node) {
                                var matchesSel = DOMIterator.matches(node, sel),
                                    matchesExclude = _this11.matchesExclude(node);

                                if (!matchesSel || matchesExclude) {
                                    return NodeFilter.FILTER_REJECT;
                                } else {
                                    return NodeFilter.FILTER_ACCEPT;
                                }
                            },
                            this.opt.done
                        );
                    },
                },
                {
                    key: 'opt',
                    set: function set(val) {
                        this._opt = _extends(
                            {},
                            {
                                element: '',
                                className: '',
                                exclude: [],
                                iframes: false,
                                iframesTimeout: 5000,
                                separateWordSearch: true,
                                acrossElements: false,
                                ignoreGroups: 0,
                                each: function each() {},
                                noMatch: function noMatch() {},
                                filter: function filter() {
                                    return true;
                                },
                                done: function done() {},
                                debug: false,
                                log: window.console,
                            },
                            val
                        );
                    },
                    get: function get() {
                        return this._opt;
                    },
                },
                {
                    key: 'iterator',
                    get: function get() {
                        return new DOMIterator(this.ctx, this.opt.iframes, this.opt.exclude, this.opt.iframesTimeout);
                    },
                },
            ]);

            return Mark;
        })();

    function Mark$1(ctx) {
        var _this = this;

        var instance = new Mark(ctx);

        this.mark = function (sv, opt) {
            instance.mark(sv, opt);
            return _this;
        };

        this.markRegExp = function (sv, opt) {
            instance.markRegExp(sv, opt);
            return _this;
        };

        this.markRanges = function (sv, opt) {
            instance.markRanges(sv, opt);
            return _this;
        };

        this.unmark = function (opt) {
            instance.unmark(opt);
            return _this;
        };

        return this;
    }

    return Mark$1;
});
