{"version":3,"file":"module.js","sources":["../src/helpers.ts","../node_modules/diff-dom/dist/module.js","../src/virtual_dom.ts","../node_modules/dayjs/dayjs.min.js","../node_modules/dayjs/plugin/customParseFormat.js","../src/date.ts","../src/read_data.ts","../src/rows.ts","../src/columns.ts","../src/column_settings.ts","../src/templates.ts","../src/config.ts","../src/virtual_pager_dom.ts","../src/datatable.ts","../src/convert/csv.ts","../src/convert/json.ts","../src/export/csv.ts","../src/export/json.ts","../src/export/sql.ts","../src/export/txt.ts","../src/editing/config.ts","../src/editing/editor.ts","../src/editing/helpers.ts","../src/column_filter/config.ts","../src/column_filter/column_filter.ts"],"sourcesContent":["import {\n    cellDataType,\n    cellType,\n    columnSettingsType,\n    inputCellType,\n    nodeType,\n    textNodeType\n} from \"./types\"\n\n/**\n * Check is item is object\n */\nexport const isObject = (val: (string | number | boolean | object | null | undefined )) => Object.prototype.toString.call(val) === \"[object Object]\"\n\n/**\n * Check for valid JSON string\n */\nexport const isJson = (str: string) => {\n    let t = !1\n    try {\n        t = JSON.parse(str)\n    } catch (e) {\n        return !1\n    }\n    return !(null === t || (!Array.isArray(t) && !isObject(t))) && t\n}\n\n/**\n * Create DOM element node\n */\nexport const createElement = (nodeName: string, attrs?: { [key: string]: string}) => {\n    const dom = document.createElement(nodeName)\n    if (attrs && \"object\" == typeof attrs) {\n        for (const attr in attrs) {\n            if (\"html\" === attr) {\n                dom.innerHTML = attrs[attr]\n            } else {\n                dom.setAttribute(attr, attrs[attr])\n            }\n        }\n    }\n    return dom\n}\n\nexport const objToText = (obj: nodeType) => {\n    if ([\"#text\", \"#comment\"].includes(obj.nodeName)) {\n        return (obj as textNodeType).data\n    }\n    if (obj.childNodes) {\n        return obj.childNodes.map((childNode: nodeType) => objToText(childNode)).join(\"\")\n    }\n    return \"\"\n}\n\nexport const cellToText = (obj: inputCellType | cellDataType | null | undefined): string => {\n    if (obj === null || obj === undefined) {\n        return \"\"\n    } else if (obj.hasOwnProperty(\"text\") || obj.hasOwnProperty(\"data\")) {\n        const cell = obj as cellType\n        return cell.text ?? cellToText(cell.data)\n    } else if (obj.hasOwnProperty(\"nodeName\")) {\n        return objToText(obj as nodeType)\n    }\n    return String(obj)\n}\n\n\nexport const escapeText = function(text: string) {\n    return text\n        .replace(/&/g, \"&amp;\")\n        .replace(/</g, \"&lt;\")\n        .replace(/>/g, \"&gt;\")\n        .replace(/\"/g, \"&quot;\")\n}\n\n\nexport const visibleToColumnIndex = function(visibleIndex: number, columns: columnSettingsType[]) {\n    let counter = 0\n    let columnIndex = 0\n    while (counter < (visibleIndex+1)) {\n        const columnSettings = columns[columnIndex]\n        if (!columnSettings.hidden) {\n            counter += 1\n        }\n        columnIndex += 1\n    }\n    return columnIndex-1\n}\n\nexport const columnToVisibleIndex = function(columnIndex: number, columns: columnSettingsType[]) {\n    let visibleIndex = columnIndex\n    let counter = 0\n    while (counter < columnIndex) {\n        const columnSettings = columns[counter]\n        if (columnSettings.hidden) {\n            visibleIndex -= 1\n        }\n        counter++\n    }\n    return visibleIndex\n}\n\n/**\n * Converts a [NamedNodeMap](https://developer.mozilla.org/en-US/docs/Web/API/NamedNodeMap) into a normal object.\n *\n * @param map The `NamedNodeMap` to convert\n */\nexport const namedNodeMapToObject = function(map: NamedNodeMap) {\n    const obj = {}\n    if (map) {\n        for (const attr of map) {\n            obj[attr.name] = attr.value\n        }\n    }\n    return obj\n}\n\n/**\n * Convert class names to a CSS selector. Multiple classes should be separated by spaces.\n * Examples:\n *  - \"my-class\" -> \".my-class\"\n *  - \"my-class second-class\" -> \".my-class.second-class\"\n *\n * @param classNames The class names to convert. Can contain multiple classes separated by spaces.\n */\nexport const classNamesToSelector = (classNames: string) => {\n    if (!classNames) {\n        return null\n    }\n    return classNames.trim().split(\" \").map(className => `.${className}`).join(\"\")\n}\n\n/**\n * Check if the element contains all the classes. Multiple classes should be separated by spaces.\n *\n * @param element The element that will be checked\n * @param classes The classes that must be present in the element. Can contain multiple classes separated by spaces.\n */\nexport const containsClass = (element: Element, classes: string) => {\n    const hasMissingClass = classes?.split(\" \").some(className => !element.classList.contains(className))\n    return !hasMissingClass\n}\n\n/**\n * Join two strings with spaces. Null values are ignored.\n * Examples:\n *  - joinWithSpaces(\"a\", \"b\") -> \"a b\"\n *  - joinWithSpaces(\"a\", null) -> \"a\"\n *  - joinWithSpaces(null, \"b\") -> \"b\"\n *  - joinWithSpaces(\"a\", \"b c\") -> \"a b c\"\n *\n * @param first The first string to join\n * @param second The second string to join\n */\nexport const joinWithSpaces = (first: string | null | undefined, second: string | null | undefined) => {\n    if (first) {\n        if (second) {\n            return `${first} ${second}`\n        }\n        return first\n    } else if (second) {\n        return second\n    }\n    return \"\"\n}\n","/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise, SuppressedError, Symbol */\r\n\r\n\r\nvar __assign = function() {\r\n    __assign = Object.assign || function __assign(t) {\n        var arguments$1 = arguments;\n\r\n        for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n            s = arguments$1[i];\r\n            for (var p in s) { if (Object.prototype.hasOwnProperty.call(s, p)) { t[p] = s[p]; } }\r\n        }\r\n        return t;\r\n    };\r\n    return __assign.apply(this, arguments);\r\n};\r\n\r\nfunction __spreadArray(to, from, pack) {\r\n    if (pack || arguments.length === 2) { for (var i = 0, l = from.length, ar; i < l; i++) {\r\n        if (ar || !(i in from)) {\r\n            if (!ar) { ar = Array.prototype.slice.call(from, 0, i); }\r\n            ar[i] = from[i];\r\n        }\r\n    } }\r\n    return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\ntypeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\r\n    var e = new Error(message);\r\n    return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\r\n};\n\nvar Diff = /** @class */ (function () {\n    function Diff(options) {\n        if (options === void 0) { options = {}; }\n        var _this = this;\n        Object.entries(options).forEach(function (_a) {\n            var key = _a[0], value = _a[1];\n            return (_this[key] = value);\n        });\n    }\n    Diff.prototype.toString = function () {\n        return JSON.stringify(this);\n    };\n    Diff.prototype.setValue = function (aKey, aValue) {\n        this[aKey] = aValue;\n        return this;\n    };\n    return Diff;\n}());\nfunction checkElementType(element) {\n    var arguments$1 = arguments;\n\n    var elementTypeNames = [];\n    for (var _i = 1; _i < arguments.length; _i++) {\n        elementTypeNames[_i - 1] = arguments$1[_i];\n    }\n    if (typeof element === \"undefined\" || element === null) {\n        return false;\n    }\n    return elementTypeNames.some(function (elementTypeName) {\n        var _a, _b;\n        // We need to check if the specified type is defined\n        // because otherwise instanceof throws an exception.\n        return typeof ((_b = (_a = element === null || element === void 0 ? void 0 : element.ownerDocument) === null || _a === void 0 ? void 0 : _a.defaultView) === null || _b === void 0 ? void 0 : _b[elementTypeName]) ===\n            \"function\" &&\n            element instanceof\n                element.ownerDocument.defaultView[elementTypeName];\n    });\n}\n\nfunction objToNode(objNode, insideSvg, options) {\n    var node;\n    if (objNode.nodeName === \"#text\") {\n        node = options.document.createTextNode(objNode.data);\n    }\n    else if (objNode.nodeName === \"#comment\") {\n        node = options.document.createComment(objNode.data);\n    }\n    else {\n        if (insideSvg) {\n            node = options.document.createElementNS(\"http://www.w3.org/2000/svg\", objNode.nodeName);\n            if (objNode.nodeName === \"foreignObject\") {\n                insideSvg = false;\n            }\n        }\n        else if (objNode.nodeName.toLowerCase() === \"svg\") {\n            node = options.document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\n            insideSvg = true;\n        }\n        else {\n            node = options.document.createElement(objNode.nodeName);\n        }\n        if (objNode.attributes) {\n            Object.entries(objNode.attributes).forEach(function (_a) {\n                var key = _a[0], value = _a[1];\n                return node.setAttribute(key, value);\n            });\n        }\n        if (objNode.childNodes) {\n            node = node;\n            objNode.childNodes.forEach(function (childNode) {\n                return node.appendChild(objToNode(childNode, insideSvg, options));\n            });\n        }\n        if (options.valueDiffing) {\n            if (objNode.value &&\n                checkElementType(node, \"HTMLButtonElement\", \"HTMLDataElement\", \"HTMLInputElement\", \"HTMLLIElement\", \"HTMLMeterElement\", \"HTMLOptionElement\", \"HTMLProgressElement\", \"HTMLParamElement\")) {\n                node.value = objNode.value;\n            }\n            if (objNode.checked && checkElementType(node, \"HTMLInputElement\")) {\n                node.checked = objNode.checked;\n            }\n            if (objNode.selected &&\n                checkElementType(node, \"HTMLOptionElement\")) {\n                node.selected = objNode.selected;\n            }\n        }\n    }\n    return node;\n}\n\n// ===== Apply a diff =====\nvar getFromRoute = function (node, route) {\n    route = route.slice();\n    while (route.length > 0) {\n        var c = route.splice(0, 1)[0];\n        node = node.childNodes[c];\n    }\n    return node;\n};\nfunction applyDiff(tree, diff, options) {\n    var action = diff[options._const.action];\n    var route = diff[options._const.route];\n    var node;\n    if (![options._const.addElement, options._const.addTextElement].includes(action)) {\n        // For adding nodes, we calculate the route later on. It's different because it includes the position of the newly added item.\n        node = getFromRoute(tree, route);\n    }\n    var newNode;\n    var reference;\n    var nodeArray;\n    // pre-diff hook\n    var info = {\n        diff: diff,\n        node: node\n    };\n    if (options.preDiffApply(info)) {\n        return true;\n    }\n    switch (action) {\n        case options._const.addAttribute:\n            if (!node || !checkElementType(node, \"Element\")) {\n                return false;\n            }\n            node.setAttribute(diff[options._const.name], diff[options._const.value]);\n            break;\n        case options._const.modifyAttribute:\n            if (!node || !checkElementType(node, \"Element\")) {\n                return false;\n            }\n            node.setAttribute(diff[options._const.name], diff[options._const.newValue]);\n            if (checkElementType(node, \"HTMLInputElement\") &&\n                diff[options._const.name] === \"value\") {\n                node.value = diff[options._const.newValue];\n            }\n            break;\n        case options._const.removeAttribute:\n            if (!node || !checkElementType(node, \"Element\")) {\n                return false;\n            }\n            node.removeAttribute(diff[options._const.name]);\n            break;\n        case options._const.modifyTextElement:\n            if (!node || !checkElementType(node, \"Text\")) {\n                return false;\n            }\n            options.textDiff(node, node.data, diff[options._const.oldValue], diff[options._const.newValue]);\n            if (checkElementType(node.parentNode, \"HTMLTextAreaElement\")) {\n                node.parentNode.value = diff[options._const.newValue];\n            }\n            break;\n        case options._const.modifyValue:\n            if (!node || typeof node.value === \"undefined\") {\n                return false;\n            }\n            node.value = diff[options._const.newValue];\n            break;\n        case options._const.modifyComment:\n            if (!node || !checkElementType(node, \"Comment\")) {\n                return false;\n            }\n            options.textDiff(node, node.data, diff[options._const.oldValue], diff[options._const.newValue]);\n            break;\n        case options._const.modifyChecked:\n            if (!node || typeof node.checked === \"undefined\") {\n                return false;\n            }\n            node.checked = diff[options._const.newValue];\n            break;\n        case options._const.modifySelected:\n            if (!node || typeof node.selected === \"undefined\") {\n                return false;\n            }\n            node.selected = diff[options._const.newValue];\n            break;\n        case options._const.replaceElement: {\n            var insideSvg = diff[options._const.newValue].nodeName.toLowerCase() === \"svg\" ||\n                node.parentNode.namespaceURI === \"http://www.w3.org/2000/svg\";\n            node.parentNode.replaceChild(objToNode(diff[options._const.newValue], insideSvg, options), node);\n            break;\n        }\n        case options._const.relocateGroup:\n            nodeArray = __spreadArray([], new Array(diff[options._const.groupLength]), true).map(function () {\n                return node.removeChild(node.childNodes[diff[options._const.from]]);\n            });\n            nodeArray.forEach(function (childNode, index) {\n                if (index === 0) {\n                    reference =\n                        node.childNodes[diff[options._const.to]];\n                }\n                node.insertBefore(childNode, reference || null);\n            });\n            break;\n        case options._const.removeElement:\n            node.parentNode.removeChild(node);\n            break;\n        case options._const.addElement: {\n            var parentRoute = route.slice();\n            var c = parentRoute.splice(parentRoute.length - 1, 1)[0];\n            node = getFromRoute(tree, parentRoute);\n            if (!checkElementType(node, \"Element\")) {\n                return false;\n            }\n            node.insertBefore(objToNode(diff[options._const.element], node.namespaceURI === \"http://www.w3.org/2000/svg\", options), node.childNodes[c] || null);\n            break;\n        }\n        case options._const.removeTextElement: {\n            if (!node || node.nodeType !== 3) {\n                return false;\n            }\n            var parentNode = node.parentNode;\n            parentNode.removeChild(node);\n            if (checkElementType(parentNode, \"HTMLTextAreaElement\")) {\n                parentNode.value = \"\";\n            }\n            break;\n        }\n        case options._const.addTextElement: {\n            var parentRoute = route.slice();\n            var c = parentRoute.splice(parentRoute.length - 1, 1)[0];\n            newNode = options.document.createTextNode(diff[options._const.value]);\n            node = getFromRoute(tree, parentRoute);\n            if (!node.childNodes) {\n                return false;\n            }\n            node.insertBefore(newNode, node.childNodes[c] || null);\n            if (checkElementType(node.parentNode, \"HTMLTextAreaElement\")) {\n                node.parentNode.value = diff[options._const.value];\n            }\n            break;\n        }\n        default:\n            console.log(\"unknown action\");\n    }\n    // if a new node was created, we might be interested in its\n    // post diff hook\n    options.postDiffApply({\n        diff: info.diff,\n        node: info.node,\n        newNode: newNode\n    });\n    return true;\n}\nfunction applyDOM(tree, diffs, options) {\n    return diffs.every(function (diff) {\n        return applyDiff(tree, diff, options);\n    });\n}\n\n// ===== Undo a diff =====\nfunction swap(obj, p1, p2) {\n    var tmp = obj[p1];\n    obj[p1] = obj[p2];\n    obj[p2] = tmp;\n}\nfunction undoDiff(tree, diff, options) {\n    switch (diff[options._const.action]) {\n        case options._const.addAttribute:\n            diff[options._const.action] = options._const.removeAttribute;\n            applyDiff(tree, diff, options);\n            break;\n        case options._const.modifyAttribute:\n            swap(diff, options._const.oldValue, options._const.newValue);\n            applyDiff(tree, diff, options);\n            break;\n        case options._const.removeAttribute:\n            diff[options._const.action] = options._const.addAttribute;\n            applyDiff(tree, diff, options);\n            break;\n        case options._const.modifyTextElement:\n            swap(diff, options._const.oldValue, options._const.newValue);\n            applyDiff(tree, diff, options);\n            break;\n        case options._const.modifyValue:\n            swap(diff, options._const.oldValue, options._const.newValue);\n            applyDiff(tree, diff, options);\n            break;\n        case options._const.modifyComment:\n            swap(diff, options._const.oldValue, options._const.newValue);\n            applyDiff(tree, diff, options);\n            break;\n        case options._const.modifyChecked:\n            swap(diff, options._const.oldValue, options._const.newValue);\n            applyDiff(tree, diff, options);\n            break;\n        case options._const.modifySelected:\n            swap(diff, options._const.oldValue, options._const.newValue);\n            applyDiff(tree, diff, options);\n            break;\n        case options._const.replaceElement:\n            swap(diff, options._const.oldValue, options._const.newValue);\n            applyDiff(tree, diff, options);\n            break;\n        case options._const.relocateGroup:\n            swap(diff, options._const.from, options._const.to);\n            applyDiff(tree, diff, options);\n            break;\n        case options._const.removeElement:\n            diff[options._const.action] = options._const.addElement;\n            applyDiff(tree, diff, options);\n            break;\n        case options._const.addElement:\n            diff[options._const.action] = options._const.removeElement;\n            applyDiff(tree, diff, options);\n            break;\n        case options._const.removeTextElement:\n            diff[options._const.action] = options._const.addTextElement;\n            applyDiff(tree, diff, options);\n            break;\n        case options._const.addTextElement:\n            diff[options._const.action] = options._const.removeTextElement;\n            applyDiff(tree, diff, options);\n            break;\n        default:\n            console.log(\"unknown action\");\n    }\n}\nfunction undoDOM(tree, diffs, options) {\n    diffs = diffs.slice();\n    diffs.reverse();\n    diffs.forEach(function (diff) {\n        undoDiff(tree, diff, options);\n    });\n}\n\nvar elementDescriptors = function (el) {\n    var output = [];\n    output.push(el.nodeName);\n    if (el.nodeName !== \"#text\" && el.nodeName !== \"#comment\") {\n        el = el;\n        if (el.attributes) {\n            if (el.attributes[\"class\"]) {\n                output.push(\"\".concat(el.nodeName, \".\").concat(el.attributes[\"class\"].replace(/ /g, \".\")));\n            }\n            if (el.attributes.id) {\n                output.push(\"\".concat(el.nodeName, \"#\").concat(el.attributes.id));\n            }\n        }\n    }\n    return output;\n};\nvar findUniqueDescriptors = function (li) {\n    var uniqueDescriptors = {};\n    var duplicateDescriptors = {};\n    li.forEach(function (node) {\n        elementDescriptors(node).forEach(function (descriptor) {\n            var inUnique = descriptor in uniqueDescriptors;\n            var inDupes = descriptor in duplicateDescriptors;\n            if (!inUnique && !inDupes) {\n                uniqueDescriptors[descriptor] = true;\n            }\n            else if (inUnique) {\n                delete uniqueDescriptors[descriptor];\n                duplicateDescriptors[descriptor] = true;\n            }\n        });\n    });\n    return uniqueDescriptors;\n};\nvar uniqueInBoth = function (l1, l2) {\n    var l1Unique = findUniqueDescriptors(l1);\n    var l2Unique = findUniqueDescriptors(l2);\n    var inBoth = {};\n    Object.keys(l1Unique).forEach(function (key) {\n        if (l2Unique[key]) {\n            inBoth[key] = true;\n        }\n    });\n    return inBoth;\n};\nvar removeDone = function (tree) {\n    delete tree.outerDone;\n    delete tree.innerDone;\n    delete tree.valueDone;\n    if (tree.childNodes) {\n        return tree.childNodes.every(removeDone);\n    }\n    else {\n        return true;\n    }\n};\nvar cleanNode = function (diffNode) {\n    if (Object.prototype.hasOwnProperty.call(diffNode, \"data\")) {\n        var textNode = {\n            nodeName: diffNode.nodeName === \"#text\" ? \"#text\" : \"#comment\",\n            data: diffNode.data\n        };\n        return textNode;\n    }\n    else {\n        var elementNode = {\n            nodeName: diffNode.nodeName\n        };\n        diffNode = diffNode;\n        if (Object.prototype.hasOwnProperty.call(diffNode, \"attributes\")) {\n            elementNode.attributes = __assign({}, diffNode.attributes);\n        }\n        if (Object.prototype.hasOwnProperty.call(diffNode, \"checked\")) {\n            elementNode.checked = diffNode.checked;\n        }\n        if (Object.prototype.hasOwnProperty.call(diffNode, \"value\")) {\n            elementNode.value = diffNode.value;\n        }\n        if (Object.prototype.hasOwnProperty.call(diffNode, \"selected\")) {\n            elementNode.selected = diffNode.selected;\n        }\n        if (Object.prototype.hasOwnProperty.call(diffNode, \"childNodes\")) {\n            elementNode.childNodes = diffNode.childNodes.map(function (diffChildNode) {\n                return cleanNode(diffChildNode);\n            });\n        }\n        return elementNode;\n    }\n};\nvar isEqual = function (e1, e2) {\n    if (![\"nodeName\", \"value\", \"checked\", \"selected\", \"data\"].every(function (element) {\n        if (e1[element] !== e2[element]) {\n            return false;\n        }\n        return true;\n    })) {\n        return false;\n    }\n    if (Object.prototype.hasOwnProperty.call(e1, \"data\")) {\n        // Comment or Text\n        return true;\n    }\n    e1 = e1;\n    e2 = e2;\n    if (Boolean(e1.attributes) !== Boolean(e2.attributes)) {\n        return false;\n    }\n    if (Boolean(e1.childNodes) !== Boolean(e2.childNodes)) {\n        return false;\n    }\n    if (e1.attributes) {\n        var e1Attributes = Object.keys(e1.attributes);\n        var e2Attributes = Object.keys(e2.attributes);\n        if (e1Attributes.length !== e2Attributes.length) {\n            return false;\n        }\n        if (!e1Attributes.every(function (attribute) {\n            if (e1.attributes[attribute] !==\n                e2.attributes[attribute]) {\n                return false;\n            }\n            return true;\n        })) {\n            return false;\n        }\n    }\n    if (e1.childNodes) {\n        if (e1.childNodes.length !== e2.childNodes.length) {\n            return false;\n        }\n        if (!e1.childNodes.every(function (childNode, index) {\n            return isEqual(childNode, e2.childNodes[index]);\n        })) {\n            return false;\n        }\n    }\n    return true;\n};\nvar roughlyEqual = function (e1, e2, uniqueDescriptors, sameSiblings, preventRecursion) {\n    if (preventRecursion === void 0) { preventRecursion = false; }\n    if (!e1 || !e2) {\n        return false;\n    }\n    if (e1.nodeName !== e2.nodeName) {\n        return false;\n    }\n    if ([\"#text\", \"#comment\"].includes(e1.nodeName)) {\n        // Note that we initially don't care what the text content of a node is,\n        // the mere fact that it's the same tag and \"has text\" means it's roughly\n        // equal, and then we can find out the true text difference later.\n        return preventRecursion\n            ? true\n            : e1.data === e2.data;\n    }\n    e1 = e1;\n    e2 = e2;\n    if (e1.nodeName in uniqueDescriptors) {\n        return true;\n    }\n    if (e1.attributes && e2.attributes) {\n        if (e1.attributes.id) {\n            if (e1.attributes.id !== e2.attributes.id) {\n                return false;\n            }\n            else {\n                var idDescriptor = \"\".concat(e1.nodeName, \"#\").concat(e1.attributes.id);\n                if (idDescriptor in uniqueDescriptors) {\n                    return true;\n                }\n            }\n        }\n        if (e1.attributes[\"class\"] &&\n            e1.attributes[\"class\"] === e2.attributes[\"class\"]) {\n            var classDescriptor = \"\".concat(e1.nodeName, \".\").concat(e1.attributes[\"class\"].replace(/ /g, \".\"));\n            if (classDescriptor in uniqueDescriptors) {\n                return true;\n            }\n        }\n    }\n    if (sameSiblings) {\n        return true;\n    }\n    var nodeList1 = e1.childNodes ? e1.childNodes.slice().reverse() : [];\n    var nodeList2 = e2.childNodes ? e2.childNodes.slice().reverse() : [];\n    if (nodeList1.length !== nodeList2.length) {\n        return false;\n    }\n    if (preventRecursion) {\n        return nodeList1.every(function (element, index) {\n            return element.nodeName === nodeList2[index].nodeName;\n        });\n    }\n    else {\n        // note: we only allow one level of recursion at any depth. If 'preventRecursion'\n        // was not set, we must explicitly force it to true for child iterations.\n        var childUniqueDescriptors_1 = uniqueInBoth(nodeList1, nodeList2);\n        return nodeList1.every(function (element, index) {\n            return roughlyEqual(element, nodeList2[index], childUniqueDescriptors_1, true, true);\n        });\n    }\n};\n/**\n * based on https://en.wikibooks.org/wiki/Algorithm_implementation/Strings/Longest_common_substring#JavaScript\n */\nvar findCommonSubsets = function (c1, c2, marked1, marked2) {\n    var lcsSize = 0;\n    var index = [];\n    var c1Length = c1.length;\n    var c2Length = c2.length;\n    var // set up the matching table\n    matches = __spreadArray([], new Array(c1Length + 1), true).map(function () { return []; });\n    var uniqueDescriptors = uniqueInBoth(c1, c2);\n    var // If all of the elements are the same tag, id and class, then we can\n    // consider them roughly the same even if they have a different number of\n    // children. This will reduce removing and re-adding similar elements.\n    subsetsSame = c1Length === c2Length;\n    if (subsetsSame) {\n        c1.some(function (element, i) {\n            var c1Desc = elementDescriptors(element);\n            var c2Desc = elementDescriptors(c2[i]);\n            if (c1Desc.length !== c2Desc.length) {\n                subsetsSame = false;\n                return true;\n            }\n            c1Desc.some(function (description, i) {\n                if (description !== c2Desc[i]) {\n                    subsetsSame = false;\n                    return true;\n                }\n            });\n            if (!subsetsSame) {\n                return true;\n            }\n        });\n    }\n    // fill the matches with distance values\n    for (var c1Index = 0; c1Index < c1Length; c1Index++) {\n        var c1Element = c1[c1Index];\n        for (var c2Index = 0; c2Index < c2Length; c2Index++) {\n            var c2Element = c2[c2Index];\n            if (!marked1[c1Index] &&\n                !marked2[c2Index] &&\n                roughlyEqual(c1Element, c2Element, uniqueDescriptors, subsetsSame)) {\n                matches[c1Index + 1][c2Index + 1] = matches[c1Index][c2Index]\n                    ? matches[c1Index][c2Index] + 1\n                    : 1;\n                if (matches[c1Index + 1][c2Index + 1] >= lcsSize) {\n                    lcsSize = matches[c1Index + 1][c2Index + 1];\n                    index = [c1Index + 1, c2Index + 1];\n                }\n            }\n            else {\n                matches[c1Index + 1][c2Index + 1] = 0;\n            }\n        }\n    }\n    if (lcsSize === 0) {\n        return false;\n    }\n    return {\n        oldValue: index[0] - lcsSize,\n        newValue: index[1] - lcsSize,\n        length: lcsSize\n    };\n};\nvar makeBooleanArray = function (n, v) {\n    return __spreadArray([], new Array(n), true).map(function () { return v; });\n};\n/**\n * Generate arrays that indicate which node belongs to which subset,\n * or whether it's actually an orphan node, existing in only one\n * of the two trees, rather than somewhere in both.\n *\n * So if t1 = <img><canvas><br>, t2 = <canvas><br><img>.\n * The longest subset is \"<canvas><br>\" (length 2), so it will group 0.\n * The second longest is \"<img>\" (length 1), so it will be group 1.\n * gaps1 will therefore be [1,0,0] and gaps2 [0,0,1].\n *\n * If an element is not part of any group, it will stay being 'true', which\n * is the initial value. For example:\n * t1 = <img><p></p><br><canvas>, t2 = <b></b><br><canvas><img>\n *\n * The \"<p></p>\" and \"<b></b>\" do only show up in one of the two and will\n * therefore be marked by \"true\". The remaining parts are parts of the\n * groups 0 and 1:\n * gaps1 = [1, true, 0, 0], gaps2 = [true, 0, 0, 1]\n *\n */\nvar getGapInformation = function (t1, t2, stable) {\n    var gaps1 = t1.childNodes\n        ? makeBooleanArray(t1.childNodes.length, true)\n        : [];\n    var gaps2 = t2.childNodes\n        ? makeBooleanArray(t2.childNodes.length, true)\n        : [];\n    var group = 0;\n    // give elements from the same subset the same group number\n    stable.forEach(function (subset) {\n        var endOld = subset.oldValue + subset.length;\n        var endNew = subset.newValue + subset.length;\n        for (var j = subset.oldValue; j < endOld; j += 1) {\n            gaps1[j] = group;\n        }\n        for (var j = subset.newValue; j < endNew; j += 1) {\n            gaps2[j] = group;\n        }\n        group += 1;\n    });\n    return {\n        gaps1: gaps1,\n        gaps2: gaps2\n    };\n};\n/**\n * Find all matching subsets, based on immediate child differences only.\n */\nvar markBoth = function (marked1, marked2, subset, i) {\n    marked1[subset.oldValue + i] = true;\n    marked2[subset.newValue + i] = true;\n};\nvar markSubTrees = function (oldTree, newTree) {\n    // note: the child lists are views, and so update as we update old/newTree\n    var oldChildren = oldTree.childNodes ? oldTree.childNodes : [];\n    var newChildren = newTree.childNodes ? newTree.childNodes : [];\n    var marked1 = makeBooleanArray(oldChildren.length, false);\n    var marked2 = makeBooleanArray(newChildren.length, false);\n    var subsets = [];\n    var returnIndex = function () {\n        return arguments[1];\n    };\n    var foundAllSubsets = false;\n    var _loop_1 = function () {\n        var subset = findCommonSubsets(oldChildren, newChildren, marked1, marked2);\n        if (subset) {\n            subsets.push(subset);\n            var subsetArray = __spreadArray([], new Array(subset.length), true).map(returnIndex);\n            subsetArray.forEach(function (item) {\n                return markBoth(marked1, marked2, subset, item);\n            });\n        }\n        else {\n            foundAllSubsets = true;\n        }\n    };\n    while (!foundAllSubsets) {\n        _loop_1();\n    }\n    oldTree.subsets = subsets;\n    oldTree.subsetsAge = 100;\n    return subsets;\n};\nvar DiffTracker = /** @class */ (function () {\n    function DiffTracker() {\n        this.list = [];\n    }\n    DiffTracker.prototype.add = function (diffs) {\n        var _a;\n        (_a = this.list).push.apply(_a, diffs);\n    };\n    DiffTracker.prototype.forEach = function (fn) {\n        this.list.forEach(function (li) { return fn(li); });\n    };\n    return DiffTracker;\n}());\n\n// ===== Apply a virtual diff =====\nfunction getFromVirtualRoute(tree, route) {\n    var node = tree;\n    var parentNode;\n    var nodeIndex;\n    route = route.slice();\n    while (route.length > 0) {\n        nodeIndex = route.splice(0, 1)[0];\n        parentNode = node;\n        node = node.childNodes ? node.childNodes[nodeIndex] : undefined;\n    }\n    return {\n        node: node,\n        parentNode: parentNode,\n        nodeIndex: nodeIndex\n    };\n}\nfunction applyVirtualDiff(tree, diff, options) {\n    var _a;\n    var node, parentNode, nodeIndex;\n    if (![options._const.addElement, options._const.addTextElement].includes(diff[options._const.action])) {\n        // For adding nodes, we calculate the route later on. It's different because it includes the position of the newly added item.\n        var routeInfo = getFromVirtualRoute(tree, diff[options._const.route]);\n        node = routeInfo.node;\n        parentNode = routeInfo.parentNode;\n        nodeIndex = routeInfo.nodeIndex;\n    }\n    var newSubsets = [];\n    // pre-diff hook\n    var info = {\n        diff: diff,\n        node: node\n    };\n    if (options.preVirtualDiffApply(info)) {\n        return true;\n    }\n    var newNode;\n    var nodeArray;\n    var route;\n    switch (diff[options._const.action]) {\n        case options._const.addAttribute:\n            if (!node.attributes) {\n                node.attributes = {};\n            }\n            node.attributes[diff[options._const.name]] =\n                diff[options._const.value];\n            if (diff[options._const.name] === \"checked\") {\n                node.checked = true;\n            }\n            else if (diff[options._const.name] === \"selected\") {\n                node.selected = true;\n            }\n            else if (node.nodeName === \"INPUT\" &&\n                diff[options._const.name] === \"value\") {\n                node.value = diff[options._const.value];\n            }\n            break;\n        case options._const.modifyAttribute:\n            node.attributes[diff[options._const.name]] =\n                diff[options._const.newValue];\n            break;\n        case options._const.removeAttribute:\n            delete node.attributes[diff[options._const.name]];\n            if (Object.keys(node.attributes).length === 0) {\n                delete node.attributes;\n            }\n            if (diff[options._const.name] === \"checked\") {\n                node.checked = false;\n            }\n            else if (diff[options._const.name] === \"selected\") {\n                delete node.selected;\n            }\n            else if (node.nodeName === \"INPUT\" &&\n                diff[options._const.name] === \"value\") {\n                delete node.value;\n            }\n            break;\n        case options._const.modifyTextElement:\n            node.data = diff[options._const.newValue];\n            if (parentNode.nodeName === \"TEXTAREA\") {\n                parentNode.value = diff[options._const.newValue];\n            }\n            break;\n        case options._const.modifyValue:\n            node.value = diff[options._const.newValue];\n            break;\n        case options._const.modifyComment:\n            node.data = diff[options._const.newValue];\n            break;\n        case options._const.modifyChecked:\n            node.checked = diff[options._const.newValue];\n            break;\n        case options._const.modifySelected:\n            node.selected = diff[options._const.newValue];\n            break;\n        case options._const.replaceElement:\n            newNode = cleanNode(diff[options._const.newValue]);\n            parentNode.childNodes[nodeIndex] = newNode;\n            break;\n        case options._const.relocateGroup:\n            nodeArray = node.childNodes\n                .splice(diff[options._const.from], diff[options._const.groupLength])\n                .reverse();\n            nodeArray.forEach(function (movedNode) {\n                return node.childNodes.splice(diff[options._const.to], 0, movedNode);\n            });\n            if (node.subsets) {\n                node.subsets.forEach(function (map) {\n                    if (diff[options._const.from] < diff[options._const.to] &&\n                        map.oldValue <= diff[options._const.to] &&\n                        map.oldValue > diff[options._const.from]) {\n                        map.oldValue -= diff[options._const.groupLength];\n                        var splitLength = map.oldValue + map.length - diff[options._const.to];\n                        if (splitLength > 0) {\n                            // new insertion splits map.\n                            newSubsets.push({\n                                oldValue: diff[options._const.to] +\n                                    diff[options._const.groupLength],\n                                newValue: map.newValue + map.length - splitLength,\n                                length: splitLength\n                            });\n                            map.length -= splitLength;\n                        }\n                    }\n                    else if (diff[options._const.from] > diff[options._const.to] &&\n                        map.oldValue > diff[options._const.to] &&\n                        map.oldValue < diff[options._const.from]) {\n                        map.oldValue += diff[options._const.groupLength];\n                        var splitLength = map.oldValue + map.length - diff[options._const.to];\n                        if (splitLength > 0) {\n                            // new insertion splits map.\n                            newSubsets.push({\n                                oldValue: diff[options._const.to] +\n                                    diff[options._const.groupLength],\n                                newValue: map.newValue + map.length - splitLength,\n                                length: splitLength\n                            });\n                            map.length -= splitLength;\n                        }\n                    }\n                    else if (map.oldValue === diff[options._const.from]) {\n                        map.oldValue = diff[options._const.to];\n                    }\n                });\n            }\n            break;\n        case options._const.removeElement:\n            parentNode.childNodes.splice(nodeIndex, 1);\n            if (parentNode.subsets) {\n                parentNode.subsets.forEach(function (map) {\n                    if (map.oldValue > nodeIndex) {\n                        map.oldValue -= 1;\n                    }\n                    else if (map.oldValue === nodeIndex) {\n                        map[\"delete\"] = true;\n                    }\n                    else if (map.oldValue < nodeIndex &&\n                        map.oldValue + map.length > nodeIndex) {\n                        if (map.oldValue + map.length - 1 === nodeIndex) {\n                            map.length--;\n                        }\n                        else {\n                            newSubsets.push({\n                                newValue: map.newValue + nodeIndex - map.oldValue,\n                                oldValue: nodeIndex,\n                                length: map.length - nodeIndex + map.oldValue - 1\n                            });\n                            map.length = nodeIndex - map.oldValue;\n                        }\n                    }\n                });\n            }\n            node = parentNode;\n            break;\n        case options._const.addElement: {\n            route = diff[options._const.route].slice();\n            var c_1 = route.splice(route.length - 1, 1)[0];\n            node = (_a = getFromVirtualRoute(tree, route)) === null || _a === void 0 ? void 0 : _a.node;\n            newNode = cleanNode(diff[options._const.element]);\n            if (!node.childNodes) {\n                node.childNodes = [];\n            }\n            if (c_1 >= node.childNodes.length) {\n                node.childNodes.push(newNode);\n            }\n            else {\n                node.childNodes.splice(c_1, 0, newNode);\n            }\n            if (node.subsets) {\n                node.subsets.forEach(function (map) {\n                    if (map.oldValue >= c_1) {\n                        map.oldValue += 1;\n                    }\n                    else if (map.oldValue < c_1 &&\n                        map.oldValue + map.length > c_1) {\n                        var splitLength = map.oldValue + map.length - c_1;\n                        newSubsets.push({\n                            newValue: map.newValue + map.length - splitLength,\n                            oldValue: c_1 + 1,\n                            length: splitLength\n                        });\n                        map.length -= splitLength;\n                    }\n                });\n            }\n            break;\n        }\n        case options._const.removeTextElement:\n            parentNode.childNodes.splice(nodeIndex, 1);\n            if (parentNode.nodeName === \"TEXTAREA\") {\n                delete parentNode.value;\n            }\n            if (parentNode.subsets) {\n                parentNode.subsets.forEach(function (map) {\n                    if (map.oldValue > nodeIndex) {\n                        map.oldValue -= 1;\n                    }\n                    else if (map.oldValue === nodeIndex) {\n                        map[\"delete\"] = true;\n                    }\n                    else if (map.oldValue < nodeIndex &&\n                        map.oldValue + map.length > nodeIndex) {\n                        if (map.oldValue + map.length - 1 === nodeIndex) {\n                            map.length--;\n                        }\n                        else {\n                            newSubsets.push({\n                                newValue: map.newValue + nodeIndex - map.oldValue,\n                                oldValue: nodeIndex,\n                                length: map.length - nodeIndex + map.oldValue - 1\n                            });\n                            map.length = nodeIndex - map.oldValue;\n                        }\n                    }\n                });\n            }\n            node = parentNode;\n            break;\n        case options._const.addTextElement: {\n            route = diff[options._const.route].slice();\n            var c_2 = route.splice(route.length - 1, 1)[0];\n            newNode = {\n                nodeName: \"#text\",\n                data: diff[options._const.value]\n            };\n            node = getFromVirtualRoute(tree, route).node;\n            if (!node.childNodes) {\n                node.childNodes = [];\n            }\n            if (c_2 >= node.childNodes.length) {\n                node.childNodes.push(newNode);\n            }\n            else {\n                node.childNodes.splice(c_2, 0, newNode);\n            }\n            if (node.nodeName === \"TEXTAREA\") {\n                node.value = diff[options._const.newValue];\n            }\n            if (node.subsets) {\n                node.subsets.forEach(function (map) {\n                    if (map.oldValue >= c_2) {\n                        map.oldValue += 1;\n                    }\n                    if (map.oldValue < c_2 && map.oldValue + map.length > c_2) {\n                        var splitLength = map.oldValue + map.length - c_2;\n                        newSubsets.push({\n                            newValue: map.newValue + map.length - splitLength,\n                            oldValue: c_2 + 1,\n                            length: splitLength\n                        });\n                        map.length -= splitLength;\n                    }\n                });\n            }\n            break;\n        }\n        default:\n            console.log(\"unknown action\");\n    }\n    if (node.subsets) {\n        node.subsets = node.subsets.filter(function (map) { return !map[\"delete\"] && map.oldValue !== map.newValue; });\n        if (newSubsets.length) {\n            node.subsets = node.subsets.concat(newSubsets);\n        }\n    }\n    options.postVirtualDiffApply({\n        node: info.node,\n        diff: info.diff,\n        newNode: newNode\n    });\n    return;\n}\nfunction applyVirtual(tree, diffs, options) {\n    diffs.forEach(function (diff) {\n        applyVirtualDiff(tree, diff, options);\n    });\n    return true;\n}\n\nfunction nodeToObj(aNode, options) {\n    if (options === void 0) { options = { valueDiffing: true }; }\n    var objNode = {\n        nodeName: aNode.nodeName\n    };\n    if (checkElementType(aNode, \"Text\", \"Comment\")) {\n        objNode.data = aNode.data;\n    }\n    else {\n        if (aNode.attributes && aNode.attributes.length > 0) {\n            objNode.attributes = {};\n            var nodeArray = Array.prototype.slice.call(aNode.attributes);\n            nodeArray.forEach(function (attribute) {\n                return (objNode.attributes[attribute.name] = attribute.value);\n            });\n        }\n        if (aNode.childNodes && aNode.childNodes.length > 0) {\n            objNode.childNodes = [];\n            var nodeArray = Array.prototype.slice.call(aNode.childNodes);\n            nodeArray.forEach(function (childNode) {\n                return objNode.childNodes.push(nodeToObj(childNode, options));\n            });\n        }\n        if (options.valueDiffing) {\n            if (checkElementType(aNode, \"HTMLTextAreaElement\")) {\n                objNode.value = aNode.value;\n            }\n            if (checkElementType(aNode, \"HTMLInputElement\") &&\n                [\"radio\", \"checkbox\"].includes(aNode.type.toLowerCase()) &&\n                aNode.checked !== undefined) {\n                objNode.checked = aNode.checked;\n            }\n            else if (checkElementType(aNode, \"HTMLButtonElement\", \"HTMLDataElement\", \"HTMLInputElement\", \"HTMLLIElement\", \"HTMLMeterElement\", \"HTMLOptionElement\", \"HTMLProgressElement\", \"HTMLParamElement\")) {\n                objNode.value = aNode.value;\n            }\n            if (checkElementType(aNode, \"HTMLOptionElement\")) {\n                objNode.selected = aNode.selected;\n            }\n        }\n    }\n    return objNode;\n}\n\n// from html-parse-stringify (MIT)\nvar tagRE = /<\\s*\\/*[a-zA-Z:_][a-zA-Z0-9:_\\-.]*\\s*(?:\"[^\"]*\"['\"]*|'[^']*'['\"]*|[^'\"/>])*\\/*\\s*>|<!--(?:.|\\n|\\r)*?-->/g;\nvar attrRE = /\\s([^'\"/\\s><]+?)[\\s/>]|([^\\s=]+)=\\s?(\".*?\"|'.*?')/g;\nfunction unescape(string) {\n    return string\n        .replace(/&lt;/g, \"<\")\n        .replace(/&gt;/g, \">\")\n        .replace(/&amp;/g, \"&\");\n}\n// create optimized lookup object for\n// void elements as listed here:\n// https://www.w3.org/html/wg/drafts/html/master/syntax.html#void-elements\nvar lookup = {\n    area: true,\n    base: true,\n    br: true,\n    col: true,\n    embed: true,\n    hr: true,\n    img: true,\n    input: true,\n    keygen: true,\n    link: true,\n    menuItem: true,\n    meta: true,\n    param: true,\n    source: true,\n    track: true,\n    wbr: true\n};\nvar parseTag = function (tag, caseSensitive) {\n    var res = {\n        nodeName: \"\",\n        attributes: {}\n    };\n    var voidElement = false;\n    var type = \"tag\";\n    var tagMatch = tag.match(/<\\/?([^\\s]+?)[/\\s>]/);\n    if (tagMatch) {\n        res.nodeName =\n            caseSensitive || tagMatch[1] === \"svg\"\n                ? tagMatch[1]\n                : tagMatch[1].toUpperCase();\n        if (lookup[tagMatch[1]] || tag.charAt(tag.length - 2) === \"/\") {\n            voidElement = true;\n        }\n        // handle comment tag\n        if (res.nodeName.startsWith(\"!--\")) {\n            var endIndex = tag.indexOf(\"-->\");\n            return {\n                type: \"comment\",\n                node: {\n                    nodeName: \"#comment\",\n                    data: endIndex !== -1 ? tag.slice(4, endIndex) : \"\"\n                },\n                voidElement: voidElement\n            };\n        }\n    }\n    var reg = new RegExp(attrRE);\n    var result = null;\n    var done = false;\n    while (!done) {\n        result = reg.exec(tag);\n        if (result === null) {\n            done = true;\n        }\n        else if (result[0].trim()) {\n            if (result[1]) {\n                var attr = result[1].trim();\n                var arr = [attr, \"\"];\n                if (attr.indexOf(\"=\") > -1)\n                    { arr = attr.split(\"=\"); }\n                res.attributes[arr[0]] = arr[1];\n                reg.lastIndex--;\n            }\n            else if (result[2])\n                { res.attributes[result[2]] = result[3]\n                    .trim()\n                    .substring(1, result[3].length - 1); }\n        }\n    }\n    return {\n        type: type,\n        node: res,\n        voidElement: voidElement\n    };\n};\nvar stringToObj = function (html, options) {\n    if (options === void 0) { options = {\n        valueDiffing: true,\n        caseSensitive: false\n    }; }\n    var result = [];\n    var current;\n    var level = -1;\n    var arr = [];\n    var inComponent = false, insideSvg = false;\n    // handle text at top level\n    if (html.indexOf(\"<\") !== 0) {\n        var end = html.indexOf(\"<\");\n        result.push({\n            nodeName: \"#text\",\n            data: end === -1 ? html : html.substring(0, end)\n        });\n    }\n    html.replace(tagRE, function (tag, index) {\n        var isOpen = tag.charAt(1) !== \"/\";\n        var isComment = tag.startsWith(\"<!--\");\n        var start = index + tag.length;\n        var nextChar = html.charAt(start);\n        if (isComment) {\n            var comment = parseTag(tag, options.caseSensitive).node;\n            // if we're at root, push new base node\n            if (level < 0) {\n                result.push(comment);\n                return \"\";\n            }\n            var parent_1 = arr[level];\n            if (parent_1 && comment.nodeName) {\n                if (!parent_1.node.childNodes) {\n                    parent_1.node.childNodes = [];\n                }\n                parent_1.node.childNodes.push(comment);\n            }\n            return \"\";\n        }\n        if (isOpen) {\n            current = parseTag(tag, options.caseSensitive || insideSvg);\n            if (current.node.nodeName === \"svg\") {\n                insideSvg = true;\n            }\n            level++;\n            if (!current.voidElement &&\n                !inComponent &&\n                nextChar &&\n                nextChar !== \"<\") {\n                if (!current.node.childNodes) {\n                    current.node.childNodes = [];\n                }\n                var data = unescape(html.slice(start, html.indexOf(\"<\", start)));\n                current.node.childNodes.push({\n                    nodeName: \"#text\",\n                    data: data\n                });\n                if (options.valueDiffing &&\n                    current.node.nodeName === \"TEXTAREA\") {\n                    current.node.value = data;\n                }\n            }\n            // if we're at root, push new base node\n            if (level === 0 && current.node.nodeName) {\n                result.push(current.node);\n            }\n            var parent_2 = arr[level - 1];\n            if (parent_2 && current.node.nodeName) {\n                if (!parent_2.node.childNodes) {\n                    parent_2.node.childNodes = [];\n                }\n                parent_2.node.childNodes.push(current.node);\n            }\n            arr[level] = current;\n        }\n        if (!isOpen || current.voidElement) {\n            if (level > -1 &&\n                (current.voidElement ||\n                    (options.caseSensitive &&\n                        current.node.nodeName === tag.slice(2, -1)) ||\n                    (!options.caseSensitive &&\n                        current.node.nodeName.toUpperCase() ===\n                            tag.slice(2, -1).toUpperCase()))) {\n                level--;\n                // move current up a level to match the end tag\n                if (level > -1) {\n                    if (current.node.nodeName === \"svg\") {\n                        insideSvg = false;\n                    }\n                    current = arr[level];\n                }\n            }\n            if (nextChar !== \"<\" && nextChar) {\n                // trailing text node\n                // if we're at the root, push a base text node. otherwise add as\n                // a child to the current node.\n                var childNodes = level === -1 ? result : arr[level].node.childNodes || [];\n                // calculate correct end of the data slice in case there's\n                // no tag after the text node.\n                var end = html.indexOf(\"<\", start);\n                var data = unescape(html.slice(start, end === -1 ? undefined : end));\n                childNodes.push({\n                    nodeName: \"#text\",\n                    data: data\n                });\n            }\n        }\n        return \"\";\n    });\n    return result[0];\n};\n\n// ===== Create a diff =====\nvar DiffFinder = /** @class */ (function () {\n    function DiffFinder(t1Node, t2Node, options) {\n        this.options = options;\n        this.t1 = (typeof Element !== \"undefined\" &&\n            checkElementType(t1Node, \"Element\")\n            ? nodeToObj(t1Node, this.options)\n            : typeof t1Node === \"string\"\n                ? stringToObj(t1Node, this.options)\n                : JSON.parse(JSON.stringify(t1Node)));\n        this.t2 = (typeof Element !== \"undefined\" &&\n            checkElementType(t2Node, \"Element\")\n            ? nodeToObj(t2Node, this.options)\n            : typeof t2Node === \"string\"\n                ? stringToObj(t2Node, this.options)\n                : JSON.parse(JSON.stringify(t2Node)));\n        this.diffcount = 0;\n        this.foundAll = false;\n        if (this.debug) {\n            this.t1Orig =\n                typeof Element !== \"undefined\" &&\n                    checkElementType(t1Node, \"Element\")\n                    ? nodeToObj(t1Node, this.options)\n                    : typeof t1Node === \"string\"\n                        ? stringToObj(t1Node, this.options)\n                        : JSON.parse(JSON.stringify(t1Node));\n            this.t2Orig =\n                typeof Element !== \"undefined\" &&\n                    checkElementType(t2Node, \"Element\")\n                    ? nodeToObj(t2Node, this.options)\n                    : typeof t2Node === \"string\"\n                        ? stringToObj(t2Node, this.options)\n                        : JSON.parse(JSON.stringify(t2Node));\n        }\n        this.tracker = new DiffTracker();\n    }\n    DiffFinder.prototype.init = function () {\n        return this.findDiffs(this.t1, this.t2);\n    };\n    DiffFinder.prototype.findDiffs = function (t1, t2) {\n        var diffs;\n        do {\n            if (this.options.debug) {\n                this.diffcount += 1;\n                if (this.diffcount > this.options.diffcap) {\n                    throw new Error(\"surpassed diffcap:\".concat(JSON.stringify(this.t1Orig), \" -> \").concat(JSON.stringify(this.t2Orig)));\n                }\n            }\n            diffs = this.findNextDiff(t1, t2, []);\n            if (diffs.length === 0) {\n                // Last check if the elements really are the same now.\n                // If not, remove all info about being done and start over.\n                // Sometimes a node can be marked as done, but the creation of subsequent diffs means that it has to be changed again.\n                if (!isEqual(t1, t2)) {\n                    if (this.foundAll) {\n                        console.error(\"Could not find remaining diffs!\");\n                    }\n                    else {\n                        this.foundAll = true;\n                        removeDone(t1);\n                        diffs = this.findNextDiff(t1, t2, []);\n                    }\n                }\n            }\n            if (diffs.length > 0) {\n                this.foundAll = false;\n                this.tracker.add(diffs);\n                applyVirtual(t1, diffs, this.options);\n            }\n        } while (diffs.length > 0);\n        return this.tracker.list;\n    };\n    DiffFinder.prototype.findNextDiff = function (t1, t2, route) {\n        var diffs;\n        var fdiffs;\n        if (this.options.maxDepth && route.length > this.options.maxDepth) {\n            return [];\n        }\n        // outer differences?\n        if (!t1.outerDone) {\n            diffs = this.findOuterDiff(t1, t2, route);\n            if (this.options.filterOuterDiff) {\n                fdiffs = this.options.filterOuterDiff(t1, t2, diffs);\n                if (fdiffs)\n                    { diffs = fdiffs; }\n            }\n            if (diffs.length > 0) {\n                t1.outerDone = true;\n                return diffs;\n            }\n            else {\n                t1.outerDone = true;\n            }\n        }\n        if (Object.prototype.hasOwnProperty.call(t1, \"data\")) {\n            // Comment or Text\n            return [];\n        }\n        t1 = t1;\n        t2 = t2;\n        // inner differences?\n        if (!t1.innerDone) {\n            diffs = this.findInnerDiff(t1, t2, route);\n            if (diffs.length > 0) {\n                return diffs;\n            }\n            else {\n                t1.innerDone = true;\n            }\n        }\n        if (this.options.valueDiffing && !t1.valueDone) {\n            // value differences?\n            diffs = this.findValueDiff(t1, t2, route);\n            if (diffs.length > 0) {\n                t1.valueDone = true;\n                return diffs;\n            }\n            else {\n                t1.valueDone = true;\n            }\n        }\n        // no differences\n        return [];\n    };\n    DiffFinder.prototype.findOuterDiff = function (t1, t2, route) {\n        var diffs = [];\n        var attr;\n        var attr1;\n        var attr2;\n        var attrLength;\n        var pos;\n        var i;\n        if (t1.nodeName !== t2.nodeName) {\n            if (!route.length) {\n                throw new Error(\"Top level nodes have to be of the same kind.\");\n            }\n            return [\n                new Diff()\n                    .setValue(this.options._const.action, this.options._const.replaceElement)\n                    .setValue(this.options._const.oldValue, cleanNode(t1))\n                    .setValue(this.options._const.newValue, cleanNode(t2))\n                    .setValue(this.options._const.route, route) ];\n        }\n        if (route.length &&\n            this.options.diffcap <\n                Math.abs((t1.childNodes || []).length - (t2.childNodes || []).length)) {\n            return [\n                new Diff()\n                    .setValue(this.options._const.action, this.options._const.replaceElement)\n                    .setValue(this.options._const.oldValue, cleanNode(t1))\n                    .setValue(this.options._const.newValue, cleanNode(t2))\n                    .setValue(this.options._const.route, route) ];\n        }\n        if (Object.prototype.hasOwnProperty.call(t1, \"data\") &&\n            t1.data !== t2.data) {\n            // Comment or text node.\n            if (t1.nodeName === \"#text\") {\n                return [\n                    new Diff()\n                        .setValue(this.options._const.action, this.options._const.modifyTextElement)\n                        .setValue(this.options._const.route, route)\n                        .setValue(this.options._const.oldValue, t1.data)\n                        .setValue(this.options._const.newValue, t2.data) ];\n            }\n            else {\n                return [\n                    new Diff()\n                        .setValue(this.options._const.action, this.options._const.modifyComment)\n                        .setValue(this.options._const.route, route)\n                        .setValue(this.options._const.oldValue, t1.data)\n                        .setValue(this.options._const.newValue, t2.data) ];\n            }\n        }\n        t1 = t1;\n        t2 = t2;\n        attr1 = t1.attributes ? Object.keys(t1.attributes).sort() : [];\n        attr2 = t2.attributes ? Object.keys(t2.attributes).sort() : [];\n        attrLength = attr1.length;\n        for (i = 0; i < attrLength; i++) {\n            attr = attr1[i];\n            pos = attr2.indexOf(attr);\n            if (pos === -1) {\n                diffs.push(new Diff()\n                    .setValue(this.options._const.action, this.options._const.removeAttribute)\n                    .setValue(this.options._const.route, route)\n                    .setValue(this.options._const.name, attr)\n                    .setValue(this.options._const.value, t1.attributes[attr]));\n            }\n            else {\n                attr2.splice(pos, 1);\n                if (t1.attributes[attr] !== t2.attributes[attr]) {\n                    diffs.push(new Diff()\n                        .setValue(this.options._const.action, this.options._const.modifyAttribute)\n                        .setValue(this.options._const.route, route)\n                        .setValue(this.options._const.name, attr)\n                        .setValue(this.options._const.oldValue, t1.attributes[attr])\n                        .setValue(this.options._const.newValue, t2.attributes[attr]));\n                }\n            }\n        }\n        attrLength = attr2.length;\n        for (i = 0; i < attrLength; i++) {\n            attr = attr2[i];\n            diffs.push(new Diff()\n                .setValue(this.options._const.action, this.options._const.addAttribute)\n                .setValue(this.options._const.route, route)\n                .setValue(this.options._const.name, attr)\n                .setValue(this.options._const.value, t2.attributes[attr]));\n        }\n        return diffs;\n    };\n    DiffFinder.prototype.findInnerDiff = function (t1, t2, route) {\n        var t1ChildNodes = t1.childNodes ? t1.childNodes.slice() : [];\n        var t2ChildNodes = t2.childNodes ? t2.childNodes.slice() : [];\n        var last = Math.max(t1ChildNodes.length, t2ChildNodes.length);\n        var childNodesLengthDifference = Math.abs(t1ChildNodes.length - t2ChildNodes.length);\n        var diffs = [];\n        var index = 0;\n        if (!this.options.maxChildCount || last < this.options.maxChildCount) {\n            var cachedSubtrees = Boolean(t1.subsets && t1.subsetsAge--);\n            var subtrees = cachedSubtrees\n                ? t1.subsets\n                : t1.childNodes && t2.childNodes\n                    ? markSubTrees(t1, t2)\n                    : [];\n            if (subtrees.length > 0) {\n                /* One or more groups have been identified among the childnodes of t1\n                 * and t2.\n                 */\n                diffs = this.attemptGroupRelocation(t1, t2, subtrees, route, cachedSubtrees);\n                if (diffs.length > 0) {\n                    return diffs;\n                }\n            }\n        }\n        /* 0 or 1 groups of similar child nodes have been found\n         * for t1 and t2. 1 If there is 1, it could be a sign that the\n         * contents are the same. When the number of groups is below 2,\n         * t1 and t2 are made to have the same length and each of the\n         * pairs of child nodes are diffed.\n         */\n        for (var i = 0; i < last; i += 1) {\n            var e1 = t1ChildNodes[i];\n            var e2 = t2ChildNodes[i];\n            if (childNodesLengthDifference) {\n                /* t1 and t2 have different amounts of childNodes. Add\n                 * and remove as necessary to obtain the same length */\n                if (e1 && !e2) {\n                    if (e1.nodeName === \"#text\") {\n                        diffs.push(new Diff()\n                            .setValue(this.options._const.action, this.options._const.removeTextElement)\n                            .setValue(this.options._const.route, route.concat(index))\n                            .setValue(this.options._const.value, e1.data));\n                        index -= 1;\n                    }\n                    else {\n                        diffs.push(new Diff()\n                            .setValue(this.options._const.action, this.options._const.removeElement)\n                            .setValue(this.options._const.route, route.concat(index))\n                            .setValue(this.options._const.element, cleanNode(e1)));\n                        index -= 1;\n                    }\n                }\n                else if (e2 && !e1) {\n                    if (e2.nodeName === \"#text\") {\n                        diffs.push(new Diff()\n                            .setValue(this.options._const.action, this.options._const.addTextElement)\n                            .setValue(this.options._const.route, route.concat(index))\n                            .setValue(this.options._const.value, e2.data));\n                    }\n                    else {\n                        diffs.push(new Diff()\n                            .setValue(this.options._const.action, this.options._const.addElement)\n                            .setValue(this.options._const.route, route.concat(index))\n                            .setValue(this.options._const.element, cleanNode(e2)));\n                    }\n                }\n            }\n            /* We are now guaranteed that childNodes e1 and e2 exist,\n             * and that they can be diffed.\n             */\n            /* Diffs in child nodes should not affect the parent node,\n             * so we let these diffs be submitted together with other\n             * diffs.\n             */\n            if (e1 && e2) {\n                if (!this.options.maxChildCount ||\n                    last < this.options.maxChildCount) {\n                    diffs = diffs.concat(this.findNextDiff(e1, e2, route.concat(index)));\n                }\n                else if (!isEqual(e1, e2)) {\n                    if (t1ChildNodes.length > t2ChildNodes.length) {\n                        if (e1.nodeName === \"#text\") {\n                            diffs.push(new Diff()\n                                .setValue(this.options._const.action, this.options._const.removeTextElement)\n                                .setValue(this.options._const.route, route.concat(index))\n                                .setValue(this.options._const.value, e1.data));\n                        }\n                        else {\n                            diffs.push(new Diff()\n                                .setValue(this.options._const.action, this.options._const.removeElement)\n                                .setValue(this.options._const.element, cleanNode(e1))\n                                .setValue(this.options._const.route, route.concat(index)));\n                        }\n                        t1ChildNodes.splice(i, 1);\n                        i -= 1;\n                        index -= 1;\n                        childNodesLengthDifference -= 1;\n                    }\n                    else if (t1ChildNodes.length < t2ChildNodes.length) {\n                        diffs = diffs.concat([\n                            new Diff()\n                                .setValue(this.options._const.action, this.options._const.addElement)\n                                .setValue(this.options._const.element, cleanNode(e2))\n                                .setValue(this.options._const.route, route.concat(index)) ]);\n                        t1ChildNodes.splice(i, 0, cleanNode(e2));\n                        childNodesLengthDifference -= 1;\n                    }\n                    else {\n                        diffs = diffs.concat([\n                            new Diff()\n                                .setValue(this.options._const.action, this.options._const.replaceElement)\n                                .setValue(this.options._const.oldValue, cleanNode(e1))\n                                .setValue(this.options._const.newValue, cleanNode(e2))\n                                .setValue(this.options._const.route, route.concat(index)) ]);\n                    }\n                }\n            }\n            index += 1;\n        }\n        t1.innerDone = true;\n        return diffs;\n    };\n    DiffFinder.prototype.attemptGroupRelocation = function (t1, t2, subtrees, route, cachedSubtrees) {\n        /* Either t1.childNodes and t2.childNodes have the same length, or\n         * there are at least two groups of similar elements can be found.\n         * attempts are made at equalizing t1 with t2. First all initial\n         * elements with no group affiliation (gaps=true) are removed (if\n         * only in t1) or added (if only in t2). Then the creation of a group\n         * relocation diff is attempted.\n         */\n        var gapInformation = getGapInformation(t1, t2, subtrees);\n        var gaps1 = gapInformation.gaps1;\n        var gaps2 = gapInformation.gaps2;\n        var t1ChildNodes = t1.childNodes.slice();\n        var t2ChildNodes = t2.childNodes.slice();\n        var shortest = Math.min(gaps1.length, gaps2.length);\n        var destinationDifferent;\n        var toGroup;\n        var group;\n        var node;\n        var similarNode;\n        var diffs = [];\n        for (var index2 = 0, index1 = 0; index2 < shortest; index1 += 1, index2 += 1) {\n            if (cachedSubtrees &&\n                (gaps1[index2] === true || gaps2[index2] === true)) ;\n            else if (gaps1[index1] === true) {\n                node = t1ChildNodes[index1];\n                if (node.nodeName === \"#text\") {\n                    if (t2ChildNodes[index2].nodeName === \"#text\") {\n                        if (node.data !==\n                            t2ChildNodes[index2].data) {\n                            // Check whether a text node with the same value follows later on.\n                            var testI = index1;\n                            while (t1ChildNodes.length > testI + 1 &&\n                                t1ChildNodes[testI + 1].nodeName === \"#text\") {\n                                testI += 1;\n                                if (t2ChildNodes[index2]\n                                    .data ===\n                                    t1ChildNodes[testI]\n                                        .data) {\n                                    similarNode = true;\n                                    break;\n                                }\n                            }\n                            if (!similarNode) {\n                                diffs.push(new Diff()\n                                    .setValue(this.options._const.action, this.options._const\n                                    .modifyTextElement)\n                                    .setValue(this.options._const.route, route.concat(index1))\n                                    .setValue(this.options._const.oldValue, node.data)\n                                    .setValue(this.options._const.newValue, t2ChildNodes[index2].data));\n                            }\n                        }\n                    }\n                    else {\n                        diffs.push(new Diff()\n                            .setValue(this.options._const.action, this.options._const.removeTextElement)\n                            .setValue(this.options._const.route, route.concat(index1))\n                            .setValue(this.options._const.value, node.data));\n                        gaps1.splice(index1, 1);\n                        t1ChildNodes.splice(index1, 1);\n                        shortest = Math.min(gaps1.length, gaps2.length);\n                        index1 -= 1;\n                        index2 -= 1;\n                    }\n                }\n                else if (gaps2[index2] === true) {\n                    // both gaps1[index1] and gaps2[index2]  are true.\n                    // We replace one element with another.\n                    diffs.push(new Diff()\n                        .setValue(this.options._const.action, this.options._const.replaceElement)\n                        .setValue(this.options._const.oldValue, cleanNode(node))\n                        .setValue(this.options._const.newValue, cleanNode(t2ChildNodes[index2]))\n                        .setValue(this.options._const.route, route.concat(index1)));\n                    // t1ChildNodes at position index1 is not up-to-date, but that does not matter as\n                    // index1 will increase +1\n                }\n                else {\n                    diffs.push(new Diff()\n                        .setValue(this.options._const.action, this.options._const.removeElement)\n                        .setValue(this.options._const.route, route.concat(index1))\n                        .setValue(this.options._const.element, cleanNode(node)));\n                    gaps1.splice(index1, 1);\n                    t1ChildNodes.splice(index1, 1);\n                    shortest = Math.min(gaps1.length, gaps2.length);\n                    index1 -= 1;\n                    index2 -= 1;\n                }\n            }\n            else if (gaps2[index2] === true) {\n                node = t2ChildNodes[index2];\n                if (node.nodeName === \"#text\") {\n                    diffs.push(new Diff()\n                        .setValue(this.options._const.action, this.options._const.addTextElement)\n                        .setValue(this.options._const.route, route.concat(index1))\n                        .setValue(this.options._const.value, node.data));\n                    gaps1.splice(index1, 0, true);\n                    t1ChildNodes.splice(index1, 0, {\n                        nodeName: \"#text\",\n                        data: node.data\n                    });\n                    shortest = Math.min(gaps1.length, gaps2.length);\n                    //index1 += 1\n                }\n                else {\n                    diffs.push(new Diff()\n                        .setValue(this.options._const.action, this.options._const.addElement)\n                        .setValue(this.options._const.route, route.concat(index1))\n                        .setValue(this.options._const.element, cleanNode(node)));\n                    gaps1.splice(index1, 0, true);\n                    t1ChildNodes.splice(index1, 0, cleanNode(node));\n                    shortest = Math.min(gaps1.length, gaps2.length);\n                    //index1 += 1\n                }\n            }\n            else if (gaps1[index1] !== gaps2[index2]) {\n                if (diffs.length > 0) {\n                    return diffs;\n                }\n                // group relocation\n                group = subtrees[gaps1[index1]];\n                toGroup = Math.min(group.newValue, t1ChildNodes.length - group.length);\n                if (toGroup !== group.oldValue) {\n                    // Check whether destination nodes are different than originating ones.\n                    destinationDifferent = false;\n                    for (var j = 0; j < group.length; j += 1) {\n                        if (!roughlyEqual(t1ChildNodes[toGroup + j], t1ChildNodes[group.oldValue + j], {}, false, true)) {\n                            destinationDifferent = true;\n                        }\n                    }\n                    if (destinationDifferent) {\n                        return [\n                            new Diff()\n                                .setValue(this.options._const.action, this.options._const.relocateGroup)\n                                .setValue(this.options._const.groupLength, group.length)\n                                .setValue(this.options._const.from, group.oldValue)\n                                .setValue(this.options._const.to, toGroup)\n                                .setValue(this.options._const.route, route) ];\n                    }\n                }\n            }\n        }\n        return diffs;\n    };\n    DiffFinder.prototype.findValueDiff = function (t1, t2, route) {\n        // Differences of value. Only useful if the value/selection/checked value\n        // differs from what is represented in the DOM. For example in the case\n        // of filled out forms, etc.\n        var diffs = [];\n        if (t1.selected !== t2.selected) {\n            diffs.push(new Diff()\n                .setValue(this.options._const.action, this.options._const.modifySelected)\n                .setValue(this.options._const.oldValue, t1.selected)\n                .setValue(this.options._const.newValue, t2.selected)\n                .setValue(this.options._const.route, route));\n        }\n        if ((t1.value || t2.value) &&\n            t1.value !== t2.value &&\n            t1.nodeName !== \"OPTION\") {\n            diffs.push(new Diff()\n                .setValue(this.options._const.action, this.options._const.modifyValue)\n                .setValue(this.options._const.oldValue, t1.value || \"\")\n                .setValue(this.options._const.newValue, t2.value || \"\")\n                .setValue(this.options._const.route, route));\n        }\n        if (t1.checked !== t2.checked) {\n            diffs.push(new Diff()\n                .setValue(this.options._const.action, this.options._const.modifyChecked)\n                .setValue(this.options._const.oldValue, t1.checked)\n                .setValue(this.options._const.newValue, t2.checked)\n                .setValue(this.options._const.route, route));\n        }\n        return diffs;\n    };\n    return DiffFinder;\n}());\n\nvar DEFAULT_OPTIONS = {\n    debug: false,\n    diffcap: 10,\n    maxDepth: false,\n    maxChildCount: 50,\n    valueDiffing: true,\n    // syntax: textDiff: function (node, currentValue, expectedValue, newValue)\n    textDiff: function (node, currentValue, expectedValue, newValue) {\n        node.data = newValue;\n        return;\n    },\n    // empty functions were benchmarked as running faster than both\n    // `f && f()` and `if (f) { f(); }`\n    preVirtualDiffApply: function () { },\n    postVirtualDiffApply: function () { },\n    preDiffApply: function () { },\n    postDiffApply: function () { },\n    filterOuterDiff: null,\n    compress: false,\n    _const: false,\n    document: typeof window !== \"undefined\" && window.document\n        ? window.document\n        : false,\n    components: []\n};\nvar DiffDOM = /** @class */ (function () {\n    function DiffDOM(options) {\n        if (options === void 0) { options = {}; }\n        // IE11 doesn't have Object.assign and buble doesn't translate object spreaders\n        // by default, so this is the safest way of doing it currently.\n        Object.entries(DEFAULT_OPTIONS).forEach(function (_a) {\n            var key = _a[0], value = _a[1];\n            if (!Object.prototype.hasOwnProperty.call(options, key)) {\n                options[key] = value;\n            }\n        });\n        if (!options._const) {\n            var varNames = [\n                \"addAttribute\",\n                \"modifyAttribute\",\n                \"removeAttribute\",\n                \"modifyTextElement\",\n                \"relocateGroup\",\n                \"removeElement\",\n                \"addElement\",\n                \"removeTextElement\",\n                \"addTextElement\",\n                \"replaceElement\",\n                \"modifyValue\",\n                \"modifyChecked\",\n                \"modifySelected\",\n                \"modifyComment\",\n                \"action\",\n                \"route\",\n                \"oldValue\",\n                \"newValue\",\n                \"element\",\n                \"group\",\n                \"groupLength\",\n                \"from\",\n                \"to\",\n                \"name\",\n                \"value\",\n                \"data\",\n                \"attributes\",\n                \"nodeName\",\n                \"childNodes\",\n                \"checked\",\n                \"selected\" ];\n            var constNames_1 = {};\n            if (options.compress) {\n                varNames.forEach(function (varName, index) { return (constNames_1[varName] = index); });\n            }\n            else {\n                varNames.forEach(function (varName) { return (constNames_1[varName] = varName); });\n            }\n            options._const = constNames_1;\n        }\n        this.options = options;\n    }\n    DiffDOM.prototype.apply = function (tree, diffs) {\n        return applyDOM(tree, diffs, this.options);\n    };\n    DiffDOM.prototype.undo = function (tree, diffs) {\n        return undoDOM(tree, diffs, this.options);\n    };\n    DiffDOM.prototype.diff = function (t1Node, t2Node) {\n        var finder = new DiffFinder(t1Node, t2Node, this.options);\n        return finder.init();\n    };\n    return DiffDOM;\n}());\n\n/**\n * Use TraceLogger to figure out function calls inside\n * JS objects by wrapping an object with a TraceLogger\n * instance.\n *\n * Pretty-prints the call trace (using unicode box code)\n * when tracelogger.toString() is called.\n */\n/**\n * Wrap an object by calling new TraceLogger(obj)\n *\n * If you're familiar with Python decorators, this\n * does roughly the same thing, adding pre/post\n * call hook logging calls so that you can see\n * what's going on.\n */\nvar TraceLogger = /** @class */ (function () {\n    function TraceLogger(obj) {\n        if (obj === void 0) { obj = {}; }\n        var _this = this;\n        this.pad = \"│   \";\n        this.padding = \"\";\n        this.tick = 1;\n        this.messages = [];\n        var wrapkey = function (obj, key) {\n            // trace this function\n            var oldfn = obj[key];\n            obj[key] = function () {\n                var arguments$1 = arguments;\n\n                var args = [];\n                for (var _i = 0; _i < arguments.length; _i++) {\n                    args[_i] = arguments$1[_i];\n                }\n                _this.fin(key, Array.prototype.slice.call(args));\n                var result = oldfn.apply(obj, args);\n                _this.fout(key, result);\n                return result;\n            };\n        };\n        // can't use Object.keys for prototype walking\n        for (var key in obj) {\n            if (typeof obj[key] === \"function\") {\n                wrapkey(obj, key);\n            }\n        }\n        this.log(\"┌ TRACELOG START\");\n    }\n    // called when entering a function\n    TraceLogger.prototype.fin = function (fn, args) {\n        this.padding += this.pad;\n        this.log(\"\\u251C\\u2500> entering \".concat(fn), args);\n    };\n    // called when exiting a function\n    TraceLogger.prototype.fout = function (fn, result) {\n        this.log(\"│<──┘ generated return value\", result);\n        this.padding = this.padding.substring(0, this.padding.length - this.pad.length);\n    };\n    // log message formatting\n    TraceLogger.prototype.format = function (s, tick) {\n        var nf = function (t) {\n            var tStr = \"\".concat(t);\n            while (tStr.length < 4) {\n                tStr = \"0\".concat(t);\n            }\n            return tStr;\n        };\n        return \"\".concat(nf(tick), \"> \").concat(this.padding).concat(s);\n    };\n    // log a trace message\n    TraceLogger.prototype.log = function () {\n        var arguments$1 = arguments;\n\n        var args = [];\n        for (var _i = 0; _i < arguments.length; _i++) {\n            args[_i] = arguments$1[_i];\n        }\n        var stringCollapse = function (v) {\n            if (!v) {\n                return \"<falsey>\";\n            }\n            if (typeof v === \"string\") {\n                return v;\n            }\n            if (checkElementType(v, \"HTMLElement\")) {\n                return v.outerHTML || \"<empty>\";\n            }\n            if (v instanceof Array) {\n                return \"[\".concat(v.map(stringCollapse).join(\",\"), \"]\");\n            }\n            return v.toString() || v.valueOf() || \"<unknown>\";\n        };\n        var s = args.map(stringCollapse).join(\", \");\n        this.messages.push(this.format(s, this.tick++));\n    };\n    // turn the log into a structured string with\n    // unicode box codes to make it a sensible trace.\n    TraceLogger.prototype.toString = function () {\n        var cap = \"×   \";\n        var terminator = \"└───\";\n        while (terminator.length <= this.padding.length + this.pad.length) {\n            terminator += cap;\n        }\n        var _ = this.padding;\n        this.padding = \"\";\n        terminator = this.format(terminator, this.tick);\n        this.padding = _;\n        return \"\".concat(this.messages.join(\"\\n\"), \"\\n\").concat(terminator);\n    };\n    return TraceLogger;\n}());\n\nexport { DiffDOM, TraceLogger, nodeToObj, stringToObj };\n//# sourceMappingURL=module.js.map\n","import {stringToObj} from \"diff-dom\"\n\nimport {cellType, columnsStateType, columnSettingsType, DataTableOptions, headerCellType, elementNodeType, textNodeType, renderOptions, rowType} from \"./types\"\nimport {cellToText, joinWithSpaces} from \"./helpers\"\n\n\nexport const headingsToVirtualHeaderRowDOM = (\n    headings,\n    columnSettings,\n    columnsState: columnsStateType,\n    {\n        classes,\n        format,\n        hiddenHeader,\n        sortable,\n        scrollY,\n        type\n    }: DataTableOptions,\n    {\n        noColumnWidths,\n        unhideHeader\n    }: renderOptions\n) => ({\n    nodeName: \"TR\",\n\n    childNodes: headings.map(\n        (heading: headerCellType, index: number) : elementNodeType | void => {\n            const column = columnSettings[index] || ({\n                type,\n                format,\n                sortable: true,\n                searchable: true\n            } as columnSettingsType)\n            if (column.hidden) {\n                return\n            }\n            const attributes : { [key: string]: string } = heading.attributes ? {...heading.attributes} : {}\n            if (column.sortable && sortable && (!scrollY.length || unhideHeader)) {\n                if (column.filter) {\n                    attributes[\"data-filterable\"] = \"true\"\n                } else {\n                    attributes[\"data-sortable\"] = \"true\"\n                }\n            }\n\n            if (column.headerClass) {\n                attributes.class = joinWithSpaces(attributes.class, column.headerClass)\n            }\n            if (columnsState.sort && columnsState.sort.column === index) {\n                const directionClass = columnsState.sort.dir === \"asc\" ? classes.ascending : classes.descending\n                attributes.class = joinWithSpaces(attributes.class, directionClass)\n                attributes[\"aria-sort\"] = columnsState.sort.dir === \"asc\" ? \"ascending\" : \"descending\"\n            } else if (columnsState.filters[index]) {\n                attributes.class = joinWithSpaces(attributes.class, classes.filterActive)\n            }\n\n            if (columnsState.widths[index] && !noColumnWidths) {\n                const style = `width: ${columnsState.widths[index]}%;`\n                attributes.style = joinWithSpaces(attributes.style, style)\n            }\n            if (scrollY.length && !unhideHeader) {\n                const style = \"padding-bottom: 0;padding-top: 0;border: 0;\"\n                attributes.style = joinWithSpaces(attributes.style, style)\n            }\n\n            const headerNodes : elementNodeType[] = heading.type === \"html\" ?\n                heading.data as elementNodeType[] :\n                [\n                    {\n                        nodeName: \"#text\",\n                        data: heading.text ?? String(heading.data)\n                    }\n                ] as textNodeType[]\n            return {\n                nodeName: \"TH\",\n                attributes,\n                childNodes:\n                    ((hiddenHeader || scrollY.length) && !unhideHeader) ?\n                        [\n                            {\n                                nodeName: \"#text\",\n                                data: \"\"\n                            }\n                        ] :\n                        !column.sortable || !sortable ?\n                            headerNodes :\n                            [\n                                {\n                                    nodeName: \"BUTTON\",\n                                    attributes: {\n                                        class: column.filter ? classes.filter : classes.sorter\n                                    },\n                                    childNodes: headerNodes\n                                }\n                            ]\n            }\n        }\n    ).filter((column: (elementNodeType | void)) => column)\n})\n\nexport const dataToVirtualDOM = (tableAttributes: { [key: string]: string}, headings: headerCellType[], rows: rowType[], columnSettings: columnSettingsType[], columnsState: columnsStateType, rowCursor: (number | false), {\n    classes,\n    hiddenHeader,\n    header,\n    footer,\n    format,\n    sortable,\n    scrollY,\n    type,\n    rowRender,\n    tabIndex\n}: DataTableOptions, {\n    noColumnWidths,\n    unhideHeader,\n    renderHeader\n}: renderOptions, footers: elementNodeType[], captions: elementNodeType[]) => {\n    const table: elementNodeType = {\n        nodeName: \"TABLE\",\n        attributes: {...tableAttributes},\n        childNodes: [\n            {\n                nodeName: \"TBODY\",\n                childNodes: rows.map(\n                    ({row, index}) => {\n                        const tr: elementNodeType = {\n                            nodeName: \"TR\",\n                            attributes: {\n                                ...row.attributes,\n                                ...{\n                                    \"data-index\": String(index)\n                                }\n                            },\n                            childNodes: row.cells.map(\n                                (cell: cellType, cIndex: number) => {\n                                    const column = columnSettings[cIndex] || ({\n                                        type,\n                                        format,\n                                        sortable: true,\n                                        searchable: true\n                                    } as columnSettingsType)\n                                    if (column.hidden) {\n                                        return\n                                    }\n                                    const td: elementNodeType = {\n                                        nodeName: \"TD\",\n                                        attributes: cell.attributes ? {...cell.attributes} : {},\n                                        childNodes: column.type === \"html\" ?\n                                            cell.data :\n                                            [\n                                                {\n                                                    nodeName: \"#text\",\n                                                    data: cellToText(cell)\n                                                }\n                                            ]\n                                    } as elementNodeType\n                                    if (!header && !footer && columnsState.widths[cIndex] && !noColumnWidths) {\n                                        td.attributes.style = joinWithSpaces(td.attributes.style, `width: ${columnsState.widths[cIndex]}%;`)\n                                    }\n                                    if (column.cellClass) {\n                                        td.attributes.class = joinWithSpaces(td.attributes.class, column.cellClass)\n                                    }\n                                    if (column.render) {\n                                        const renderedCell : (string | elementNodeType | void) = column.render(cell.data, td, index, cIndex)\n                                        if (renderedCell) {\n                                            if (typeof renderedCell === \"string\") {\n                                                // Convenience method to make it work similarly to what it did up to version 5.\n                                                const node = stringToObj(`<td>${renderedCell}</td>`)\n\n                                                if (node.childNodes.length !== 1 || ![\"#text\", \"#comment\"].includes(node.childNodes[0].nodeName)) {\n                                                    td.childNodes = node.childNodes\n                                                } else {\n                                                    (td.childNodes[0] as textNodeType).data = renderedCell\n                                                }\n\n                                            } else {\n                                                return renderedCell\n                                            }\n                                        }\n\n                                    }\n                                    return td\n                                }\n                            ).filter((column: (elementNodeType | void)) => column)\n                        }\n                        if (index === rowCursor) {\n                            tr.attributes.class = joinWithSpaces(tr.attributes.class, classes.cursor)\n                        }\n                        if (rowRender) {\n                            const renderedRow : (elementNodeType | void) = rowRender(row, tr, index)\n                            if (renderedRow) {\n                                if (typeof renderedRow === \"string\") {\n                                    // Convenience method to make it work similarly to what it did up to version 5.\n                                    const node = stringToObj(`<tr>${renderedRow}</tr>`)\n                                    if (node.childNodes && (node.childNodes.length !== 1 || ![\"#text\", \"#comment\"].includes(node.childNodes[0].nodeName))) {\n                                        tr.childNodes = node.childNodes\n                                    } else {\n                                        (tr.childNodes[0] as textNodeType).data = renderedRow\n                                    }\n\n                                } else {\n                                    return renderedRow\n                                }\n                            }\n                        }\n                        return tr\n                    }\n                )\n            } as elementNodeType\n        ]\n    }\n\n    table.attributes.class = joinWithSpaces(table.attributes.class, classes.table)\n\n    if (header || footer || renderHeader) {\n        const headerRow: elementNodeType = headingsToVirtualHeaderRowDOM(headings, columnSettings, columnsState, {classes,\n            hiddenHeader,\n            sortable,\n            scrollY}, {noColumnWidths,\n            unhideHeader})\n\n        if (header || renderHeader) {\n            const thead: elementNodeType = {\n                nodeName: \"THEAD\",\n                childNodes: [headerRow]\n            }\n            if ((scrollY.length || hiddenHeader) && !unhideHeader) {\n                thead.attributes = {\n                    style: \"height: 0px;\"\n                }\n            }\n            table.childNodes.unshift(thead)\n        }\n        if (footer) {\n            const footerRow = header ? structuredClone(headerRow) : headerRow\n            const tfoot: elementNodeType = {\n                nodeName: \"TFOOT\",\n                childNodes: [footerRow]\n            }\n            if ((scrollY.length || hiddenHeader) && !unhideHeader) {\n                tfoot.attributes = {style: \"height: 0px;\"}\n            }\n            table.childNodes.push(tfoot)\n        }\n    }\n\n    footers.forEach(foot => table.childNodes.push(foot))\n    captions.forEach(caption => table.childNodes.push(caption))\n\n    if (tabIndex !== false) {\n        table.attributes.tabindex = String(tabIndex)\n    }\n\n    return table\n}\n","!function(t,e){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=e():\"function\"==typeof define&&define.amd?define(e):(t=\"undefined\"!=typeof globalThis?globalThis:t||self).dayjs=e()}(this,(function(){\"use strict\";var t=1e3,e=6e4,n=36e5,r=\"millisecond\",i=\"second\",s=\"minute\",u=\"hour\",a=\"day\",o=\"week\",c=\"month\",f=\"quarter\",h=\"year\",d=\"date\",l=\"Invalid Date\",$=/^(\\d{4})[-/]?(\\d{1,2})?[-/]?(\\d{0,2})[Tt\\s]*(\\d{1,2})?:?(\\d{1,2})?:?(\\d{1,2})?[.:]?(\\d+)?$/,y=/\\[([^\\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,M={name:\"en\",weekdays:\"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday\".split(\"_\"),months:\"January_February_March_April_May_June_July_August_September_October_November_December\".split(\"_\"),ordinal:function(t){var e=[\"th\",\"st\",\"nd\",\"rd\"],n=t%100;return\"[\"+t+(e[(n-20)%10]||e[n]||e[0])+\"]\"}},m=function(t,e,n){var r=String(t);return!r||r.length>=e?t:\"\"+Array(e+1-r.length).join(n)+t},v={s:m,z:function(t){var e=-t.utcOffset(),n=Math.abs(e),r=Math.floor(n/60),i=n%60;return(e<=0?\"+\":\"-\")+m(r,2,\"0\")+\":\"+m(i,2,\"0\")},m:function t(e,n){if(e.date()<n.date())return-t(n,e);var r=12*(n.year()-e.year())+(n.month()-e.month()),i=e.clone().add(r,c),s=n-i<0,u=e.clone().add(r+(s?-1:1),c);return+(-(r+(n-i)/(s?i-u:u-i))||0)},a:function(t){return t<0?Math.ceil(t)||0:Math.floor(t)},p:function(t){return{M:c,y:h,w:o,d:a,D:d,h:u,m:s,s:i,ms:r,Q:f}[t]||String(t||\"\").toLowerCase().replace(/s$/,\"\")},u:function(t){return void 0===t}},g=\"en\",D={};D[g]=M;var p=\"$isDayjsObject\",S=function(t){return t instanceof _||!(!t||!t[p])},w=function t(e,n,r){var i;if(!e)return g;if(\"string\"==typeof e){var s=e.toLowerCase();D[s]&&(i=s),n&&(D[s]=n,i=s);var u=e.split(\"-\");if(!i&&u.length>1)return t(u[0])}else{var a=e.name;D[a]=e,i=a}return!r&&i&&(g=i),i||!r&&g},O=function(t,e){if(S(t))return t.clone();var n=\"object\"==typeof e?e:{};return n.date=t,n.args=arguments,new _(n)},b=v;b.l=w,b.i=S,b.w=function(t,e){return O(t,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var _=function(){function M(t){this.$L=w(t.locale,null,!0),this.parse(t),this.$x=this.$x||t.x||{},this[p]=!0}var m=M.prototype;return m.parse=function(t){this.$d=function(t){var e=t.date,n=t.utc;if(null===e)return new Date(NaN);if(b.u(e))return new Date;if(e instanceof Date)return new Date(e);if(\"string\"==typeof e&&!/Z$/i.test(e)){var r=e.match($);if(r){var i=r[2]-1||0,s=(r[7]||\"0\").substring(0,3);return n?new Date(Date.UTC(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,s)):new Date(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,s)}}return new Date(e)}(t),this.init()},m.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},m.$utils=function(){return b},m.isValid=function(){return!(this.$d.toString()===l)},m.isSame=function(t,e){var n=O(t);return this.startOf(e)<=n&&n<=this.endOf(e)},m.isAfter=function(t,e){return O(t)<this.startOf(e)},m.isBefore=function(t,e){return this.endOf(e)<O(t)},m.$g=function(t,e,n){return b.u(t)?this[e]:this.set(n,t)},m.unix=function(){return Math.floor(this.valueOf()/1e3)},m.valueOf=function(){return this.$d.getTime()},m.startOf=function(t,e){var n=this,r=!!b.u(e)||e,f=b.p(t),l=function(t,e){var i=b.w(n.$u?Date.UTC(n.$y,e,t):new Date(n.$y,e,t),n);return r?i:i.endOf(a)},$=function(t,e){return b.w(n.toDate()[t].apply(n.toDate(\"s\"),(r?[0,0,0,0]:[23,59,59,999]).slice(e)),n)},y=this.$W,M=this.$M,m=this.$D,v=\"set\"+(this.$u?\"UTC\":\"\");switch(f){case h:return r?l(1,0):l(31,11);case c:return r?l(1,M):l(0,M+1);case o:var g=this.$locale().weekStart||0,D=(y<g?y+7:y)-g;return l(r?m-D:m+(6-D),M);case a:case d:return $(v+\"Hours\",0);case u:return $(v+\"Minutes\",1);case s:return $(v+\"Seconds\",2);case i:return $(v+\"Milliseconds\",3);default:return this.clone()}},m.endOf=function(t){return this.startOf(t,!1)},m.$set=function(t,e){var n,o=b.p(t),f=\"set\"+(this.$u?\"UTC\":\"\"),l=(n={},n[a]=f+\"Date\",n[d]=f+\"Date\",n[c]=f+\"Month\",n[h]=f+\"FullYear\",n[u]=f+\"Hours\",n[s]=f+\"Minutes\",n[i]=f+\"Seconds\",n[r]=f+\"Milliseconds\",n)[o],$=o===a?this.$D+(e-this.$W):e;if(o===c||o===h){var y=this.clone().set(d,1);y.$d[l]($),y.init(),this.$d=y.set(d,Math.min(this.$D,y.daysInMonth())).$d}else l&&this.$d[l]($);return this.init(),this},m.set=function(t,e){return this.clone().$set(t,e)},m.get=function(t){return this[b.p(t)]()},m.add=function(r,f){var d,l=this;r=Number(r);var $=b.p(f),y=function(t){var e=O(l);return b.w(e.date(e.date()+Math.round(t*r)),l)};if($===c)return this.set(c,this.$M+r);if($===h)return this.set(h,this.$y+r);if($===a)return y(1);if($===o)return y(7);var M=(d={},d[s]=e,d[u]=n,d[i]=t,d)[$]||1,m=this.$d.getTime()+r*M;return b.w(m,this)},m.subtract=function(t,e){return this.add(-1*t,e)},m.format=function(t){var e=this,n=this.$locale();if(!this.isValid())return n.invalidDate||l;var r=t||\"YYYY-MM-DDTHH:mm:ssZ\",i=b.z(this),s=this.$H,u=this.$m,a=this.$M,o=n.weekdays,c=n.months,f=n.meridiem,h=function(t,n,i,s){return t&&(t[n]||t(e,r))||i[n].slice(0,s)},d=function(t){return b.s(s%12||12,t,\"0\")},$=f||function(t,e,n){var r=t<12?\"AM\":\"PM\";return n?r.toLowerCase():r};return r.replace(y,(function(t,r){return r||function(t){switch(t){case\"YY\":return String(e.$y).slice(-2);case\"YYYY\":return b.s(e.$y,4,\"0\");case\"M\":return a+1;case\"MM\":return b.s(a+1,2,\"0\");case\"MMM\":return h(n.monthsShort,a,c,3);case\"MMMM\":return h(c,a);case\"D\":return e.$D;case\"DD\":return b.s(e.$D,2,\"0\");case\"d\":return String(e.$W);case\"dd\":return h(n.weekdaysMin,e.$W,o,2);case\"ddd\":return h(n.weekdaysShort,e.$W,o,3);case\"dddd\":return o[e.$W];case\"H\":return String(s);case\"HH\":return b.s(s,2,\"0\");case\"h\":return d(1);case\"hh\":return d(2);case\"a\":return $(s,u,!0);case\"A\":return $(s,u,!1);case\"m\":return String(u);case\"mm\":return b.s(u,2,\"0\");case\"s\":return String(e.$s);case\"ss\":return b.s(e.$s,2,\"0\");case\"SSS\":return b.s(e.$ms,3,\"0\");case\"Z\":return i}return null}(t)||i.replace(\":\",\"\")}))},m.utcOffset=function(){return 15*-Math.round(this.$d.getTimezoneOffset()/15)},m.diff=function(r,d,l){var $,y=this,M=b.p(d),m=O(r),v=(m.utcOffset()-this.utcOffset())*e,g=this-m,D=function(){return b.m(y,m)};switch(M){case h:$=D()/12;break;case c:$=D();break;case f:$=D()/3;break;case o:$=(g-v)/6048e5;break;case a:$=(g-v)/864e5;break;case u:$=g/n;break;case s:$=g/e;break;case i:$=g/t;break;default:$=g}return l?$:b.a($)},m.daysInMonth=function(){return this.endOf(c).$D},m.$locale=function(){return D[this.$L]},m.locale=function(t,e){if(!t)return this.$L;var n=this.clone(),r=w(t,e,!0);return r&&(n.$L=r),n},m.clone=function(){return b.w(this.$d,this)},m.toDate=function(){return new Date(this.valueOf())},m.toJSON=function(){return this.isValid()?this.toISOString():null},m.toISOString=function(){return this.$d.toISOString()},m.toString=function(){return this.$d.toUTCString()},M}(),k=_.prototype;return O.prototype=k,[[\"$ms\",r],[\"$s\",i],[\"$m\",s],[\"$H\",u],[\"$W\",a],[\"$M\",c],[\"$y\",h],[\"$D\",d]].forEach((function(t){k[t[1]]=function(e){return this.$g(e,t[0],t[1])}})),O.extend=function(t,e){return t.$i||(t(e,_,O),t.$i=!0),O},O.locale=w,O.isDayjs=S,O.unix=function(t){return O(1e3*t)},O.en=D[g],O.Ls=D,O.p={},O}));","!function(e,t){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=t():\"function\"==typeof define&&define.amd?define(t):(e=\"undefined\"!=typeof globalThis?globalThis:e||self).dayjs_plugin_customParseFormat=t()}(this,(function(){\"use strict\";var e={LTS:\"h:mm:ss A\",LT:\"h:mm A\",L:\"MM/DD/YYYY\",LL:\"MMMM D, YYYY\",LLL:\"MMMM D, YYYY h:mm A\",LLLL:\"dddd, MMMM D, YYYY h:mm A\"},t=/(\\[[^[]*\\])|([-_:/.,()\\s]+)|(A|a|YYYY|YY?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,n=/\\d\\d/,r=/\\d\\d?/,i=/\\d*[^-_:/,()\\s\\d]+/,o={},s=function(e){return(e=+e)+(e>68?1900:2e3)};var a=function(e){return function(t){this[e]=+t}},f=[/[+-]\\d\\d:?(\\d\\d)?|Z/,function(e){(this.zone||(this.zone={})).offset=function(e){if(!e)return 0;if(\"Z\"===e)return 0;var t=e.match(/([+-]|\\d\\d)/g),n=60*t[1]+(+t[2]||0);return 0===n?0:\"+\"===t[0]?-n:n}(e)}],h=function(e){var t=o[e];return t&&(t.indexOf?t:t.s.concat(t.f))},u=function(e,t){var n,r=o.meridiem;if(r){for(var i=1;i<=24;i+=1)if(e.indexOf(r(i,0,t))>-1){n=i>12;break}}else n=e===(t?\"pm\":\"PM\");return n},d={A:[i,function(e){this.afternoon=u(e,!1)}],a:[i,function(e){this.afternoon=u(e,!0)}],S:[/\\d/,function(e){this.milliseconds=100*+e}],SS:[n,function(e){this.milliseconds=10*+e}],SSS:[/\\d{3}/,function(e){this.milliseconds=+e}],s:[r,a(\"seconds\")],ss:[r,a(\"seconds\")],m:[r,a(\"minutes\")],mm:[r,a(\"minutes\")],H:[r,a(\"hours\")],h:[r,a(\"hours\")],HH:[r,a(\"hours\")],hh:[r,a(\"hours\")],D:[r,a(\"day\")],DD:[n,a(\"day\")],Do:[i,function(e){var t=o.ordinal,n=e.match(/\\d+/);if(this.day=n[0],t)for(var r=1;r<=31;r+=1)t(r).replace(/\\[|\\]/g,\"\")===e&&(this.day=r)}],M:[r,a(\"month\")],MM:[n,a(\"month\")],MMM:[i,function(e){var t=h(\"months\"),n=(h(\"monthsShort\")||t.map((function(e){return e.slice(0,3)}))).indexOf(e)+1;if(n<1)throw new Error;this.month=n%12||n}],MMMM:[i,function(e){var t=h(\"months\").indexOf(e)+1;if(t<1)throw new Error;this.month=t%12||t}],Y:[/[+-]?\\d+/,a(\"year\")],YY:[n,function(e){this.year=s(e)}],YYYY:[/\\d{4}/,a(\"year\")],Z:f,ZZ:f};function c(n){var r,i;r=n,i=o&&o.formats;for(var s=(n=r.replace(/(\\[[^\\]]+])|(LTS?|l{1,4}|L{1,4})/g,(function(t,n,r){var o=r&&r.toUpperCase();return n||i[r]||e[r]||i[o].replace(/(\\[[^\\]]+])|(MMMM|MM|DD|dddd)/g,(function(e,t,n){return t||n.slice(1)}))}))).match(t),a=s.length,f=0;f<a;f+=1){var h=s[f],u=d[h],c=u&&u[0],l=u&&u[1];s[f]=l?{regex:c,parser:l}:h.replace(/^\\[|\\]$/g,\"\")}return function(e){for(var t={},n=0,r=0;n<a;n+=1){var i=s[n];if(\"string\"==typeof i)r+=i.length;else{var o=i.regex,f=i.parser,h=e.slice(r),u=o.exec(h)[0];f.call(t,u),e=e.replace(u,\"\")}}return function(e){var t=e.afternoon;if(void 0!==t){var n=e.hours;t?n<12&&(e.hours+=12):12===n&&(e.hours=0),delete e.afternoon}}(t),t}}return function(e,t,n){n.p.customParseFormat=!0,e&&e.parseTwoDigitYear&&(s=e.parseTwoDigitYear);var r=t.prototype,i=r.parse;r.parse=function(e){var t=e.date,r=e.utc,s=e.args;this.$u=r;var a=s[1];if(\"string\"==typeof a){var f=!0===s[2],h=!0===s[3],u=f||h,d=s[2];h&&(d=s[2]),o=this.$locale(),!f&&d&&(o=n.Ls[d]),this.$d=function(e,t,n){try{if([\"x\",\"X\"].indexOf(t)>-1)return new Date((\"X\"===t?1e3:1)*e);var r=c(t)(e),i=r.year,o=r.month,s=r.day,a=r.hours,f=r.minutes,h=r.seconds,u=r.milliseconds,d=r.zone,l=new Date,m=s||(i||o?1:l.getDate()),M=i||l.getFullYear(),Y=0;i&&!o||(Y=o>0?o-1:l.getMonth());var p=a||0,v=f||0,D=h||0,g=u||0;return d?new Date(Date.UTC(M,Y,m,p,v,D,g+60*d.offset*1e3)):n?new Date(Date.UTC(M,Y,m,p,v,D,g)):new Date(M,Y,m,p,v,D,g)}catch(e){return new Date(\"\")}}(t,a,r),this.init(),d&&!0!==d&&(this.$L=this.locale(d).$L),u&&t!=this.format(a)&&(this.$d=new Date(\"\")),o={}}else if(a instanceof Array)for(var l=a.length,m=1;m<=l;m+=1){s[1]=a[m-1];var M=n.apply(this,s);if(M.isValid()){this.$d=M.$d,this.$L=M.$L,this.init();break}m===l&&(this.$d=new Date(\"\"))}else i.call(this,e)}}}));","import dayjs from \"dayjs\"\nimport customParseFormat from \"dayjs/plugin/customParseFormat\"\n\ndayjs.extend(customParseFormat)\n\n/**\n * Use dayjs to parse cell contents for sorting\n */\nexport const parseDate = (content: string, format: string) => {\n    let date: number | string\n\n    // Converting to YYYYMMDD ensures we can accurately sort the column numerically\n\n    if (format) {\n        switch (format) {\n        case \"ISO_8601\":\n            // ISO8601 is already lexiographically sorted, so we can just sort it as a string.\n            date = content\n            break\n        case \"RFC_2822\":\n            date = dayjs(content.slice(5), \"DD MMM YYYY HH:mm:ss ZZ\").unix()\n            break\n        case \"MYSQL\":\n            date = dayjs(content, \"YYYY-MM-DD hh:mm:ss\").unix()\n            break\n        case \"UNIX\":\n            date = dayjs(content).unix()\n            break\n        // User defined format using the data-format attribute or columns[n].format option\n        default:\n            date = dayjs(content, format, true).valueOf()\n            break\n        }\n    }\n    return date\n}\n","import {nodeToObj, stringToObj} from \"diff-dom\"\nimport {parseDate} from \"./date\"\nimport {namedNodeMapToObject, objToText} from \"./helpers\"\nimport {\n    cellType,\n    columnSettingsType,\n    DataOption,\n    dataRowType,\n    headerCellType,\n    inputCellType,\n    inputHeaderCellType,\n    inputRowType,\n    nodeType\n} from \"./types\"\n\nexport const readDataCell = (cell: inputCellType, columnSettings : columnSettingsType) : cellType => {\n    if (cell?.constructor === Object && Object.prototype.hasOwnProperty.call(cell, \"data\") && !Object.keys(cell).find(key => !([\"text\", \"order\", \"data\", \"attributes\"].includes(key)))) {\n        return (cell as cellType)\n    }\n    const cellData : cellType = {\n        data: cell\n    }\n    switch (columnSettings.type) {\n    case \"string\":\n        if (!(typeof cell === \"string\")) {\n            cellData.text = String(cellData.data)\n            cellData.order = cellData.text\n        }\n        break\n    case \"date\":\n        if (columnSettings.format) {\n            cellData.order = parseDate(String(cellData.data), columnSettings.format)\n        }\n        break\n    case \"number\":\n        cellData.text = String(cellData.data as number)\n        cellData.data = parseFloat(cellData.data as string)\n        cellData.order = cellData.data\n        break\n    case \"html\": {\n        const node = Array.isArray(cellData.data) ?\n            {nodeName: \"TD\",\n                childNodes: (cellData.data as nodeType[])} : // If it is an array, we assume it is an array of nodeType\n            stringToObj(`<td>${String(cellData.data)}</td>`)\n        cellData.data = node.childNodes || []\n        const text = objToText(node)\n        cellData.text = text\n        cellData.order = text\n        break\n    }\n    case \"boolean\":\n        if (typeof cellData.data === \"string\") {\n            cellData.data = cellData.data.toLowerCase().trim()\n        }\n        cellData.data = ![\"false\", false, null, undefined, 0].includes(cellData.data as (string | number | boolean | null | undefined))\n        cellData.order = cellData.data ? 1 : 0\n        cellData.text = String(cellData.data)\n        break\n    case \"other\":\n        cellData.text = \"\"\n        cellData.order = 0\n        break\n    default:\n        cellData.text = JSON.stringify(cellData.data)\n        break\n    }\n\n    return cellData\n}\n\nconst readDOMDataCell = (cell: HTMLElement, columnSettings : columnSettingsType) : cellType => {\n    let cellData : cellType\n    switch (columnSettings.type) {\n    case \"string\":\n        cellData = {\n            data: cell.innerText\n        }\n        break\n    case \"date\": {\n        const data = cell.innerText\n        cellData = {\n            data,\n            order: parseDate(data, columnSettings.format)\n        }\n        break\n    }\n    case \"number\": {\n        const data = parseFloat(cell.innerText)\n        cellData = {\n            data,\n            order: data,\n            text: cell.innerText\n        }\n        break\n    }\n    case \"boolean\": {\n        const data = ![\"false\", \"0\", \"null\", \"undefined\"].includes(cell.innerText.toLowerCase().trim())\n        cellData = {\n            data,\n            text: data ? \"1\" : \"0\",\n            order: data ? 1 : 0\n        }\n        break\n    }\n    default: { // \"html\", \"other\"\n        const node = nodeToObj(cell, {valueDiffing: false})\n        cellData = {\n            data: node.childNodes || [],\n            text: cell.innerText,\n            order: cell.innerText\n        }\n        break\n    }\n    }\n\n    // Save cell attributes to reference when rendering\n    cellData.attributes = namedNodeMapToObject(cell.attributes)\n\n    return cellData\n}\n\n\nexport const readHeaderCell = (cell: inputHeaderCellType) : headerCellType => {\n    if (\n        cell instanceof Object &&\n        cell.constructor === Object &&\n        cell.hasOwnProperty(\"data\") &&\n        (typeof cell.text === \"string\" || typeof cell.data === \"string\")\n    ) {\n        return cell\n    }\n    const cellData : headerCellType = {\n        data: cell\n    }\n    if (typeof cell === \"string\") {\n        if (cell.length) {\n            const node = stringToObj(`<th>${cell}</th>`)\n            if (node.childNodes && (node.childNodes.length !== 1 || node.childNodes[0].nodeName !== \"#text\")) {\n                cellData.data = node.childNodes\n                cellData.type = \"html\"\n                const text = objToText(node)\n                cellData.text = text\n            }\n        }\n\n    } else if ([null, undefined].includes(cell)) {\n        cellData.text = \"\"\n    } else {\n        cellData.text = JSON.stringify(cell)\n    }\n    return cellData\n}\n\nexport const readDOMHeaderCell = (cell: HTMLElement) : headerCellType => {\n    const node = nodeToObj(cell, {valueDiffing: false})\n    let cellData: headerCellType\n    if (node.childNodes && (node.childNodes.length !== 1 || node.childNodes[0].nodeName !== \"#text\")) {\n        cellData = {\n            data: node.childNodes,\n            type: \"html\",\n            text: objToText(node)\n        }\n    } else {\n        cellData = {\n            data: cell.innerText,\n            type: \"string\"\n        }\n    }\n\n    // Save header cell attributes to reference when rendering\n    cellData.attributes = node.attributes\n\n    return cellData\n\n}\n\nexport const readTableData = (dataOption: DataOption, dom: (HTMLTableElement | undefined)=undefined, columnSettings, defaultType, defaultFormat) => {\n\n    const data = {\n        data: [] as dataRowType[],\n        headings: [] as headerCellType[]\n    }\n    if (dataOption.headings) {\n        data.headings = dataOption.headings.map((heading: inputHeaderCellType) => readHeaderCell(heading))\n    } else if (dom?.tHead) {\n        data.headings = Array.from(dom.tHead.querySelectorAll(\"th\")).map((th, index) => {\n            const heading = readDOMHeaderCell(th)\n            if (!columnSettings[index]) {\n                columnSettings[index] = {\n                    type: defaultType,\n                    format: defaultFormat,\n                    searchable: true,\n                    sortable: true\n                }\n            }\n            const settings = columnSettings[index]\n            if (th.dataset.sortable?.trim().toLowerCase() === \"false\" || th.dataset.sort?.trim().toLowerCase() === \"false\") {\n                settings.sortable = false\n            }\n            if (th.dataset.searchable?.trim().toLowerCase() === \"false\") {\n                settings.searchable = false\n            }\n            if (th.dataset.hidden?.trim().toLowerCase() === \"true\" || th.getAttribute(\"hidden\")?.trim().toLowerCase() === \"true\") {\n                settings.hidden = true\n            }\n            if ([\"number\", \"string\", \"html\", \"date\", \"boolean\", \"other\"].includes(th.dataset.type)) {\n                settings.type = th.dataset.type\n                if (settings.type === \"date\" && th.dataset.format) {\n                    settings.format = th.dataset.format\n                }\n            }\n            return heading\n        })\n    } else if (dataOption.data?.length) {\n        const firstRow = dataOption.data[0]\n        const firstRowCells = Array.isArray(firstRow) ? firstRow : firstRow.cells\n        data.headings = firstRowCells.map((_cell: inputCellType) => readHeaderCell(\"\"))\n    } else if (dom?.tBodies.length) {\n        data.headings = Array.from(dom.tBodies[0].rows[0].cells).map((_cell: HTMLElement) => readHeaderCell(\"\"))\n    }\n    for (let i=0; i<data.headings.length; i++) {\n        // Make sure that there are settings for all columns\n        if (!columnSettings[i]) {\n            columnSettings[i] = {\n                type: defaultType,\n                format: defaultFormat,\n                sortable: true,\n                searchable: true\n            }\n        }\n    }\n    if (dataOption.data) {\n        data.data = dataOption.data.map((row: inputRowType | inputCellType[]) => {\n            let attributes: { [key: string]: string }\n            let cells: inputCellType[]\n            if (Array.isArray(row)) {\n                attributes = {}\n                cells = row\n            } else {\n                attributes = row.attributes\n                cells = row.cells\n            }\n            return {\n                attributes,\n                cells: cells.map((cell: inputCellType, index: number) => readDataCell(cell, columnSettings[index]))\n            } as dataRowType\n        })\n    } else if (dom?.tBodies?.length) {\n        data.data = Array.from(dom.tBodies[0].rows).map(\n            row => ({\n                attributes: namedNodeMapToObject(row.attributes),\n                cells: Array.from(row.cells).map(\n                    (cell, index) => {\n                        const cellData = cell.dataset.content ?\n                            readDataCell(cell.dataset.content, columnSettings[index]) :\n                            readDOMDataCell(cell, columnSettings[index])\n                        if (cell.dataset.order) {\n                            cellData.order = isNaN(parseFloat(cell.dataset.order)) ? cell.dataset.order : parseFloat(cell.dataset.order)\n                        }\n                        return cellData\n\n                    }\n                )\n            } as dataRowType)\n        )\n    }\n\n    if (data.data.length && data.data[0].cells.length !== data.headings.length) {\n        throw new Error(\n            \"Data heading length mismatch.\"\n        )\n    }\n    return data\n}\n","import {readDataCell} from \"./read_data\"\nimport {DataTable} from \"./datatable\"\nimport {cellType, dataRowType, inputCellType} from \"./types\"\nimport {cellToText, classNamesToSelector} from \"./helpers\"\n\n/**\n * Rows API\n */\nexport class Rows {\n    cursor: (false | number)\n\n    dt: DataTable\n\n    constructor(dt: DataTable) {\n        this.dt = dt\n\n        this.cursor = false\n    }\n\n    setCursor(index: (false | number) = false) {\n        if (index === this.cursor) {\n            return\n        }\n        const oldCursor = this.cursor\n        this.cursor = index\n        this.dt._renderTable()\n        if (index !== false && this.dt.options.scrollY) {\n            const cursorSelector = classNamesToSelector(this.dt.options.classes.cursor)\n            const cursorDOM = this.dt.dom.querySelector(`tr${cursorSelector}`)\n            if (cursorDOM) {\n                cursorDOM.scrollIntoView({block: \"nearest\"})\n            }\n        }\n        this.dt.emit(\"datatable.cursormove\", this.cursor, oldCursor)\n    }\n\n    /**\n     * Add new row\n     */\n    add(data: cellType[]) {\n        if (!Array.isArray(data) || data.length < 1) {\n            return\n        }\n\n        const row: dataRowType = {\n            cells: data.map((cell: cellType, index: number) => {\n                const columnSettings = this.dt.columns.settings[index]\n                return readDataCell(cell, columnSettings)\n            })\n        }\n        this.dt.data.data.push(row)\n        this.dt.hasRows = true\n        this.dt.update(true)\n    }\n\n    /**\n     * Remove row(s)\n     */\n    remove(select: number | number[]) {\n        if (Array.isArray(select)) {\n            this.dt.data.data = this.dt.data.data.filter((_row: dataRowType, index: number) => !select.includes(index))\n            // We may have emptied the table\n            if ( !this.dt.data.data.length ) {\n                this.dt.hasRows = false\n            }\n            this.dt.update(true)\n        } else {\n            return this.remove([select])\n        }\n    }\n\n\n    /**\n     * Find index of row by searching for a value in a column\n     */\n    findRowIndex(columnIndex: number, value: string | boolean | number) {\n        // returns row index of first case-insensitive string match\n        // inside the td innerText at specific column index\n        return this.dt.data.data.findIndex(\n            (row: dataRowType) => {\n                const cell = row.cells[columnIndex]\n                const cellText = cellToText(cell)\n                return cellText.toLowerCase().includes(String(value).toLowerCase())\n            }\n        )\n    }\n\n    /**\n     * Find index, row, and column data by searching for a value in a column\n     */\n    findRow(columnIndex: number, value: string | boolean | number) {\n        // get the row index\n        const index = this.findRowIndex(columnIndex, value)\n        // exit if not found\n        if (index < 0) {\n            return {\n                index: -1,\n                row: null,\n                cols: []\n            }\n        }\n        // get the row from data\n        const row = this.dt.data.data[index]\n        // return innerHTML of each td\n        const cols = row.cells.map((cell: cellType) => cell.data)\n        // return everything\n        return {\n            index,\n            row,\n            cols\n        }\n    }\n\n    /**\n     * Update a row with new data\n     */\n    updateRow(select: number, data: inputCellType[]) {\n        const row: dataRowType = {\n            cells: data.map((cell: inputCellType, index: number) => {\n                const columnSettings = this.dt.columns.settings[index]\n                return readDataCell(cell, columnSettings)\n            })\n        }\n        this.dt.data.data.splice(select, 1, row)\n        this.dt.update(true)\n    }\n}\n","import {readDataCell, readHeaderCell} from \"./read_data\"\nimport {DataTable} from \"./datatable\"\nimport {\n    cellType,\n    columnSettingsType,\n    columnsStateType,\n    dataRowType,\n    elementNodeType,\n    headerCellType,\n    inputCellType,\n    inputHeaderCellType\n} from \"./types\"\nimport {readColumnSettings} from \"./column_settings\"\nimport {cellToText} from \"./helpers\"\n\n\nexport class Columns {\n    dt: DataTable\n\n    settings: columnSettingsType[]\n\n    _state: columnsStateType\n\n    constructor(dt: DataTable) {\n        this.dt = dt\n        this.init()\n    }\n\n    init() {\n        [this.settings, this._state] = readColumnSettings(this.dt.options.columns, this.dt.options.type, this.dt.options.format)\n    }\n\n    get(column: number) {\n        if (column < 0 || column >= this.size()) {\n            return null\n        }\n        return {...this.settings[column]}\n    }\n\n    size() {\n        return this.settings.length\n    }\n\n    /**\n     * Swap two columns\n     */\n    swap(columns: [number, number]) {\n        if (columns.length === 2) {\n            // Get the current column indexes\n            const cols = this.dt.data.headings.map((_node: headerCellType, index: number) => index)\n\n            const x = columns[0]\n            const y = columns[1]\n            const b = cols[y]\n            cols[y] = cols[x]\n            cols[x] = b\n\n            return this.order(cols)\n        }\n    }\n\n    /**\n     * Reorder the columns\n     */\n    order(columns: number[]) {\n\n        this.dt.data.headings = columns.map((index: number) => this.dt.data.headings[index])\n        this.dt.data.data.forEach(\n            (row: dataRowType) => (row.cells = columns.map((index: number) => row.cells[index]))\n        )\n        this.settings = columns.map(\n            (index: number) => this.settings[index]\n        )\n\n        // Update\n        this.dt.update()\n    }\n\n    /**\n     * Hide columns\n     */\n    hide(columns: number | number[]) {\n        if (!Array.isArray(columns)) {\n            columns = [columns]\n        }\n        if (!columns.length) {\n            return\n        }\n        columns.forEach((index: number) => {\n            if (!this.settings[index]) {\n                this.settings[index] = {\n                    type: \"string\"\n                }\n            }\n            const column = this.settings[index]\n            column.hidden = true\n        })\n\n        this.dt.update()\n    }\n\n    /**\n     * Show columns\n     */\n    show(columns: number | number[]) {\n        if (!Array.isArray(columns)) {\n            columns = [columns]\n        }\n        if (!columns.length) {\n            return\n        }\n        columns.forEach((index: number) => {\n            if (!this.settings[index]) {\n                this.settings[index] = {\n                    type: \"string\",\n                    sortable: true\n                }\n            }\n            const column = this.settings[index]\n            delete column.hidden\n        })\n\n        this.dt.update()\n    }\n\n    /**\n     * Check column(s) visibility\n     */\n    visible(columns: number | number[] | undefined) {\n\n        if (columns === undefined) {\n            columns = [...Array(this.dt.data.headings.length).keys()]\n        }\n        if (Array.isArray(columns)) {\n            return columns.map(index => !this.settings[index]?.hidden)\n        }\n        return !this.settings[columns]?.hidden\n\n    }\n\n    /**\n     * Add a new column\n     */\n    add(data: {data: inputCellType[], heading: inputHeaderCellType} & columnSettingsType) {\n        const newColumnSelector = this.dt.data.headings.length\n        this.dt.data.headings = this.dt.data.headings.concat([readHeaderCell(data.heading)])\n        this.dt.data.data.forEach((row: dataRowType, index: number) => {\n            row.cells = row.cells.concat([readDataCell(data.data[index], data)])\n        })\n        this.settings[newColumnSelector] = {\n            type: data.type || \"string\",\n            sortable: true,\n            searchable: true\n        }\n        if (data.type || data.format || data.sortable || data.render || data.filter) {\n            const column = this.settings[newColumnSelector]\n\n            if (data.render) {\n                column.render = data.render\n            }\n\n            if (data.format) {\n                column.format = data.format\n            }\n\n            if (data.cellClass) {\n                column.cellClass = data.cellClass\n            }\n\n            if (data.headerClass) {\n                column.headerClass = data.headerClass\n            }\n\n            if (data.locale) {\n                column.locale = data.locale\n            }\n\n            if (data.sortable === false) {\n                column.sortable = false\n            } else {\n                if (data.numeric) {\n                    column.numeric = data.numeric\n                }\n                if (data.caseFirst) {\n                    column.caseFirst = data.caseFirst\n                }\n            }\n\n            if (data.searchable === false) {\n                column.searchable = false\n            } else {\n                if (data.sensitivity) {\n                    column.sensitivity = data.sensitivity\n                }\n            }\n\n            if (column.searchable || column.sortable) {\n                if (data.ignorePunctuation) {\n                    column.ignorePunctuation = data.ignorePunctuation\n                }\n            }\n\n            if (data.hidden) {\n                column.hidden = true\n            }\n\n            if (data.filter) {\n                column.filter = data.filter\n            }\n\n            if (data.sortSequence) {\n                column.sortSequence = data.sortSequence\n            }\n        }\n        this.dt.update(true)\n    }\n\n    /**\n     * Remove column(s)\n     */\n    remove(columns: number | number[]) {\n        if (!Array.isArray(columns)) {\n            columns = [columns]\n        }\n\n        this.dt.data.headings = this.dt.data.headings.filter((_heading: headerCellType, index: number) => !columns.includes(index))\n        this.dt.data.data.forEach(\n            (row: dataRowType) => (row.cells = row.cells.filter((_cell: cellType, index: number) => !columns.includes(index)))\n        )\n        this.dt.update(true)\n    }\n\n    /**\n     * Filter by column\n     */\n    filter(column: number, init = false) {\n\n        if (!this.settings[column]?.filter?.length) {\n            // There is no filter to apply.\n            return\n        }\n\n        const currentFilter = this._state.filters[column]\n        let newFilterState\n        if (currentFilter) {\n            let returnNext = false\n            newFilterState = this.settings[column].filter.find((filter: (string | number | boolean | elementNodeType[] | object | ((arg: (string | number | boolean | elementNodeType[] | object)) => boolean))) => {\n                if (returnNext) {\n                    return true\n                }\n                if (filter === currentFilter) {\n                    returnNext = true\n                }\n                return false\n            })\n        } else {\n            const filter = this.settings[column].filter\n            newFilterState = filter ? filter[0] : undefined\n        }\n\n        if (newFilterState) {\n            this._state.filters[column] = newFilterState\n        } else if (currentFilter) {\n            this._state.filters[column] = undefined\n        }\n        this.dt._currentPage = 1\n        this.dt.update()\n\n        if (!init) {\n            this.dt.emit(\"datatable.filter\", column, newFilterState)\n        }\n    }\n\n    /**\n     * Sort by column\n     */\n    sort(index: number, dir: (\"asc\" | \"desc\" | undefined) = undefined, init = false) {\n        const column = this.settings[index]\n\n        if (!init) {\n            this.dt.emit(\"datatable.sorting\", index, dir)\n        }\n\n        if (!dir) {\n            const currentDir = this._state.sort && this._state.sort.column === index ? this._state.sort?.dir : false\n            const sortSequence = column?.sortSequence || [\"asc\", \"desc\"]\n            if (!currentDir) {\n                dir = sortSequence.length ? sortSequence[0] : \"asc\"\n            } else {\n                const currentDirIndex = sortSequence.indexOf(currentDir)\n                if (currentDirIndex === -1) {\n                    dir = sortSequence[0] || \"asc\"\n                } else if (currentDirIndex === sortSequence.length -1) {\n                    dir = sortSequence[0]\n                } else {\n                    dir = sortSequence[currentDirIndex + 1]\n                }\n            }\n\n        }\n\n        const collator = [\"string\", \"html\"].includes(column.type) ?\n            new Intl.Collator(column.locale || this.dt.options.locale, {\n                usage: \"sort\",\n                numeric: column.numeric || this.dt.options.numeric,\n                caseFirst: column.caseFirst || this.dt.options.caseFirst,\n                ignorePunctuation: column.ignorePunctuation|| this.dt.options.ignorePunctuation\n            }) :\n            false\n\n        this.dt.data.data.sort((row1: dataRowType, row2: dataRowType) => {\n            const cell1 = row1.cells[index]\n            const cell2 = row2.cells[index]\n            let order1 = cell1.order ?? cellToText(cell1)\n            let order2 = cell2.order ?? cellToText(cell2)\n            if (dir === \"desc\") {\n                const temp = order1\n                order1 = order2\n                order2 = temp\n            }\n            if (collator) {\n                return collator.compare(String(order1), String(order2))\n            }\n            if (order1 < order2) {\n                return -1\n            } else if (order1 > order2) {\n                return 1\n            }\n            return 0\n        })\n\n        this._state.sort = {column: index,\n            dir}\n        if (this.dt._searchQueries.length) {\n            this.dt.multiSearch(this.dt._searchQueries)\n            this.dt.emit(\"datatable.sort\", index, dir)\n        } else if (!init) {\n            this.dt._currentPage = 1\n            this.dt.update()\n            this.dt.emit(\"datatable.sort\", index, dir)\n        }\n    }\n\n    /**\n     * Measure the actual width of cell content by rendering the entire table with all contents.\n     * Note: Destroys current DOM and therefore requires subsequent dt.update()\n     */\n    _measureWidths() {\n        const activeHeadings = this.dt.data.headings.filter((heading: headerCellType, index: number) => !this.settings[index]?.hidden)\n        if ((this.dt.options.scrollY.length || this.dt.options.fixedColumns) && activeHeadings?.length) {\n\n            this._state.widths = []\n            const renderOptions: {noPaging?: true, noColumnWidths?: true, unhideHeader?: true, renderHeader?: true} = {\n                noPaging: true\n            }\n            // If we have headings we need only set the widths on them\n            // otherwise we need a temp header and the widths need applying to all cells\n            if (this.dt.options.header || this.dt.options.footer) {\n\n                if (this.dt.options.scrollY.length) {\n                    renderOptions.unhideHeader = true\n                }\n                if (this.dt.headerDOM) {\n                    // Remove headerDOM for accurate measurements\n                    this.dt.headerDOM.parentElement.removeChild(this.dt.headerDOM)\n                }\n\n                // Reset widths\n                renderOptions.noColumnWidths = true\n                this.dt._renderTable(renderOptions)\n\n                const activeDOMHeadings : HTMLTableCellElement[] = Array.from(this.dt.dom.querySelector(\"thead, tfoot\")?.firstElementChild?.querySelectorAll(\"th\") || [])\n                let domCounter = 0\n                const absoluteColumnWidths = this.dt.data.headings.map((_heading: headerCellType, index: number) => {\n                    if (this.settings[index]?.hidden) {\n                        return 0\n                    }\n                    const width = activeDOMHeadings[domCounter].offsetWidth\n                    domCounter += 1\n                    return width\n\n                })\n                const totalOffsetWidth = absoluteColumnWidths.reduce(\n                    (total, cellWidth) => total + cellWidth,\n                    0\n                )\n                this._state.widths = absoluteColumnWidths.map(cellWidth => cellWidth / totalOffsetWidth * 100)\n\n            } else {\n                renderOptions.renderHeader = true\n                this.dt._renderTable(renderOptions)\n\n                const activeDOMHeadings: HTMLTableCellElement[] = Array.from(this.dt.dom.querySelector(\"thead, tfoot\")?.firstElementChild?.querySelectorAll(\"th\") || [])\n                let domCounter = 0\n                const absoluteColumnWidths = this.dt.data.headings.map((_heading: headerCellType, index: number) => {\n                    if (this.settings[index]?.hidden) {\n                        return 0\n                    }\n                    const width = activeDOMHeadings[domCounter].offsetWidth\n                    domCounter += 1\n                    return width\n\n                })\n                const totalOffsetWidth = absoluteColumnWidths.reduce(\n                    (total, cellWidth) => total + cellWidth,\n                    0\n                )\n                this._state.widths = absoluteColumnWidths.map(cellWidth => cellWidth / totalOffsetWidth * 100)\n            }\n            // render table without options for measurements\n            this.dt._renderTable()\n        }\n    }\n}\n","import {\n    columnsStateType,\n    filterStateType,\n    columnSettingsType\n} from \"./types\"\n\nexport const readColumnSettings = (columnOptions = [], defaultType, defaultFormat) : [columnSettingsType[], columnsStateType] => {\n\n    let columns: (columnSettingsType | undefined)[] = []\n    let sort: (false | {column: number, dir: \"asc\" | \"desc\"}) = false\n    const filters: (filterStateType | undefined )[] = []\n\n    // Check for the columns option\n\n    columnOptions.forEach(data => {\n\n        // convert single column selection to array\n        const columnSelectors = Array.isArray(data.select) ? data.select : [data.select]\n\n        columnSelectors.forEach((selector: number) => {\n            if (columns[selector]) {\n                if (data.type) {\n                    columns[selector].type = data.type\n                }\n            } else {\n                columns[selector] = {\n                    type: data.type || defaultType,\n                    sortable: true,\n                    searchable: true\n                }\n            }\n            const column = columns[selector]\n\n\n            if (data.render) {\n                column.render = data.render\n            }\n\n            if (data.format) {\n                column.format = data.format\n            } else if (data.type === \"date\") {\n                column.format = defaultFormat\n            }\n\n            if (data.cellClass) {\n                column.cellClass = data.cellClass\n            }\n\n            if (data.headerClass) {\n                column.headerClass = data.headerClass\n            }\n\n            if (data.locale) {\n                column.locale = data.locale\n            }\n\n            if (data.sortable === false) {\n                column.sortable = false\n            } else {\n                if (data.numeric) {\n                    column.numeric = data.numeric\n                }\n                if (data.caseFirst) {\n                    column.caseFirst = data.caseFirst\n                }\n            }\n\n            if (data.searchable === false) {\n                column.searchable = false\n            } else {\n                if (data.sensitivity) {\n                    column.sensitivity = data.sensitivity\n                }\n            }\n\n            if (column.searchable || column.sortable) {\n                if (typeof data.ignorePunctuation !== \"undefined\") {\n                    column.ignorePunctuation = data.ignorePunctuation\n                }\n            }\n\n            if (data.hidden) {\n                column.hidden = true\n            }\n\n            if (data.filter) {\n                column.filter = data.filter\n            }\n\n            if (data.sortSequence) {\n                column.sortSequence = data.sortSequence\n            }\n\n            if (data.sort) {\n                if (data.filter) {\n                    filters[selector] = data.sort\n                } else {\n                    // We only allow one. The last one will overwrite all other options\n                    sort = {column: selector,\n                        dir: data.sort}\n                }\n            }\n\n            if (typeof data.searchItemSeparator !== \"undefined\") {\n                column.searchItemSeparator = data.searchItemSeparator\n            }\n\n        })\n\n\n    })\n\n    columns = columns.map(column => column ?\n        column :\n        {type: defaultType,\n            format: defaultType === \"date\" ? defaultFormat : undefined,\n            sortable: true,\n            searchable: true})\n\n    const widths = [] // Width are determined later on by measuring on screen.\n\n    return [\n        columns, {filters,\n            sort,\n            widths}\n    ]\n\n}\n","// Template for custom layouts\nexport const layoutTemplate = (options, dom) => `<div class='${options.classes.top}'>\n    ${\n    options.paging && options.perPageSelect ?\n        `<div class='${options.classes.dropdown}'>\n            <label>\n                <select class='${options.classes.selector}' name=\"per-page\"></select> ${options.labels.perPage}\n            </label>\n        </div>` :\n        \"\"\n}\n    ${\n    options.searchable ?\n        `<div class='${options.classes.search}'>\n            <input class='${options.classes.input}' placeholder='${options.labels.placeholder}' type='search' name=\"search\" title='${options.labels.searchTitle}'${dom.id ? ` aria-controls=\"${dom.id}\"` : \"\"}>\n        </div>` :\n        \"\"\n}\n</div>\n<div class='${options.classes.container}'${options.scrollY.length ? ` style='height: ${options.scrollY}; overflow-Y: auto;'` : \"\"}></div>\n<div class='${options.classes.bottom}'>\n    ${\n    options.paging ?\n        `<div class='${options.classes.info}'></div>` :\n        \"\"\n}\n    <nav class='${options.classes.pagination}'></nav>\n</div>`\n","import {DataTableConfiguration} from \"./types\"\nimport {layoutTemplate} from \"./templates\"\n/**\n * Default configuration\n */\nexport const defaultConfig: DataTableConfiguration = {\n    // for sorting\n    sortable: true,\n    locale: \"en\",\n    numeric: true,\n    caseFirst: \"false\",\n\n    // for searching\n    searchable: true,\n    sensitivity: \"base\",\n    ignorePunctuation: true,\n    destroyable: true,\n    searchItemSeparator: \"\", // If specified, splits the content of cells up using this separator before performing search.\n    searchQuerySeparator: \" \",\n    searchAnd: false,\n\n    // data\n    data: {},\n    type: \"html\", // Default data type for columns.\n    format: \"YYYY-MM-DD\",\n    columns: [],\n\n    // Pagination\n    paging: true,\n    perPage: 10,\n    perPageSelect: [5, 10, 15, 20, 25],\n    nextPrev: true,\n    firstLast: false,\n    prevText: \"‹\",\n    nextText: \"›\",\n    firstText: \"«\",\n    lastText: \"»\",\n    ellipsisText: \"…\",\n    truncatePager: true,\n    pagerDelta: 2,\n\n    scrollY: \"\",\n\n    fixedColumns: true,\n    fixedHeight: false,\n\n    footer: false,\n    header: true,\n    hiddenHeader: false,\n    caption: undefined,\n\n    rowNavigation: false,\n    tabIndex: false,\n\n    // for overriding rendering\n    pagerRender: false,\n    rowRender: false,\n    tableRender: false,\n    diffDomOptions: {\n        valueDiffing: false\n    },\n\n    // Customise the display text\n    labels: {\n        placeholder: \"Search...\", // The search input placeholder\n        searchTitle: \"Search within table\", // The search input title\n        perPage: \"entries per page\", // per-page dropdown label\n        pageTitle: \"Page {page}\", // page label used in Aria-label\n        noRows: \"No entries found\", // Message shown when there are no records to show\n        noResults: \"No results match your search query\", // Message shown when there are no search results\n        info: \"Showing {start} to {end} of {rows} entries\" //\n    },\n\n    // Customise the layout\n    template: layoutTemplate,\n\n    // Customize the class names used by datatable for different parts\n    classes: {\n        active: \"datatable-active\",\n        ascending: \"datatable-ascending\",\n        bottom: \"datatable-bottom\",\n        container: \"datatable-container\",\n        cursor: \"datatable-cursor\",\n        descending: \"datatable-descending\",\n        disabled: \"datatable-disabled\",\n        dropdown: \"datatable-dropdown\",\n        ellipsis: \"datatable-ellipsis\",\n        filter: \"datatable-filter\",\n        filterActive: \"datatable-filter-active\",\n        empty: \"datatable-empty\",\n        headercontainer: \"datatable-headercontainer\",\n        hidden: \"datatable-hidden\",\n        info: \"datatable-info\",\n        input: \"datatable-input\",\n        loading: \"datatable-loading\",\n        pagination: \"datatable-pagination\",\n        paginationList: \"datatable-pagination-list\",\n        paginationListItem: \"datatable-pagination-list-item\",\n        paginationListItemLink: \"datatable-pagination-list-item-link\",\n        search: \"datatable-search\",\n        selector: \"datatable-selector\",\n        sorter: \"datatable-sorter\",\n        table: \"datatable-table\",\n        top: \"datatable-top\",\n        wrapper: \"datatable-wrapper\"\n    }\n}\n","import {DataTableConfiguration, elementNodeType} from \"./types\"\n\n/**\n * Pager truncation algorithm\n */\nconst truncate = (paginationListItems: elementNodeType[], currentPage: number, pagesLength: number, options: DataTableConfiguration) : elementNodeType[] => {\n    const pagerDelta = options.pagerDelta\n    const classes = options.classes\n    const ellipsisText = options.ellipsisText\n\n    const doublePagerDelta = 2 * pagerDelta\n    let previousPage = currentPage - pagerDelta\n    let nextPage = currentPage + pagerDelta\n\n    if (currentPage < 4 - pagerDelta + doublePagerDelta) {\n        nextPage = 3 + doublePagerDelta\n    } else if (currentPage > pagesLength - (3 - pagerDelta + doublePagerDelta)) {\n        previousPage = pagesLength - (2 + doublePagerDelta)\n    }\n    const paginationListItemsToModify: elementNodeType[] = []\n    for (let k = 1; k <= pagesLength; k++) {\n        if (1 == k || k == pagesLength || (k >= previousPage && k <= nextPage)) {\n            const li = paginationListItems[k - 1]\n            paginationListItemsToModify.push(li)\n        }\n    }\n    let previousLi: elementNodeType\n    const modifiedLis: elementNodeType[] = []\n    paginationListItemsToModify.forEach(li => {\n        const pageNumber = parseInt((li.childNodes[0] as elementNodeType).attributes[\"data-page\"], 10)\n        if (previousLi) {\n            const previousPageNumber = parseInt((previousLi.childNodes[0] as elementNodeType).attributes[\"data-page\"], 10)\n            if (pageNumber - previousPageNumber == 2) {\n                modifiedLis.push(paginationListItems[previousPageNumber])\n            } else if (pageNumber - previousPageNumber != 1) {\n                const newLi: elementNodeType = {\n                    nodeName: \"LI\",\n                    attributes: {\n                        class: `${classes.paginationListItem} ${classes.ellipsis} ${classes.disabled}`\n                    },\n                    childNodes: [\n                        {\n                            nodeName: \"BUTTON\",\n                            attributes: {\n                                class: classes.paginationListItemLink\n                            },\n                            childNodes: [\n                                {\n                                    nodeName: \"#text\",\n                                    data: ellipsisText\n                                }\n                            ]\n                        }\n                    ]\n                }\n                modifiedLis.push(newLi)\n            }\n        }\n        modifiedLis.push(li)\n        previousLi = li\n    })\n\n    return modifiedLis\n}\n\n\nconst paginationListItem = (page: number, label: string, options: DataTableConfiguration, state: {active?: boolean, hidden?: boolean} = {}) : elementNodeType => ({\n    nodeName: \"LI\",\n    attributes: {\n        class:\n        (state.active && !state.hidden) ?\n            `${options.classes.paginationListItem} ${options.classes.active}` :\n            state.hidden ?\n                `${options.classes.paginationListItem} ${options.classes.hidden} ${options.classes.disabled}` :\n                options.classes.paginationListItem\n    },\n    childNodes: [\n        {\n            nodeName: \"BUTTON\",\n            attributes: {\n                \"data-page\": String(page),\n                class: options.classes.paginationListItemLink,\n                \"aria-label\": options.labels.pageTitle.replace(\"{page}\", String(page))\n            },\n            childNodes: [\n                {\n                    nodeName: \"#text\",\n                    data: label\n                }\n            ]\n        }\n    ]\n})\n\nexport const createVirtualPagerDOM = (onFirstPage: boolean, onLastPage: boolean, currentPage: number, totalPages: number, options) => {\n\n    let pagerListItems : elementNodeType[] = []\n\n    // first button\n    if (options.firstLast) {\n        pagerListItems.push(paginationListItem(1, options.firstText, options))\n    }\n\n    // prev button\n    if (options.nextPrev) {\n        const prev = onFirstPage ? 1 : currentPage - 1\n        pagerListItems.push(paginationListItem(prev, options.prevText, options, {hidden: onFirstPage}))\n    }\n\n    let pages = [...Array(totalPages).keys()].map(index => paginationListItem(index+1, String(index+1), options, {active: (index === (currentPage-1))}))\n\n    if (options.truncatePager) {\n        // truncate the paginationListItems\n        pages = truncate(\n            pages,\n            currentPage,\n            totalPages,\n            options\n        )\n\n    }\n\n    // append the paginationListItems\n    pagerListItems = pagerListItems.concat(pages)\n\n    // next button\n    if (options.nextPrev) {\n        const next = onLastPage ? totalPages : currentPage + 1\n        pagerListItems.push(paginationListItem(next, options.nextText, options, {hidden: onLastPage}))\n    }\n\n    // last button\n    if (options.firstLast) {\n        pagerListItems.push(paginationListItem(totalPages, options.lastText, options))\n    }\n\n    const pager : elementNodeType = {\n        nodeName: \"UL\",\n        attributes: {\n            class: options.classes.paginationList\n        },\n        childNodes: pages.length > 1 ? pagerListItems : [] // Don't show single page\n    }\n\n    return pager\n\n}\n","import {\n    cellToText,\n    classNamesToSelector,\n    containsClass,\n    createElement,\n    isObject,\n    joinWithSpaces,\n    visibleToColumnIndex\n} from \"./helpers\"\nimport {\n    cellType,\n    DataTableConfiguration,\n    DataTableOptions,\n    dataRowType,\n    filterStateType,\n    headerCellType,\n    inputCellType,\n    inputRowType,\n    elementNodeType,\n    renderOptions,\n    rowType,\n    TableDataType\n} from \"./types\"\nimport {DiffDOM, nodeToObj} from \"diff-dom\"\n\nimport {dataToVirtualDOM, headingsToVirtualHeaderRowDOM} from \"./virtual_dom\"\nimport {readTableData, readDataCell, readHeaderCell} from \"./read_data\"\nimport {Rows} from \"./rows\"\nimport {Columns} from \"./columns\"\nimport {defaultConfig} from \"./config\"\nimport {createVirtualPagerDOM} from \"./virtual_pager_dom\"\n\n\nexport class DataTable {\n\n    columns: Columns\n\n    containerDOM: HTMLDivElement\n\n    _currentPage: number\n\n    data: TableDataType\n\n    _dd: DiffDOM\n\n    dom: HTMLTableElement\n\n    _events: { [key: string]: ((...args) => void)[]}\n\n    hasHeadings: boolean\n\n    hasRows: boolean\n\n    headerDOM: HTMLDivElement\n\n    _initialHTML: string\n\n    initialized: boolean\n\n    _label: HTMLElement\n\n    lastPage: number\n\n    _listeners: { [key: string]: () => void}\n\n    onFirstPage: boolean\n\n    onLastPage: boolean\n\n    options: DataTableConfiguration\n\n    _pagerDOMs: HTMLElement[]\n\n    _virtualPagerDOM: elementNodeType\n\n    pages: rowType[][]\n\n    _rect: {width: number, height: number}\n\n    rows: Rows\n\n    _searchData: number[]\n\n    _searchQueries: {terms: string[], columns: (number[] | undefined)}[]\n\n    _tableAttributes: {[key: string]: string}\n\n    _tableFooters: elementNodeType[]\n\n    _tableCaptions: elementNodeType[]\n\n    totalPages: number\n\n    _virtualDOM: elementNodeType\n\n    _virtualHeaderDOM: elementNodeType\n\n    wrapperDOM: HTMLElement\n\n    constructor(table: HTMLTableElement | string, options: DataTableOptions = {}) {\n\n        const dom = typeof table === \"string\" ?\n            document.querySelector(table) :\n            table\n        if (dom instanceof HTMLTableElement) {\n            this.dom = dom\n        } else {\n            this.dom = document.createElement(\"table\")\n            dom.appendChild(this.dom)\n        }\n\n        const diffDomOptions = {\n            ...defaultConfig.diffDomOptions,\n            ...options.diffDomOptions\n        }\n\n        const labels = {\n            ...defaultConfig.labels,\n            ...options.labels\n        }\n\n        const classes = {\n            ...defaultConfig.classes,\n            ...options.classes\n        }\n\n        // user options\n        this.options = {\n            ...defaultConfig,\n            ...options,\n            diffDomOptions,\n            labels,\n            classes\n        }\n\n        this._initialHTML = this.options.destroyable ? dom.outerHTML : \"\" // preserve in case of later destruction\n\n        if (this.options.tabIndex) {\n            this.dom.tabIndex = this.options.tabIndex\n        } else if (this.options.rowNavigation && this.dom.tabIndex === -1) {\n            this.dom.tabIndex = 0\n        }\n\n        this._listeners = {\n            onResize: () => this._onResize()\n        }\n\n        this._dd = new DiffDOM(this.options.diffDomOptions || {})\n\n        this.initialized = false\n        this._events = {}\n\n        this._currentPage = 0\n        this.onFirstPage = true\n        this.hasHeadings = false\n        this.hasRows = false\n        this._searchQueries = []\n\n        this.init()\n    }\n\n    /**\n     * Initialize the instance\n     */\n    init() {\n        if (this.initialized || containsClass(this.dom, this.options.classes.table)) {\n            return false\n        }\n\n        this._virtualDOM = nodeToObj(this.dom, this.options.diffDomOptions || {})\n\n        this._tableAttributes = {...this._virtualDOM.attributes}\n        this._tableFooters = this._virtualDOM.childNodes?.filter(node => node.nodeName === \"TFOOT\") ?? []\n        this._tableCaptions = this._virtualDOM.childNodes?.filter(node => node.nodeName === \"CAPTION\") ?? []\n        if (this.options.caption !== undefined) {\n            this._tableCaptions.push({\n                nodeName: \"CAPTION\",\n                childNodes: [\n                    {\n                        nodeName: \"#text\",\n                        data: this.options.caption\n                    }\n                ]\n            })\n        }\n\n        this.rows = new Rows(this)\n        this.columns = new Columns(this)\n\n        this.data = readTableData(this.options.data, this.dom, this.columns.settings, this.options.type, this.options.format)\n\n        this._render()\n\n        setTimeout(() => {\n            this.emit(\"datatable.init\")\n            this.initialized = true\n        }, 10)\n    }\n\n\n    /**\n     * Render the instance\n     */\n    _render() {\n\n        // Build\n        this.wrapperDOM = createElement(\"div\", {\n            class: `${this.options.classes.wrapper} ${this.options.classes.loading}`\n        })\n\n        this.wrapperDOM.innerHTML = this.options.template(this.options, this.dom)\n\n        const selectorClassSelector = classNamesToSelector(this.options.classes.selector)\n        const selector = this.wrapperDOM.querySelector(`select${selectorClassSelector}`)\n\n        // Per Page Select\n        if (selector && this.options.paging && this.options.perPageSelect) {\n\n            // Create the options\n            this.options.perPageSelect.forEach((choice: number | [string, number]) => {\n                const [lab, val] = Array.isArray(choice) ? [choice[0], choice[1]] : [String(choice), choice]\n                const selected = val === this.options.perPage\n                const option = new Option(lab, String(val), selected, selected)\n                selector.appendChild(option)\n            })\n\n        } else if (selector) {\n            selector.parentElement.removeChild(selector)\n        }\n\n        const containerSelector = classNamesToSelector(this.options.classes.container)\n        this.containerDOM = this.wrapperDOM.querySelector(containerSelector)\n\n        this._pagerDOMs = []\n        const paginationSelector = classNamesToSelector(this.options.classes.pagination)\n        Array.from(this.wrapperDOM.querySelectorAll(paginationSelector)).forEach(el => {\n            if (!(el instanceof HTMLElement)) {\n                return\n            }\n            // We remove the inner part of the pager containers to ensure they are all the same.\n            el.innerHTML = `<ul class=\"${this.options.classes.paginationList}\"></ul>`\n            this._pagerDOMs.push(el.firstElementChild as HTMLElement)\n        })\n\n        this._virtualPagerDOM = {\n            nodeName: \"UL\",\n            attributes: {\n                class: this.options.classes.paginationList\n            }\n        }\n\n\n        const infoSelector = classNamesToSelector(this.options.classes.info)\n        this._label = this.wrapperDOM.querySelector(infoSelector)\n\n        // Insert in to DOM tree\n        this.dom.parentElement.replaceChild(this.wrapperDOM, this.dom)\n        this.containerDOM.appendChild(this.dom)\n\n        // Store the table dimensions\n        this._rect = this.dom.getBoundingClientRect()\n\n        // Fix height\n        this._fixHeight()\n\n        // Class names\n        if (!this.options.header) {\n            this.wrapperDOM.classList.add(\"no-header\")\n        }\n\n        if (!this.options.footer) {\n            this.wrapperDOM.classList.add(\"no-footer\")\n        }\n\n        if (this.options.sortable) {\n            this.wrapperDOM.classList.add(\"sortable\")\n        }\n\n        if (this.options.searchable) {\n            this.wrapperDOM.classList.add(\"searchable\")\n        }\n\n        if (this.options.fixedHeight) {\n            this.wrapperDOM.classList.add(\"fixed-height\")\n        }\n\n        if (this.options.fixedColumns) {\n            this.wrapperDOM.classList.add(\"fixed-columns\")\n        }\n\n        this._bindEvents()\n\n        if (this.columns._state.sort) {\n            this.columns.sort(this.columns._state.sort.column, this.columns._state.sort.dir, true)\n        }\n\n        this.update(true)\n    }\n\n    _renderTable(renderOptions: renderOptions = {}) {\n        let rows: rowType[]\n        const isPaged = (this.options.paging || this._searchQueries.length || this.columns._state.filters.length) && this._currentPage && this.pages.length && !renderOptions.noPaging\n        if (isPaged) {\n            rows = this.pages[this._currentPage - 1]\n        } else {\n            rows = this.data.data.map((row, index) => ({\n                row,\n                index\n            }))\n        }\n\n        let newVirtualDOM = dataToVirtualDOM(\n            this._tableAttributes,\n            this.data.headings,\n            rows,\n            this.columns.settings,\n            this.columns._state,\n            this.rows.cursor,\n            this.options,\n            renderOptions,\n            this._tableFooters,\n            this._tableCaptions\n        )\n\n        if (this.options.tableRender) {\n            const renderedTableVirtualDOM : (elementNodeType | void) = this.options.tableRender(this.data, newVirtualDOM, \"main\")\n            if (renderedTableVirtualDOM) {\n                newVirtualDOM = renderedTableVirtualDOM\n            }\n        }\n        const diff = this._dd.diff(this._virtualDOM, newVirtualDOM)\n        this._dd.apply(this.dom, diff)\n        this._virtualDOM = newVirtualDOM\n    }\n\n    /**\n     * Render the page\n     * @return {Void}\n     */\n    _renderPage(lastRowCursor=false) {\n        if (this.hasRows && this.totalPages) {\n            if (this._currentPage > this.totalPages) {\n                this._currentPage = 1\n            }\n\n            // Use a fragment to limit touching the DOM\n            this._renderTable()\n\n            this.onFirstPage = this._currentPage === 1\n            this.onLastPage = this._currentPage === this.lastPage\n        } else {\n            this.setMessage(this.options.labels.noRows)\n        }\n\n        // Update the info\n        let current = 0\n\n        let f = 0\n        let t = 0\n        let items\n\n        if (this.totalPages) {\n            current = this._currentPage - 1\n            f = current * this.options.perPage\n            t = f + this.pages[current].length\n            f = f + 1\n            items = this._searchQueries.length ? this._searchData.length : this.data.data.length\n        }\n\n        if (this._label && this.options.labels.info.length) {\n            // CUSTOM LABELS\n            const string = this.options.labels.info\n                .replace(\"{start}\", String(f))\n                .replace(\"{end}\", String(t))\n                .replace(\"{page}\", String(this._currentPage))\n                .replace(\"{pages}\", String(this.totalPages))\n                .replace(\"{rows}\", String(items))\n\n            this._label.innerHTML = items ? string : \"\"\n        }\n\n        if (this._currentPage == 1) {\n            this._fixHeight()\n        }\n\n        if (this.options.rowNavigation && this._currentPage) {\n            if (!this.rows.cursor || !this.pages[this._currentPage-1].find(\n                row => row.index === this.rows.cursor)\n            ) {\n                const rows = this.pages[this._currentPage-1]\n                if (rows.length) {\n                    if (lastRowCursor) {\n                        this.rows.setCursor(rows[rows.length-1].index)\n                    } else {\n                        this.rows.setCursor(rows[0].index)\n                    }\n                }\n            }\n        }\n    }\n\n    /** Render the pager(s)\n     *\n     */\n    _renderPagers() {\n        if (!this.options.paging) {\n            return\n        }\n        let newPagerVirtualDOM = createVirtualPagerDOM(this.onFirstPage, this.onLastPage, this._currentPage, this.totalPages, this.options)\n\n        if (this.options.pagerRender) {\n            const renderedPagerVirtualDOM : (elementNodeType | void) = this.options.pagerRender([this.onFirstPage, this.onLastPage, this._currentPage, this.totalPages], newPagerVirtualDOM)\n            if (renderedPagerVirtualDOM) {\n                newPagerVirtualDOM = renderedPagerVirtualDOM\n            }\n        }\n\n        const diffs = this._dd.diff(this._virtualPagerDOM, newPagerVirtualDOM)\n        // We may have more than one pager\n        this._pagerDOMs.forEach((pagerDOM: HTMLElement) => {\n            this._dd.apply(pagerDOM, diffs)\n        })\n\n        this._virtualPagerDOM = newPagerVirtualDOM\n    }\n\n    // Render header that is not in the same table element as the remainder\n    // of the table. Used for tables with scrollY.\n    _renderSeparateHeader() {\n        const container = this.dom.parentElement\n        if (!this.headerDOM) {\n            this.headerDOM = document.createElement(\"div\")\n            this._virtualHeaderDOM = {\n                nodeName: \"DIV\"\n            }\n\n        }\n        container.parentElement.insertBefore(this.headerDOM, container)\n        let tableVirtualDOM : elementNodeType = {\n            nodeName: \"TABLE\",\n            attributes: this._tableAttributes,\n            childNodes: [\n                {\n                    nodeName: \"THEAD\",\n                    childNodes: [\n                        headingsToVirtualHeaderRowDOM(\n                            this.data.headings, this.columns.settings, this.columns._state, this.options, {unhideHeader: true})\n                    ]\n\n                }\n\n            ]\n        }\n        tableVirtualDOM.attributes.class = joinWithSpaces(tableVirtualDOM.attributes.class, this.options.classes.table)\n        if (this.options.tableRender) {\n            const renderedTableVirtualDOM : (elementNodeType | void) = this.options.tableRender(this.data, tableVirtualDOM, \"header\")\n            if (renderedTableVirtualDOM) {\n                tableVirtualDOM = renderedTableVirtualDOM\n            }\n        }\n\n        const newVirtualHeaderDOM = {\n            nodeName: \"DIV\",\n            attributes: {\n                class: this.options.classes.headercontainer\n            },\n            childNodes: [tableVirtualDOM]\n        }\n\n        const diff = this._dd.diff(this._virtualHeaderDOM, newVirtualHeaderDOM)\n        this._dd.apply(this.headerDOM, diff)\n        this._virtualHeaderDOM = newVirtualHeaderDOM\n\n        // Compensate for scrollbars\n        const paddingRight = this.headerDOM.firstElementChild.clientWidth - this.dom.clientWidth\n        if (paddingRight) {\n            const paddedVirtualHeaderDOM = structuredClone(this._virtualHeaderDOM)\n            paddedVirtualHeaderDOM.attributes.style = `padding-right: ${paddingRight}px;`\n            const diff = this._dd.diff(this._virtualHeaderDOM, paddedVirtualHeaderDOM)\n            this._dd.apply(this.headerDOM, diff)\n            this._virtualHeaderDOM = paddedVirtualHeaderDOM\n        }\n\n        if (container.scrollHeight > container.clientHeight) {\n            // scrollbars on one page means scrollbars on all pages.\n            container.style.overflowY = \"scroll\"\n        }\n    }\n\n    /**\n     * Bind event listeners\n     * @return {[type]} [description]\n     */\n    _bindEvents() {\n        // Per page selector\n        if (this.options.perPageSelect) {\n            const selectorClassSelector = classNamesToSelector(this.options.classes.selector)\n            const selector = this.wrapperDOM.querySelector(selectorClassSelector)\n            if (selector && selector instanceof HTMLSelectElement) {\n                // Change per page\n                selector.addEventListener(\"change\", () => {\n                    this.options.perPage = parseInt(selector.value, 10)\n                    this.update()\n\n                    this._fixHeight()\n\n                    this.emit(\"datatable.perpage\", this.options.perPage)\n                }, false)\n            }\n        }\n\n        // Search input\n        if (this.options.searchable) {\n            this.wrapperDOM.addEventListener(\"input\", (event: InputEvent) => {\n                const inputSelector = classNamesToSelector(this.options.classes.input)\n                const target = event.target\n                if (!(target instanceof HTMLInputElement) || !target.matches(inputSelector)) {\n                    return\n                }\n                event.preventDefault()\n\n                const searches: { terms: string[], columns: (number[] | undefined) }[] = []\n                const searchFields: HTMLInputElement[] = Array.from(this.wrapperDOM.querySelectorAll(inputSelector))\n                searchFields.filter(\n                    el => el.value.length\n                ).forEach(\n                    el => {\n                        const andSearch = el.dataset.and || this.options.searchAnd\n                        const querySeparator = el.dataset.querySeparator || this.options.searchQuerySeparator\n                        const terms = querySeparator ? el.value.split(this.options.searchQuerySeparator) : [el.value]\n                        if (andSearch) {\n                            terms.forEach(term => {\n                                if (el.dataset.columns) {\n                                    searches.push({\n                                        terms: [term],\n                                        columns: (JSON.parse(el.dataset.columns) as number[])\n                                    })\n                                } else {\n                                    searches.push({terms: [term],\n                                        columns: undefined})\n                                }\n                            })\n                        } else {\n                            if (el.dataset.columns) {\n                                searches.push({\n                                    terms,\n                                    columns: (JSON.parse(el.dataset.columns) as number[])\n                                })\n                            } else {\n                                searches.push({terms,\n                                    columns: undefined})\n                            }\n                        }\n\n                    }\n                )\n                if (searches.length === 1 && searches[0].terms.length === 1) {\n                    const search = searches[0]\n                    this.search(search.terms[0], search.columns)\n                } else {\n                    this.multiSearch(searches)\n                }\n            })\n        }\n\n        // Pager(s) / sorting\n        this.wrapperDOM.addEventListener(\"click\", (event: Event) => {\n            const target = event.target as Element\n            const hyperlink = target.closest(\"a, button\")\n            if (!hyperlink) {\n                return\n            }\n\n            if (hyperlink.hasAttribute(\"data-page\")) {\n                this.page(parseInt(hyperlink.getAttribute(\"data-page\"), 10))\n                event.preventDefault()\n            } else if (containsClass(hyperlink, this.options.classes.sorter)) {\n                const visibleIndex = Array.from(hyperlink.parentElement.parentElement.children).indexOf(hyperlink.parentElement)\n                const columnIndex = visibleToColumnIndex(visibleIndex, this.columns.settings)\n                this.columns.sort(columnIndex)\n                event.preventDefault()\n            } else if (containsClass(hyperlink, this.options.classes.filter)) {\n                const visibleIndex = Array.from(hyperlink.parentElement.parentElement.children).indexOf(hyperlink.parentElement)\n                const columnIndex = visibleToColumnIndex(visibleIndex, this.columns.settings)\n                this.columns.filter(columnIndex)\n                event.preventDefault()\n            }\n        }, false)\n\n        if (this.options.rowNavigation) {\n            this.dom.addEventListener(\"keydown\", (event: KeyboardEvent) => {\n                if (event.key === \"ArrowUp\") {\n                    event.preventDefault()\n                    event.stopPropagation()\n                    let lastRow: rowType\n                    this.pages[this._currentPage-1].find((row: rowType) => {\n                        if (row.index===this.rows.cursor) {\n                            return true\n                        }\n                        lastRow = row\n                        return false\n                    })\n                    if (lastRow) {\n                        this.rows.setCursor(lastRow.index)\n                    } else if (!this.onFirstPage) {\n                        this.page(this._currentPage-1, true)\n                    }\n                } else if (event.key === \"ArrowDown\") {\n                    event.preventDefault()\n                    event.stopPropagation()\n                    let foundRow: boolean\n                    const nextRow = this.pages[this._currentPage-1].find((row: rowType) => {\n                        if (foundRow) {\n                            return true\n                        }\n                        if (row.index===this.rows.cursor) {\n                            foundRow = true\n                        }\n                        return false\n                    })\n                    if (nextRow) {\n                        this.rows.setCursor(nextRow.index)\n                    } else if (!this.onLastPage) {\n                        this.page(this._currentPage+1)\n                    }\n                } else if ([\"Enter\", \" \"].includes(event.key)) {\n                    this.emit(\"datatable.selectrow\", this.rows.cursor, event)\n                }\n            })\n            this.dom.addEventListener(\"mousedown\", (event: Event) => {\n                const target = event.target\n                if (!(target instanceof Element)) {\n                    return\n                }\n                if (this.dom.matches(\":focus\")) {\n                    const row = Array.from(this.dom.querySelectorAll(\"tbody > tr\")).find(row => row.contains(target))\n                    if (row && row instanceof HTMLElement) {\n                        this.emit(\"datatable.selectrow\", parseInt(row.dataset.index, 10), event)\n                    }\n                }\n\n            })\n        } else {\n            this.dom.addEventListener(\"mousedown\", (event: Event) => {\n                const target = event.target\n                if (!(target instanceof Element)) {\n                    return\n                }\n                const row = Array.from(this.dom.querySelectorAll(\"tbody > tr\")).find(row => row.contains(target))\n                if (row && row instanceof HTMLElement) {\n                    this.emit(\"datatable.selectrow\", parseInt(row.dataset.index, 10), event)\n                }\n            })\n        }\n\n        window.addEventListener(\"resize\", this._listeners.onResize)\n    }\n\n    /**\n     * execute on resize\n     */\n    _onResize() {\n        this._rect = this.containerDOM.getBoundingClientRect()\n        if (!this._rect.width) {\n            // No longer shown, likely no longer part of DOM. Give up.\n            return\n        }\n        this.update(true)\n    }\n\n    /**\n     * Destroy the instance\n     * @return {void}\n     */\n    destroy() {\n        if (!this.options.destroyable) {\n            return\n        }\n        if (this.wrapperDOM.parentElement) {\n            // Restore the initial HTML\n            const oldDOM = createElement(\"div\")\n            oldDOM.innerHTML = this._initialHTML\n            this.wrapperDOM.parentElement.replaceChild(oldDOM.firstElementChild, this.wrapperDOM)\n        } else {\n            // Remove the className\n            this.options.classes.table?.split(\" \").forEach(className => this.wrapperDOM.classList.remove(className))\n        }\n\n        window.removeEventListener(\"resize\", this._listeners.onResize)\n\n        this.initialized = false\n    }\n\n    /**\n     * Update the instance\n     * @return {Void}\n     */\n    update(measureWidths = false) {\n        if (measureWidths) {\n            this.columns._measureWidths()\n            this.hasRows = Boolean(this.data.data.length)\n            this.hasHeadings = Boolean(this.data.headings.length)\n        }\n        this.options.classes.empty?.split(\" \").forEach(className => this.wrapperDOM.classList.remove(className))\n\n        this._paginate()\n        this._renderPage()\n\n        this._renderPagers()\n\n        if (this.options.scrollY.length) {\n            this._renderSeparateHeader()\n        }\n\n        this.emit(\"datatable.update\")\n    }\n\n    _paginate() {\n        let rows: rowType[] = this.data.data.map((row, index) => ({\n            row,\n            index\n        }))\n\n        if (this._searchQueries.length) {\n            rows = []\n\n            this._searchData.forEach((index: number) => rows.push({index,\n                row: this.data.data[index]}))\n        }\n\n        if (this.columns._state.filters.length) {\n            this.columns._state.filters.forEach(\n                (filterState: (filterStateType | undefined), column: number) => {\n                    if (!filterState) {\n                        return\n                    }\n                    rows = rows.filter(\n                        (row: {index: number, row: dataRowType}) => {\n                            const cell = row.row.cells[column]\n                            return typeof filterState === \"function\" ? filterState(cell.data) : cellToText(cell) === filterState\n                        }\n                    )\n                }\n            )\n        }\n\n        if (this.options.paging && this.options.perPage > 0) {\n            // Check for hidden columns\n            this.pages = rows\n                .map((_row, i: number) => i % this.options.perPage === 0 ? rows.slice(i, i + this.options.perPage) : null)\n                .filter((page: {row: dataRowType, index: number}[]) => page)\n        } else {\n            this.pages = [rows]\n        }\n\n        this.totalPages = this.lastPage = this.pages.length\n\n        if (!this._currentPage) {\n            this._currentPage = 1\n        }\n        return this.totalPages\n    }\n\n    /**\n     * Fix the container height\n     */\n    _fixHeight() {\n        if (this.options.fixedHeight) {\n            this.containerDOM.style.height = null\n            this._rect = this.containerDOM.getBoundingClientRect()\n            this.containerDOM.style.height = `${this._rect.height}px`\n        }\n    }\n\n    /**\n     * Perform a simple search of the data set\n     */\n    search(term: string, columns: (number[] | undefined ) = undefined) {\n\n        if (!term.length) {\n            this._currentPage = 1\n            this._searchQueries = []\n            this._searchData = []\n            this.update()\n            this.emit(\"datatable.search\", \"\", [])\n            this.wrapperDOM.classList.remove(\"search-results\")\n            return false\n        }\n\n        this.multiSearch([\n            {terms: [term],\n                columns: columns ? columns : undefined}\n        ])\n\n        this.emit(\"datatable.search\", term, this._searchData)\n\n    }\n\n    /**\n     * Perform a search of the data set seraching for up to multiple strings in various columns\n     */\n    multiSearch(rawQueries : {terms: string[], columns: (number[] | undefined)}[]) {\n        if (!this.hasRows) return false\n\n        this._currentPage = 1\n        this._searchData = []\n        // Remove empty queries\n        const queries = rawQueries.map(query => ({\n            columns: query.columns,\n            terms: query.terms.map(term => term.trim()).filter(term => term)\n        })).filter(query => query.terms.length\n        )\n\n        this._searchQueries = queries\n\n        if (!queries.length) {\n            this.update()\n            this.emit(\"datatable.multisearch\", queries, this._searchData)\n            this.wrapperDOM.classList.remove(\"search-results\")\n            return false\n        }\n        const queryWords = queries.map(query => this.columns.settings.map(\n            (column, index) => {\n                if (column.hidden || !column.searchable || (query.columns && !query.columns.includes(index))) {\n                    return false\n                }\n                let columnQueries = query.terms\n                const sensitivity = column.sensitivity || this.options.sensitivity\n                if ([\"base\", \"accent\"].includes(sensitivity)) {\n                    columnQueries = columnQueries.map(query => query.toLowerCase())\n                }\n                if ([\"base\", \"case\"].includes(sensitivity)) {\n                    columnQueries = columnQueries.map(query => query.normalize(\"NFD\").replace(/\\p{Diacritic}/gu, \"\"))\n                }\n                const ignorePunctuation = column.ignorePunctuation ?? this.options.ignorePunctuation\n                if (ignorePunctuation) {\n                    columnQueries = columnQueries.map(query => query.replace(/[.,/#!$%^&*;:{}=-_`~()]/g, \"\"))\n                }\n                return columnQueries\n            }\n        ))\n        this.data.data.forEach((row: dataRowType, idx: number) => {\n            const searchRow = row.cells.map((cell, i) => {\n                let content = cellToText(cell).trim()\n                const column = this.columns.settings[i]\n                if (content.length) {\n                    const sensitivity = column.sensitivity || this.options.sensitivity\n                    if ([\"base\", \"accent\"].includes(sensitivity)) {\n                        content = content.toLowerCase()\n                    }\n                    if ([\"base\", \"case\"].includes(sensitivity)) {\n                        content = content.normalize(\"NFD\").replace(/\\p{Diacritic}/gu, \"\")\n                    }\n                    const ignorePunctuation = column.ignorePunctuation ?? this.options.ignorePunctuation\n                    if (ignorePunctuation) {\n                        content = content.replace(/[.,/#!$%^&*;:{}=-_`~()]/g, \"\")\n                    }\n                }\n                const searchItemSeparator = column.searchItemSeparator || this.options.searchItemSeparator\n                return searchItemSeparator ? content.split(searchItemSeparator) : [content]\n            })\n            if (\n                queryWords.every(\n                    queries => queries.find(\n                        (query, index) => query ?\n                            query.find(queryWord => searchRow[index].find(searchItem => searchItem.includes(queryWord))) :\n                            false\n                    )\n                )\n            ) {\n                this._searchData.push(idx)\n            }\n\n        })\n\n        this.wrapperDOM.classList.add(\"search-results\")\n        if (this._searchData.length) {\n            this.update()\n        } else {\n            this.wrapperDOM.classList.remove(\"search-results\")\n\n            this.setMessage(this.options.labels.noResults)\n        }\n\n        this.emit(\"datatable.multisearch\", queries, this._searchData)\n    }\n\n    /**\n     * Change page\n     */\n    page(page: number, lastRowCursor = false) {\n        // We don't want to load the current page again.\n        if (page === this._currentPage) {\n            return false\n        }\n\n        if (!isNaN(page)) {\n            this._currentPage = page\n        }\n\n        if (page > this.pages.length || page < 0) {\n            return false\n        }\n\n        this._renderPage(lastRowCursor)\n        this._renderPagers()\n\n        this.emit(\"datatable.page\", page)\n    }\n\n    /**\n     * Add new row data\n     */\n    insert(data: (\n        {headings?: string[], data?: (inputRowType | inputCellType[])[]} | { [key: string]: inputCellType}[])) {\n        let rows: dataRowType[] = []\n        if (Array.isArray(data)) {\n            const headings = this.data.headings.map((heading: headerCellType) => heading.text ?? String(heading.data))\n            data.forEach((row, rIndex) => {\n                const r: cellType[] = []\n                Object.entries(row).forEach(([heading, cell]) => {\n\n                    const index = headings.indexOf(heading)\n\n                    if (index > -1) {\n                        r[index] = readDataCell(cell as inputCellType, this.columns.settings[index])\n                    } else if (!this.hasHeadings && !this.hasRows && rIndex === 0) {\n                        r[headings.length] = readDataCell(cell as inputCellType, this.columns.settings[headings.length])\n                        headings.push(heading)\n                        this.data.headings.push(readHeaderCell(heading))\n                    }\n                })\n                rows.push({\n                    cells: r\n                })\n            })\n        } else if (isObject(data)) {\n            if (data.headings && !this.hasHeadings && !this.hasRows) {\n                this.data = readTableData(data, undefined, this.columns.settings, this.options.type, this.options.format)\n            } else if (data.data && Array.isArray(data.data)) {\n                rows = data.data.map(row => {\n                    let attributes: { [key: string]: string }\n                    let cells: inputCellType[]\n                    if (Array.isArray(row)) {\n                        attributes = {}\n                        cells = row\n                    } else {\n                        attributes = row.attributes\n                        cells = row.cells\n                    }\n                    return {\n                        attributes,\n                        cells: cells.map((cell, index) => readDataCell(cell as inputCellType, this.columns.settings[index]))\n                    } as dataRowType\n                })\n            }\n        }\n        if (rows.length) {\n            rows.forEach((row: dataRowType) => this.data.data.push(row))\n        }\n        this.hasHeadings = Boolean(this.data.headings.length)\n\n        if (this.columns._state.sort) {\n            this.columns.sort(this.columns._state.sort.column, this.columns._state.sort.dir, true)\n        }\n\n        this.update(true)\n    }\n\n    /**\n     * Refresh the instance\n     */\n    refresh() {\n        if (this.options.searchable) {\n            const inputSelector = classNamesToSelector(this.options.classes.input)\n            const inputs: HTMLInputElement[] = Array.from(this.wrapperDOM.querySelectorAll(inputSelector))\n            inputs.forEach(el => (el.value = \"\"))\n            this._searchQueries = []\n        }\n        this._currentPage = 1\n        this.onFirstPage = true\n        this.update(true)\n\n        this.emit(\"datatable.refresh\")\n    }\n\n    /**\n     * Print the table\n     */\n    print() {\n        const tableDOM = createElement(\"table\")\n        const tableVirtualDOM = {nodeName: \"TABLE\"}\n        let newTableVirtualDOM = dataToVirtualDOM(\n            this._tableAttributes,\n            this.data.headings,\n            this.data.data.map((row, index) => ({\n                row,\n                index\n            })),\n            this.columns.settings,\n            this.columns._state,\n            false, // No row cursor\n            this.options,\n            {\n                noColumnWidths: true,\n                unhideHeader: true\n            },\n            this._tableFooters,\n            this._tableCaptions\n        )\n\n        if (this.options.tableRender) {\n            const renderedTableVirtualDOM : (elementNodeType | void) = this.options.tableRender(this.data, newTableVirtualDOM, \"print\")\n            if (renderedTableVirtualDOM) {\n                newTableVirtualDOM = renderedTableVirtualDOM\n            }\n        }\n\n        const diff = this._dd.diff(tableVirtualDOM, newTableVirtualDOM)\n        this._dd.apply(tableDOM, diff)\n\n        // Open new window\n        const w = window.open()\n\n        // Append the table to the body\n        w.document.body.appendChild(tableDOM)\n\n        // Print\n        w.print()\n    }\n\n    /**\n     * Show a message in the table\n     */\n    setMessage(message: string) {\n        const activeHeadings = this.data.headings.filter((heading: headerCellType, index: number) => !this.columns.settings[index]?.hidden)\n        const colspan = activeHeadings.length || 1\n\n        this.options.classes.empty?.split(\" \").forEach(className => this.wrapperDOM.classList.add(className))\n\n        if (this._label) {\n            this._label.innerHTML = \"\"\n        }\n        this.totalPages = 0\n        this._renderPagers()\n\n        let newVirtualDOM : elementNodeType = {\n            nodeName: \"TABLE\",\n            attributes: this._tableAttributes,\n            childNodes: [\n                {\n                    nodeName: \"THEAD\",\n                    childNodes: [\n                        headingsToVirtualHeaderRowDOM(\n                            this.data.headings, this.columns.settings, this.columns._state, this.options, {})\n                    ]\n                },\n                {\n                    nodeName: \"TBODY\",\n                    childNodes: [\n                        {\n                            nodeName: \"TR\",\n                            childNodes: [\n                                {\n                                    nodeName: \"TD\",\n                                    attributes: {\n                                        class: this.options.classes.empty,\n                                        colspan: String(colspan)\n                                    },\n                                    childNodes: [\n                                        {\n                                            nodeName: \"#text\",\n                                            data: message\n                                        }\n                                    ]\n                                }\n                            ]\n                        }\n                    ]\n                }\n\n            ]\n        }\n\n        this._tableFooters.forEach(footer => newVirtualDOM.childNodes.push(footer))\n        this._tableCaptions.forEach(caption => newVirtualDOM.childNodes.push(caption))\n\n        newVirtualDOM.attributes.class = joinWithSpaces(newVirtualDOM.attributes.class, this.options.classes.table)\n\n        if (this.options.tableRender) {\n            const renderedTableVirtualDOM : (elementNodeType | void) = this.options.tableRender(this.data, newVirtualDOM, \"message\")\n            if (renderedTableVirtualDOM) {\n                newVirtualDOM = renderedTableVirtualDOM\n            }\n        }\n\n        const diff = this._dd.diff(this._virtualDOM, newVirtualDOM)\n        this._dd.apply(this.dom, diff)\n        this._virtualDOM = newVirtualDOM\n\n    }\n\n    /**\n     * Add custom event listener\n     */\n    on(event: string, callback: () => void) {\n        this._events[event] = this._events[event] || []\n        this._events[event].push(callback)\n    }\n\n    /**\n     * Remove custom event listener\n     */\n    off(event: string, callback: () => void) {\n        if (event in this._events === false) return\n        this._events[event].splice(this._events[event].indexOf(callback), 1)\n    }\n\n    /**\n     * Fire custom event\n     */\n    emit(event: string, ...args) {\n        if (event in this._events === false) return\n        for (let i = 0; i < this._events[event].length; i++) {\n            this._events[event][i](...args)\n        }\n    }\n}\n","import {\n    isObject\n} from \"../helpers\"\n\ninterface csvConvertUserOptions {\n  lineDelimiter?: string,\n  columnDelimiter?: string\n  removeDoubleQuotes?: boolean\n  data: string,\n  headings?: string[],\n}\n\n\n/**\n * Convert CSV data to fit the format used in the table.\n */\nexport const convertCSV = function(userOptions : csvConvertUserOptions) {\n    let obj\n    const defaults = {\n        lineDelimiter: \"\\n\",\n        columnDelimiter: \",\",\n        removeDoubleQuotes: false\n    }\n\n    // Check for the options object\n    if (!isObject(userOptions)) {\n        return false\n    }\n\n    const options = {\n        ...defaults,\n        ...userOptions\n    }\n\n    if (options.data.length) {\n        // Import CSV\n        obj = {\n            data: []\n        }\n\n        // Split the string into rows\n        const rows : string[] = options.data.split(options.lineDelimiter)\n\n        if (rows.length) {\n\n            if (options.headings) {\n                obj.headings = rows[0].split(options.columnDelimiter)\n                if (options.removeDoubleQuotes) {\n                    obj.headings = obj.headings.map((e: string) => e.trim().replace(/(^\"|\"$)/g, \"\"))\n                }\n                rows.shift()\n            }\n\n            rows.forEach((row: string, i: number) => {\n                obj.data[i] = []\n\n                // Split the rows into values\n                const values = row.split(options.columnDelimiter)\n\n                if (values.length) {\n                    values.forEach((value: string) => {\n                        if (options.removeDoubleQuotes) {\n                            value = value.trim().replace(/(^\"|\"$)/g, \"\")\n                        }\n                        obj.data[i].push(value)\n                    })\n                }\n            })\n        }\n\n        if (obj) {\n            return obj\n        }\n    }\n\n    return false\n}\n","import {\n    isJson,\n    isObject\n} from \"../helpers\"\n\ninterface jsonConvertUserOptions {\n  lineDelimiter?: string,\n  columnDelimiter?: string\n  removeDoubleQuotes?: boolean\n  data: string,\n  headings?: string[],\n}\n\n/**\n * Convert JSON data to fit the format used in the table.\n */\nexport const convertJSON = function(userOptions : jsonConvertUserOptions) {\n    let obj\n    const defaults = {\n        data: \"\"\n    }\n\n    // Check for the options object\n    if (!isObject(userOptions)) {\n        return false\n    }\n\n    const options = {\n        ...defaults,\n        ...userOptions\n    }\n\n    if (options.data.length || isObject(options.data)) {\n        // Import JSON\n        const json = isJson(options.data) ? JSON.parse(options.data) : false\n\n        // Valid JSON string\n        if (json) {\n            obj = {\n                headings: [],\n                data: []\n            }\n\n            json.forEach((data: { [key: string]: string | number | boolean | null | undefined}, i: number) => {\n                obj.data[i] = []\n                Object.entries(data).forEach(([column, value]) => {\n                    if (!obj.headings.includes(column)) {\n                        obj.headings.push(column)\n                    }\n                    obj.data[i].push(value)\n                })\n            })\n        } else {\n            console.warn(\"That's not valid JSON!\")\n        }\n\n        if (obj) {\n            return obj\n        }\n    }\n\n    return false\n}\n","import {\n    cellToText,\n    isObject\n} from \"../helpers\"\nimport {DataTable} from \"../datatable\"\nimport {\n    cellDataType,\n    cellType,\n    dataRowType,\n    headerCellType\n} from \"../types\"\n\n/**\n * Export table to CSV\n */\n\ninterface csvUserOptions {\n  download?: boolean,\n  skipColumn?: number[],\n  lineDelimiter?: string,\n  columnDelimiter?: string,\n  selection?: number | number[],\n  filename?: string,\n}\n\n\nexport const exportCSV = function(dt: DataTable, userOptions: csvUserOptions = {}) {\n    if (!dt.hasHeadings && !dt.hasRows) return false\n\n    const defaults = {\n        download: true,\n        skipColumn: [],\n        lineDelimiter: \"\\n\",\n        columnDelimiter: \",\"\n    }\n\n    // Check for the options object\n    if (!isObject(userOptions)) {\n        return false\n    }\n\n    const options = {\n        ...defaults,\n        ...userOptions\n    }\n    const columnShown = (index: number) => !options.skipColumn.includes(index) && !dt.columns.settings[index]?.hidden\n    const headers = dt.data.headings.filter((_heading: headerCellType, index: number) => columnShown(index)).map((header: headerCellType) => header.text ?? header.data)\n\n    // Selection or whole table\n    let selectedRows: dataRowType[]\n    if (options.selection) {\n        // Page number\n        if (Array.isArray(options.selection)) {\n            // Array of page numbers\n            selectedRows = []\n            for (let i = 0; i < options.selection.length; i++) {\n                selectedRows = selectedRows.concat(dt.pages[options.selection[i] - 1].map(row => row.row))\n            }\n\n        } else {\n            selectedRows = dt.pages[options.selection - 1].map(row => row.row)\n        }\n    } else {\n        selectedRows = dt.data.data\n    }\n\n    let rows : cellDataType[][] = []\n    // Include headings\n    rows[0] = headers\n    rows = rows.concat(selectedRows.map((row: dataRowType) => {\n        const shownCells = row.cells.filter((_cell: cellType, index: number) => columnShown(index))\n        return shownCells.map((cell: cellType) => cellToText(cell))\n    }))\n\n    // Only proceed if we have data\n    if (rows.length) {\n        let str = \"\"\n        rows.forEach(row => {\n            row.forEach((cell: cellDataType) => {\n                if (typeof cell === \"string\") {\n                    cell = cell.trim()\n                    cell = cell.replace(/\\s{2,}/g, \" \")\n                    cell = cell.replace(/\\n/g, \"  \")\n                    cell = cell.replace(/\"/g, \"\\\"\\\"\")\n                    //have to manually encode \"#\" as encodeURI leaves it as is.\n                    cell = cell.replace(/#/g, \"%23\")\n                    if (cell.includes(\",\")) {\n                        cell = `\"${cell}\"`\n                    }\n                }\n                str += cell + options.columnDelimiter\n            })\n            // Remove trailing column delimiter\n            str = str.trim().substring(0, str.length - 1)\n\n            // Apply line delimiter\n            str += options.lineDelimiter\n        })\n\n        // Remove trailing line delimiter\n        str = str.trim().substring(0, str.length - 1)\n\n        // Download\n        if (options.download) {\n            // Create a link to trigger the download\n            const link = document.createElement(\"a\")\n            link.href = encodeURI(`data:text/csv;charset=utf-8,${str}`)\n            link.download = `${options.filename || \"datatable_export\"}.csv`\n\n            // Append the link\n            document.body.appendChild(link)\n\n            // Trigger the download\n            link.click()\n\n            // Remove the link\n            document.body.removeChild(link)\n        }\n\n        return str\n    }\n\n    return false\n}\n","import {\n    cellToText,\n    isObject\n} from \"../helpers\"\nimport {DataTable} from \"../datatable\"\nimport {\n    cellDataType,\n    cellType,\n    dataRowType,\n    headerCellType\n} from \"../types\"\n/**\n * Export table to JSON\n */\n\n interface jsonUserOptions {\n   download?: boolean,\n   skipColumn?: number[],\n   replacer?: null | ((key, value) => string) | (string | number)[],\n   space?: number,\n   selection?: number | number[],\n   filename?: string,\n }\n\n\nexport const exportJSON = function(dt: DataTable, userOptions: jsonUserOptions = {}) {\n    if (!dt.hasHeadings && !dt.hasRows) return false\n\n\n    const defaults = {\n        download: true,\n        skipColumn: [],\n        replacer: null,\n        space: 4\n    }\n\n    // Check for the options object\n    if (!isObject(userOptions)) {\n        return false\n    }\n\n    const options = {\n        ...defaults,\n        ...userOptions\n    }\n\n    const columnShown = (index: number) => !options.skipColumn.includes(index) && !dt.columns.settings[index]?.hidden\n\n    // Selection or whole table\n    let selectedRows: dataRowType[]\n    if (options.selection) {\n        // Page number\n        if (Array.isArray(options.selection)) {\n            // Array of page numbers\n            selectedRows = []\n            for (let i = 0; i < options.selection.length; i++) {\n                selectedRows = selectedRows.concat(dt.pages[options.selection[i] - 1].map(row => row.row))\n            }\n        } else {\n            selectedRows = dt.pages[options.selection - 1].map(row => row.row)\n        }\n    } else {\n        selectedRows = dt.data.data\n    }\n\n    const rows: cellDataType[][] = selectedRows.map((row: dataRowType) => {\n        const shownCells = row.cells.filter((_cell: cellType, index: number) => columnShown(index))\n        return shownCells.map((cell: cellType) => cellToText(cell))\n    })\n\n    const headers = dt.data.headings.filter((_heading: headerCellType, index: number) => columnShown(index)).map((header: headerCellType) => header.text ?? String(header.data))\n\n    // Only proceed if we have data\n    if (rows.length) {\n        const arr: (void | { [key: string]: cellDataType})[] = []\n        rows.forEach((row: cellDataType[], x: number) => {\n            arr[x] = arr[x] || {}\n            row.forEach((cell: cellDataType, i: number) => {\n                arr[x][headers[i]] = cell\n            })\n        })\n\n        // Convert the array of objects to JSON string\n        const str = JSON.stringify(arr, options.replacer, options.space)\n\n        // Download\n        if (options.download) {\n            // Create a link to trigger the download\n\n            const blob = new Blob(\n                [str],\n                {\n                    type: \"data:application/json;charset=utf-8\"\n                }\n            )\n            const url = URL.createObjectURL(blob)\n\n\n            const link = document.createElement(\"a\")\n            link.href = url\n            link.download = `${options.filename || \"datatable_export\"}.json`\n\n            // Append the link\n            document.body.appendChild(link)\n\n            // Trigger the download\n            link.click()\n\n            // Remove the link\n            document.body.removeChild(link)\n            URL.revokeObjectURL(url)\n        }\n\n        return str\n    }\n\n    return false\n}\n","import {\n    cellToText,\n    isObject\n} from \"../helpers\"\nimport {DataTable} from \"../datatable\"\nimport {\n    cellDataType,\n    cellType,\n    dataRowType,\n    headerCellType\n} from \"../types\"\n/**\n * Export table to SQL\n */\n\n interface sqlUserOptions {\n   download?: boolean,\n   skipColumn?: number[],\n   tableName?: string,\n   selection?: number | number[],\n   filename?: string,\n }\n\nexport const exportSQL = function(dt: DataTable, userOptions : sqlUserOptions = {}) {\n    if (!dt.hasHeadings && !dt.hasRows) return false\n\n    const defaults = {\n        download: true,\n        skipColumn: [],\n        tableName: \"myTable\"\n    }\n\n    // Check for the options object\n    if (!isObject(userOptions)) {\n        return false\n    }\n\n    const options = {\n        ...defaults,\n        ...userOptions\n    }\n    const columnShown = (index: number) => !options.skipColumn.includes(index) && !dt.columns.settings[index]?.hidden\n\n    // Selection or whole table\n    let selectedRows: dataRowType[] = []\n    if (options.selection) {\n        // Page number\n        if (Array.isArray(options.selection)) {\n            // Array of page numbers\n            for (let i = 0; i < options.selection.length; i++) {\n                selectedRows = selectedRows.concat(dt.pages[options.selection[i] - 1].map(row => row.row))\n            }\n\n        } else {\n            selectedRows = dt.pages[options.selection - 1].map(row => row.row)\n        }\n    } else {\n        selectedRows = dt.data.data\n    }\n\n    const rows: cellDataType[][] = selectedRows.map((row: dataRowType) => {\n        const shownCells = row.cells.filter((_cell: cellType, index: number) => columnShown(index))\n        return shownCells.map((cell: cellType) => cellToText(cell))\n    })\n\n    const headers = dt.data.headings.filter((_heading: headerCellType, index: number) => columnShown(index)).map((header: headerCellType) => header.text ?? String(header.data))\n    // Only proceed if we have data\n    if (rows.length) {\n        // Begin INSERT statement\n        let str = `INSERT INTO \\`${options.tableName}\\` (`\n\n        // Convert table headings to column names\n        headers.forEach((header: string) => {\n            str += `\\`${header}\\`,`\n        })\n\n        // Remove trailing comma\n        str = str.trim().substring(0, str.length - 1)\n\n        // Begin VALUES\n        str += \") VALUES \"\n\n        // Iterate rows and convert cell data to column values\n\n        rows.forEach((row: cellDataType[]) => {\n            str += \"(\"\n            row.forEach((cell: cellDataType) => {\n                if (typeof cell === \"string\") {\n                    str += `\"${cell}\",`\n                } else {\n                    str += `${cell},`\n                }\n            })\n            // Remove trailing comma\n            str = str.trim().substring(0, str.length - 1)\n\n            // end VALUES\n            str += \"),\"\n\n        })\n\n        // Remove trailing comma\n        str = str.trim().substring(0, str.length - 1)\n\n        // Add trailing colon\n        str += \";\"\n\n        if (options.download) {\n            str = `data:application/sql;charset=utf-8,${str}`\n        }\n\n        // Download\n        if (options.download) {\n            // Create a link to trigger the download\n            const link = document.createElement(\"a\")\n            link.href = encodeURI(str)\n            link.download = `${options.filename || \"datatable_export\"}.sql`\n\n            // Append the link\n            document.body.appendChild(link)\n\n            // Trigger the download\n            link.click()\n\n            // Remove the link\n            document.body.removeChild(link)\n        }\n\n        return str\n    }\n\n    return false\n}\n","import {\n    cellToText,\n    isObject\n} from \"../helpers\"\nimport {DataTable} from \"../datatable\"\nimport {\n    cellDataType,\n    cellType,\n    dataRowType,\n    headerCellType\n} from \"../types\"\n/**\n * Export table to TXT\n */\n interface txtUserOptions {\n   download?: boolean,\n   skipColumn?: number[],\n   lineDelimiter?: string,\n   columnDelimiter?: string,\n   selection?: number | number[],\n   filename?: string,\n }\n\n\nexport const exportTXT = function(dt: DataTable, userOptions : txtUserOptions = {}) {\n    if (!dt.hasHeadings && !dt.hasRows) return false\n\n    const defaults = {\n        download: true,\n        skipColumn: [],\n        lineDelimiter: \"\\n\",\n        columnDelimiter: \",\"\n    }\n\n    // Check for the options object\n    if (!isObject(userOptions)) {\n        return false\n    }\n\n    const options = {\n        ...defaults,\n        ...userOptions\n    }\n\n    const columnShown = (index: number) => !options.skipColumn.includes(index) && !dt.columns.settings[index]?.hidden\n\n    const headers = dt.data.headings.filter((_heading: headerCellType, index: number) => columnShown(index)).map((header: headerCellType) => header.text ?? header.data)\n\n    // Selection or whole table\n    let selectedRows: dataRowType[]\n    if (options.selection) {\n        // Page number\n        if (Array.isArray(options.selection)) {\n            // Array of page numbers\n            selectedRows = []\n            for (let i = 0; i < options.selection.length; i++) {\n                selectedRows = selectedRows.concat(dt.pages[options.selection[i] - 1].map(row => row.row))\n            }\n        } else {\n            selectedRows = dt.pages[options.selection - 1].map(row => row.row)\n        }\n    } else {\n        selectedRows = dt.data.data\n    }\n\n    let rows : cellDataType[][] = []\n    // Include headings\n    rows[0] = headers\n    rows = rows.concat(selectedRows.map((row: dataRowType) => {\n        const shownCells = row.cells.filter((_cell: cellType, index: number) => columnShown(index))\n        return shownCells.map((cell: cellType) => cellToText(cell))\n    }))\n\n    // Only proceed if we have data\n    if (rows.length) {\n        let str = \"\"\n\n        rows.forEach(row => {\n            row.forEach((cell: cellDataType) => {\n                if (typeof cell === \"string\") {\n                    cell = cell.trim()\n                    cell = cell.replace(/\\s{2,}/g, \" \")\n                    cell = cell.replace(/\\n/g, \"  \")\n                    cell = cell.replace(/\"/g, \"\\\"\\\"\")\n                    //have to manually encode \"#\" as encodeURI leaves it as is.\n                    cell = cell.replace(/#/g, \"%23\")\n                    if (cell.includes(\",\")) {\n                        cell = `\"${cell}\"`\n                    }\n                }\n                str += cell + options.columnDelimiter\n            })\n            // Remove trailing column delimiter\n            str = str.trim().substring(0, str.length - 1)\n\n            // Apply line delimiter\n            str += options.lineDelimiter\n\n        })\n\n        // Remove trailing line delimiter\n        str = str.trim().substring(0, str.length - 1)\n\n        if (options.download) {\n            str = `data:text/csv;charset=utf-8,${str}`\n        }\n        // Download\n        if (options.download) {\n            // Create a link to trigger the download\n            const link = document.createElement(\"a\")\n            link.href = encodeURI(str)\n            link.download = `${options.filename || \"datatable_export\"}.txt`\n\n            // Append the link\n            document.body.appendChild(link)\n\n            // Trigger the download\n            link.click()\n\n            // Remove the link\n            document.body.removeChild(link)\n        }\n\n        return str\n    }\n\n    return false\n}\n","/**\n* Default config\n* @type {Object}\n*/\nimport {Editor} from \"./editor\"\n\nexport const defaultConfig = {\n    classes: {\n        row: \"datatable-editor-row\",\n        form: \"datatable-editor-form\",\n        item: \"datatable-editor-item\",\n        menu: \"datatable-editor-menu\",\n        save: \"datatable-editor-save\",\n        block: \"datatable-editor-block\",\n        cancel: \"datatable-editor-cancel\",\n        close: \"datatable-editor-close\",\n        inner: \"datatable-editor-inner\",\n        input: \"datatable-editor-input\",\n        label: \"datatable-editor-label\",\n        modal: \"datatable-editor-modal\",\n        action: \"datatable-editor-action\",\n        header: \"datatable-editor-header\",\n        wrapper: \"datatable-editor-wrapper\",\n        editable: \"datatable-editor-editable\",\n        container: \"datatable-editor-container\",\n        separator: \"datatable-editor-separator\"\n    },\n\n    labels: {\n        closeX: \"x\",\n        editCell: \"Edit Cell\",\n        editRow: \"Edit Row\",\n        removeRow: \"Remove Row\",\n        reallyRemove: \"Are you sure?\",\n        reallyCancel: \"Do you really want to cancel?\",\n        save: \"Save\",\n        cancel: \"Cancel\"\n    },\n\n    cancelModal: editor => confirm(editor.options.labels.reallyCancel),\n\n    // edit inline instead of using a modal lay-over for editing content\n    inline: true,\n\n    // include hidden columns in the editor\n    hiddenColumns: false,\n\n    // enable the context menu\n    contextMenu: true,\n\n    // event to start editing\n    clickEvent: \"dblclick\",\n\n    // indexes of columns not to be edited\n    excludeColumns: [],\n\n    // set the context menu items\n    menuItems: [\n        {\n            text: (editor: Editor) => editor.options.labels.editCell,\n            action: (editor: Editor, _event: Event) => {\n                if (!(editor.event.target instanceof Element)) {\n                    return\n                }\n                const cell = editor.event.target.closest(\"td\")\n                return editor.editCell(cell)\n            }\n        },\n        {\n            text: (editor: Editor) => editor.options.labels.editRow,\n            action: (editor: Editor, _event: Event) => {\n                if (!(editor.event.target instanceof Element)) {\n                    return\n                }\n                const row = editor.event.target.closest(\"tr\")\n                return editor.editRow(row)\n            }\n        },\n        {\n            separator: true\n        },\n        {\n            text: (editor: Editor) => editor.options.labels.removeRow,\n            action: (editor: Editor, _event: Event) => {\n                if (!(editor.event.target instanceof Element)) {\n                    return\n                }\n                if (confirm(editor.options.labels.reallyRemove)) {\n                    const row = editor.event.target.closest(\"tr\")\n                    editor.removeRow(row)\n                }\n            }\n        }\n    ]\n}\n","import {\n    classNamesToSelector,\n    cellToText,\n    columnToVisibleIndex,\n    createElement,\n    escapeText,\n    visibleToColumnIndex\n} from \"../helpers\"\nimport {\n    cellType,\n    rowRenderType,\n    elementNodeType\n} from \"../types\"\nimport {DataTable} from \"../datatable\"\nimport {parseDate} from \"../date\"\n\nimport {\n    defaultConfig\n} from \"./config\"\nimport {\n    debounce\n} from \"./helpers\"\nimport {menuItemType, dataType, EditorOptions} from \"./types\"\n\n\n/**\n * Main lib\n * @param {Object} dataTable Target dataTable\n * @param {Object} options User config\n */\nexport class Editor {\n    menuOpen: boolean\n\n    containerDOM: HTMLElement\n\n    data: dataType\n\n    disabled: boolean\n\n    dt: DataTable\n\n    editing: boolean\n\n    editingCell: boolean\n\n    editingRow: boolean\n\n    event: Event\n\n    events: { [key: string]: () => void}\n\n    initialized: boolean\n\n    limits: {x: number, y: number}\n\n    menuDOM: HTMLElement\n\n    modalDOM: HTMLElement | false\n\n    options: EditorOptions\n\n    originalRowRender: rowRenderType | false\n\n    rect: {width: number, height: number}\n\n    wrapperDOM: HTMLElement\n\n    constructor(dataTable: DataTable, options = {}) {\n        this.dt = dataTable\n        this.options = {\n            ...defaultConfig,\n            ...options\n        }\n    }\n\n    /**\n     * Init instance\n     * @return {Void}\n     */\n    init() {\n        if (this.initialized) {\n            return\n        }\n        this.options.classes.editable?.split(\" \").forEach(className => this.dt.wrapperDOM.classList.add(className))\n        if (this.options.inline) {\n            this.originalRowRender = this.dt.options.rowRender\n            this.dt.options.rowRender = (row, tr, index) => {\n                let newTr = this.rowRender(row, tr, index)\n                if (this.originalRowRender) {\n                    newTr = this.originalRowRender(row, newTr, index)\n                }\n                return newTr\n            }\n        }\n        if (this.options.contextMenu) {\n            this.containerDOM = createElement(\"div\", {\n                id: this.options.classes.container\n            })\n            this.wrapperDOM = createElement(\"div\", {\n                class: this.options.classes.wrapper\n            })\n            this.menuDOM = createElement(\"ul\", {\n                class: this.options.classes.menu\n            })\n            if (this.options.menuItems && this.options.menuItems.length) {\n                this.options.menuItems.forEach((item: menuItemType) => {\n                    const li = createElement(\"li\", {\n                        class: item.separator ? this.options.classes.separator : this.options.classes.item\n                    })\n                    if (!item.separator) {\n                        const a = createElement(\"a\", {\n                            class: this.options.classes.action,\n                            href: item.url || \"#\",\n                            html: typeof item.text === \"function\" ? item.text(this) : item.text\n                        })\n                        li.appendChild(a)\n                        if (item.action && typeof item.action === \"function\") {\n                            a.addEventListener(\"click\", (event: Event) => {\n                                event.preventDefault()\n                                item.action(this, event)\n                            })\n                        }\n                    }\n                    this.menuDOM.appendChild(li)\n                })\n            }\n            this.wrapperDOM.appendChild(this.menuDOM)\n            this.containerDOM.appendChild(this.wrapperDOM)\n            this.updateMenu()\n        }\n        this.data = {}\n        this.menuOpen = false\n        this.editing = false\n        this.editingRow = false\n        this.editingCell = false\n        this.bindEvents()\n        setTimeout(() => {\n            this.initialized = true\n            this.dt.emit(\"editable.init\")\n        }, 10)\n    }\n\n    /**\n     * Bind events to DOM\n     * @return {Void}\n     */\n    bindEvents() {\n        this.events = {\n            keydown: this.keydown.bind(this),\n            click: this.click.bind(this)\n        }\n        // listen for click / double-click\n        this.dt.dom.addEventListener(this.options.clickEvent, this.events.click)\n        // listen for right-click\n        document.addEventListener(\"keydown\", this.events.keydown)\n\n        if (this.options.contextMenu) {\n            this.events.context = this.context.bind(this)\n            this.events.updateMenu = this.updateMenu.bind(this)\n            this.events.dismissMenu = this.dismissMenu.bind(this)\n            this.events.reset = debounce(() => this.events.updateMenu(), 50)\n\n            // listen for right-click\n            this.dt.dom.addEventListener(\"contextmenu\", this.events.context)\n            // listen for click everywhere except the menu\n            document.addEventListener(\"click\", this.events.dismissMenu)\n            // Reset contextmenu on browser window changes\n            window.addEventListener(\"resize\", this.events.reset)\n            window.addEventListener(\"scroll\", this.events.reset)\n        }\n    }\n\n    /**\n     * contextmenu listener\n     * @param  {Object} event Event\n     * @return {Void}\n     */\n    context(event: MouseEvent) {\n        const target = event.target\n        if (!(target instanceof Element)) {\n            return\n        }\n        this.event = event\n\n        const cell = target.closest(\"tbody td\")\n        if (!this.disabled && cell) {\n            event.preventDefault()\n            // get the mouse position\n            let x = event.pageX\n            let y = event.pageY\n            // check if we're near the right edge of window\n            if (x > this.limits.x) {\n                x -= this.rect.width\n            }\n            // check if we're near the bottom edge of window\n            if (y > this.limits.y) {\n                y -= this.rect.height\n            }\n            this.wrapperDOM.style.top = `${y}px`\n            this.wrapperDOM.style.left = `${x}px`\n            this.openMenu()\n            this.updateMenu()\n        }\n    }\n\n    /**\n     * dblclick listener\n     * @param  {Object} event Event\n     * @return {Void}\n     */\n    click(event: MouseEvent) {\n        const target = event.target\n        if (!(target instanceof Element)) {\n            return\n        }\n        if (this.editing && this.data && this.editingCell) {\n            const inputSelector = classNamesToSelector(this.options.classes.input)\n            const input = this.modalDOM ?\n                (this.modalDOM.querySelector(`input${inputSelector}[type=text]`) as HTMLInputElement) :\n                (this.dt.wrapperDOM.querySelector(`input${inputSelector}[type=text]`) as HTMLInputElement)\n            this.saveCell(input.value)\n        } else if (!this.editing) {\n            const cell = target.closest(\"tbody td\") as HTMLTableCellElement\n            if (cell) {\n                this.editCell(cell)\n                event.preventDefault()\n            }\n        }\n    }\n\n    /**\n     * keydown listener\n     * @param  {Object} event Event\n     * @return {Void}\n     */\n    keydown(event: KeyboardEvent) {\n        const inputSelector = classNamesToSelector(this.options.classes.input)\n        if (this.modalDOM) {\n            if (event.key === \"Escape\") { // close button\n                if (this.options.cancelModal(this)) {\n                    this.closeModal()\n                }\n            } else if (event.key === \"Enter\") { // save button\n                // Save\n                if (this.editingCell) {\n                    const input = (this.modalDOM.querySelector(`input${inputSelector}[type=text]`) as HTMLInputElement)\n                    this.saveCell(input.value)\n                } else {\n                    const values = (Array.from(this.modalDOM.querySelectorAll(`input${inputSelector}[type=text]`)) as HTMLInputElement[]).map(input => input.value.trim())\n                    this.saveRow(values, this.data.row)\n                }\n            }\n        } else if (this.editing && this.data) {\n            if (event.key === \"Enter\") {\n                // Enter key saves\n                if (this.editingCell) {\n                    const input = (this.dt.wrapperDOM.querySelector(`input${inputSelector}[type=text]`) as HTMLInputElement)\n                    this.saveCell(input.value)\n                } else if (this.editingRow) {\n                    const values = (Array.from(this.dt.wrapperDOM.querySelectorAll(`input${inputSelector}[type=text]`)) as HTMLInputElement[]).map(input => input.value.trim())\n                    this.saveRow(values, this.data.row)\n                }\n            } else if (event.key === \"Escape\") {\n                // Escape key reverts\n                if (this.editingCell) {\n                    this.saveCell(this.data.content)\n                } else if (this.editingRow) {\n                    this.saveRow(null, this.data.row)\n                }\n            }\n        }\n    }\n\n    /**\n     * Edit cell\n     * @param  {Object} td    The HTMLTableCellElement\n     * @return {Void}\n     */\n    editCell(td: HTMLTableCellElement) {\n        const columnIndex = visibleToColumnIndex(td.cellIndex, this.dt.columns.settings)\n        if (this.options.excludeColumns.includes(columnIndex)) {\n            this.closeMenu()\n            return\n        }\n        const rowIndex = parseInt(td.parentElement.dataset.index, 10)\n        const row = this.dt.data.data[rowIndex]\n        const cell = row.cells[columnIndex]\n\n        this.data = {\n            cell,\n            rowIndex,\n            columnIndex,\n            content: cellToText(cell)\n        }\n        this.editing = true\n        this.editingCell = true\n        if (this.options.inline) {\n            this.dt.update()\n        } else {\n            this.editCellModal()\n        }\n        this.closeMenu()\n    }\n\n    editCellModal() {\n        const cell = this.data.cell\n        const columnIndex = this.data.columnIndex\n        const label = this.dt.data.headings[columnIndex].text || String(this.dt.data.headings[columnIndex].data)\n        const template = [\n            `<div class='${this.options.classes.inner}'>`,\n            `<div class='${this.options.classes.header}'>`,\n            `<h4>${this.options.labels.editCell}</h4>`,\n            `<button class='${this.options.classes.close}' type='button' data-editor-cancel>${this.options.labels.closeX}</button>`,\n            \" </div>\",\n            `<div class='${this.options.classes.block}'>`,\n            `<form class='${this.options.classes.form}'>`,\n            `<div class='${this.options.classes.row}'>`,\n            `<label class='${this.options.classes.label}'>${escapeText(label)}</label>`,\n            `<input class='${this.options.classes.input}' value='${escapeText(cellToText(cell))}' type='text'>`,\n            \"</div>\",\n            `<div class='${this.options.classes.row}'>`,\n            `<button class='${this.options.classes.cancel}' type='button' data-editor-cancel>${this.options.labels.cancel}</button>`,\n            `<button class='${this.options.classes.save}' type='button' data-editor-save>${this.options.labels.save}</button>`,\n            \"</div>\",\n            \"</form>\",\n            \"</div>\",\n            \"</div>\"\n        ].join(\"\")\n        const modalDOM = createElement(\"div\", {\n            class: this.options.classes.modal,\n            html: template\n        })\n        this.modalDOM = modalDOM\n        this.openModal()\n        const inputSelector = classNamesToSelector(this.options.classes.input)\n        const input = (modalDOM.querySelector(`input${inputSelector}[type=text]`) as HTMLInputElement)\n        input.focus()\n        input.selectionStart = input.selectionEnd = input.value.length\n        // Close / save\n        modalDOM.addEventListener(\"click\", (event: Event) => {\n            const target = event.target\n            if (!(target instanceof Element)) {\n                return\n            }\n            if (target.hasAttribute(\"data-editor-cancel\")) { // cancel button\n                event.preventDefault()\n                if (this.options.cancelModal(this)) {\n                    this.closeModal()\n                }\n            } else if (target.hasAttribute(\"data-editor-save\")) { // save button\n                event.preventDefault()\n                // Save\n                this.saveCell(input.value)\n            }\n        })\n    }\n\n    /**\n     * Save edited cell\n     * @param  {Object} row    The HTMLTableCellElement\n     * @param  {String} value   Cell content\n     * @return {Void}\n     */\n    saveCell(value: string) {\n        const oldData = this.data.content\n        // Get the type of that column\n        const type = this.dt.columns.settings[this.data.columnIndex].type || this.dt.options.type\n        const stringValue = value.trim()\n        let cell\n        if (type === \"number\") {\n            cell = {data: parseFloat(stringValue)}\n        } else if (type === \"boolean\") {\n            if ([\"\", \"false\", \"0\"].includes(stringValue)) {\n                cell = {data: false,\n                    text: \"false\",\n                    order: 0}\n            } else {\n                cell = {data: true,\n                    text: \"true\",\n                    order: 1}\n            }\n        } else if (type === \"html\") {\n            cell = {data: [\n                {nodeName: \"#text\",\n                    data: value}\n            ],\n            text: value,\n            order: value}\n        } else if (type === \"string\") {\n            cell = {data: value}\n        } else if (type === \"date\") {\n            const format = this.dt.columns.settings[this.data.columnIndex].format || this.dt.options.format\n            cell = {data: value,\n                order: parseDate(String(value), format)}\n        } else {\n            cell = {data: value}\n        }\n        // Set the cell content\n        const row = this.dt.data.data[this.data.rowIndex]\n        row.cells[this.data.columnIndex] = cell\n        this.closeModal()\n        const rowIndex = this.data.rowIndex\n        const columnIndex = this.data.columnIndex\n        this.data = {}\n        this.dt.update(true)\n        this.editing = false\n        this.editingCell = false\n        this.dt.emit(\"editable.save.cell\", value, oldData, rowIndex, columnIndex)\n    }\n\n    /**\n     * Edit row\n     * @param  {Object} row    The HTMLTableRowElement\n     * @return {Void}\n     */\n    editRow(tr: HTMLElement) {\n        if (!tr || tr.nodeName !== \"TR\" || this.editing) return\n        const rowIndex = parseInt(tr.dataset.index, 10)\n        const row = this.dt.data.data[rowIndex]\n        this.data = {\n            row: row.cells,\n            rowIndex\n        }\n        this.editing = true\n        this.editingRow = true\n        if (this.options.inline) {\n            this.dt.update()\n        } else {\n            this.editRowModal()\n        }\n        this.closeMenu()\n    }\n\n    editRowModal() {\n        const row = this.data.row\n\n        const template = [\n            `<div class='${this.options.classes.inner}'>`,\n            `<div class='${this.options.classes.header}'>`,\n            `<h4>${this.options.labels.editRow}</h4>`,\n            `<button class='${this.options.classes.close}' type='button' data-editor-cancel>${this.options.labels.closeX}</button>`,\n            \" </div>\",\n            `<div class='${this.options.classes.block}'>`,\n            `<form class='${this.options.classes.form}'>`,\n            `<div class='${this.options.classes.row}'>`,\n            `<button class='${this.options.classes.cancel}' type='button' data-editor-cancel>${this.options.labels.cancel}</button>`,\n            `<button class='${this.options.classes.save}' type='button' data-editor-save>${this.options.labels.save}</button>`,\n            \"</div>\",\n            \"</form>\",\n            \"</div>\",\n            \"</div>\"\n        ].join(\"\")\n        const modalDOM = createElement(\"div\", {\n            class: this.options.classes.modal,\n            html: template\n        })\n        const inner = modalDOM.firstElementChild\n        if (!inner) {\n            return\n        }\n        const form = inner.lastElementChild?.firstElementChild\n        if (!form) {\n            return\n        }\n        // Add the inputs for each cell\n        row.forEach((cell: cellType, i: number) => {\n            const columnSettings = this.dt.columns.settings[i]\n            if ((!columnSettings.hidden || (columnSettings.hidden && this.options.hiddenColumns)) && !this.options.excludeColumns.includes(i)) {\n                const label = this.dt.data.headings[i].text || String(this.dt.data.headings[i].data)\n                form.insertBefore(createElement(\"div\", {\n                    class: this.options.classes.row,\n                    html: [\n                        `<div class='${this.options.classes.row}'>`,\n                        `<label class='${this.options.classes.label}'>${escapeText(label)}</label>`,\n                        `<input class='${this.options.classes.input}' value='${escapeText(cellToText(cell))}' type='text'>`,\n                        \"</div>\"\n                    ].join(\"\")\n                }), form.lastElementChild)\n            }\n        })\n        this.modalDOM = modalDOM\n        this.openModal()\n        // Grab the inputs\n        const inputSelector = classNamesToSelector(this.options.classes.input)\n        const inputs = Array.from(form.querySelectorAll(`input${inputSelector}[type=text]`)) as HTMLInputElement[]\n\n        // Close / save\n        modalDOM.addEventListener(\"click\", (event: MouseEvent) => {\n            const target = event.target\n            if (!(target instanceof Element)) {\n                return\n            }\n            if (target.hasAttribute(\"data-editor-cancel\")) { // cancel button\n                if (this.options.cancelModal(this)) {\n                    this.closeModal()\n                }\n            } else if (target.hasAttribute(\"data-editor-save\")) { // save button\n                // Save\n                const values = inputs.map((input: HTMLInputElement) => input.value.trim())\n                this.saveRow(values, this.data.row)\n            }\n        })\n    }\n\n    /**\n     * Save edited row\n     * @param  {Object} row    The HTMLTableRowElement\n     * @param  {Array} data   Cell data\n     * @return {Void}\n     */\n    saveRow(data: string[], row: cellType[]) {\n        // Store the old data for the emitter\n        const oldData = row.map((cell: cellType) => cellToText(cell))\n        const updatedRow = this.dt.data.data[this.data.rowIndex]\n\n        if (data) {\n            let valueCounter = 0\n            updatedRow.cells = row.map((oldItem, colIndex) => {\n                if (this.options.excludeColumns.includes(colIndex) || this.dt.columns.settings[colIndex].hidden) {\n                    return oldItem\n                }\n                const type = this.dt.columns.settings[colIndex].type || this.dt.options.type\n                const value = data[valueCounter++]\n                let cell\n                if (type === \"number\") {\n                    cell = {data: parseFloat(value)}\n                } else if (type === \"boolean\") {\n                    if ([\"\", \"false\", \"0\"].includes(value)) {\n                        cell = {data: false,\n                            text: \"false\",\n                            order: 0}\n                    } else {\n                        cell = {data: true,\n                            text: \"true\",\n                            order: 1}\n                    }\n                } else if (type === \"html\") {\n                    cell = {\n                        data: [\n                            {nodeName: \"#text\",\n                                data: value}\n                        ],\n                        text: value,\n                        order: value\n                    }\n                } else if (type === \"string\") {\n                    cell = {data: value}\n                } else if (type === \"date\") {\n                    const format = this.dt.columns.settings[colIndex].format || this.dt.options.format\n                    cell = {data: value,\n                        order: parseDate(String(value), format)}\n                } else {\n                    cell = {data: value}\n                }\n                return cell\n\n            })\n        }\n\n        const newData = updatedRow.cells.map(cell => cellToText(cell))\n\n        this.data = {}\n        this.dt.update(true)\n        this.closeModal()\n        this.editing = false\n        this.dt.emit(\"editable.save.row\", newData, oldData, row)\n    }\n\n    /**\n     * Open the row editor modal\n     * @return {Void}\n     */\n    openModal() {\n        if (this.modalDOM) {\n            document.body.appendChild(this.modalDOM)\n        }\n    }\n\n    /**\n     * Close the row editor modal\n     * @return {Void}\n     */\n    closeModal() {\n        if (this.editing && this.modalDOM) {\n            document.body.removeChild(this.modalDOM)\n            this.modalDOM = this.editing = this.editingRow = this.editingCell = false\n        }\n    }\n\n    /**\n     * Remove a row\n     * @param  {Object} tr The HTMLTableRowElement\n     * @return {Void}\n     */\n    removeRow(tr: HTMLElement) {\n        if (!tr || tr.nodeName !== \"TR\" || this.editing) return\n        const index = parseInt(tr.dataset.index, 10)\n        this.dt.rows.remove(index)\n        this.closeMenu()\n    }\n\n    /**\n     * Update context menu position\n     * @return {Void}\n     */\n    updateMenu() {\n        const scrollX = window.scrollX || window.pageXOffset\n        const scrollY = window.scrollY || window.pageYOffset\n        this.rect = this.wrapperDOM.getBoundingClientRect()\n        this.limits = {\n            x: window.innerWidth + scrollX - this.rect.width,\n            y: window.innerHeight + scrollY - this.rect.height\n        }\n    }\n\n    /**\n     * Dismiss the context menu\n     * @param  {Object} event Event\n     * @return {Void}\n     */\n    dismissMenu(event: Event) {\n        const target = event.target\n        if (!(target instanceof Element) || this.wrapperDOM.contains(target)) {\n            return\n        }\n        let valid = true\n        if (this.editing) {\n            const inputSelector = classNamesToSelector(this.options.classes.input)\n            valid = !(target.matches(`input${inputSelector}[type=text]`))\n        }\n        if (valid) {\n            this.closeMenu()\n        }\n    }\n\n    /**\n     * Open the context menu\n     * @return {Void}\n     */\n    openMenu() {\n        if (this.editing && this.data && this.editingCell) {\n            const inputSelector = classNamesToSelector(this.options.classes.input)\n            const input = this.modalDOM ?\n                (this.modalDOM.querySelector(`input${inputSelector}[type=text]`) as HTMLInputElement) :\n                (this.dt.wrapperDOM.querySelector(`input${inputSelector}[type=text]`) as HTMLInputElement)\n\n            this.saveCell(input.value)\n        }\n        document.body.appendChild(this.containerDOM)\n        this.menuOpen = true\n        this.dt.emit(\"editable.context.open\")\n    }\n\n    /**\n     * Close the context menu\n     * @return {Void}\n     */\n    closeMenu() {\n        if (this.menuOpen) {\n            this.menuOpen = false\n            document.body.removeChild(this.containerDOM)\n            this.dt.emit(\"editable.context.close\")\n        }\n    }\n\n    /**\n     * Destroy the instance\n     * @return {Void}\n     */\n    destroy() {\n        this.dt.dom.removeEventListener(this.options.clickEvent, this.events.click)\n        this.dt.dom.removeEventListener(\"contextmenu\", this.events.context)\n        document.removeEventListener(\"click\", this.events.dismissMenu)\n        document.removeEventListener(\"keydown\", this.events.keydown)\n        window.removeEventListener(\"resize\", this.events.reset)\n        window.removeEventListener(\"scroll\", this.events.reset)\n        if (document.body.contains(this.containerDOM)) {\n            document.body.removeChild(this.containerDOM)\n        }\n        if (this.options.inline) {\n            this.dt.options.rowRender = this.originalRowRender\n        }\n        this.initialized = false\n    }\n\n    rowRender(row, tr, index) {\n        if (!this.data || this.data.rowIndex !== index) {\n            return tr\n        }\n\n        if (this.editingCell) {\n            // cell editing\n            const cell = tr.childNodes[columnToVisibleIndex(this.data.columnIndex, this.dt.columns.settings)]\n            cell.childNodes = [\n                {\n                    nodeName: \"INPUT\",\n                    attributes: {\n                        type: \"text\",\n                        value: this.data.content,\n                        class: this.options.classes.input\n                    }\n                }\n            ]\n        } else {\n            // row editing\n\n            // Add the inputs for each cell\n            tr.childNodes.forEach((cell: elementNodeType, i: number) => {\n                const index = visibleToColumnIndex(i, this.dt.columns.settings)\n                const dataCell = row[index]\n                if (!this.options.excludeColumns.includes(index)) {\n                    const cell = tr.childNodes[i]\n                    cell.childNodes = [\n                        {\n                            nodeName: \"INPUT\",\n                            attributes: {\n                                type: \"text\",\n                                value: escapeText(dataCell.text || String(dataCell.data) || \"\"),\n                                class: this.options.classes.input\n                            }\n                        }\n                    ]\n                }\n            })\n\n        }\n        return tr\n\n    }\n}\n\nexport const makeEditable = function(dataTable: DataTable, options = {}) {\n    const editor = new Editor(dataTable, options)\n    if (dataTable.initialized) {\n        editor.init()\n    } else {\n        dataTable.on(\"datatable.init\", () => editor.init())\n    }\n\n    return editor\n}\n","// Source: https://www.freecodecamp.org/news/javascript-debounce-example/\n\nexport const debounce = function(func: () => void, timeout = 300) {\n    let timer: number\n    return (..._args: any[]) => {\n        clearTimeout(timer)\n        timer = window.setTimeout(() => func(), timeout)\n    }\n}\n","/**\n* Default config\n* @type {Object}\n*/\n//import {ColumnFilter} from \"./column_filter\"\n\nexport const defaultConfig = {\n    classes: {\n        button: \"datatable-column-filter-button\",\n        menu: \"datatable-column-filter-menu\",\n        container: \"datatable-column-filter-container\",\n        wrapper: \"datatable-column-filter-wrapper\"\n    },\n    labels: {\n        button: \"Filter columns within the table\" // The filter button title\n    },\n    hiddenColumns: []\n}\n","import {DataTable} from \"../datatable\"\nimport {classNamesToSelector, createElement} from \"../helpers\"\n\nimport {\n    defaultConfig\n} from \"./config\"\n\nimport {ColumnFilterOptions} from \"./types\"\n\nclass ColumnFilter {\n\n    addedButtonDOM: boolean\n\n    menuOpen: boolean\n\n    buttonDOM: HTMLElement\n\n    dt: DataTable\n\n    events: { [key: string]: () => void}\n\n    initialized: boolean\n\n    options: ColumnFilterOptions\n\n    menuDOM: HTMLElement\n\n    containerDOM: HTMLElement\n\n    wrapperDOM: HTMLElement\n\n    limits: {x: number, y: number}\n\n    rect: {width: number, height: number}\n\n    event: Event\n\n    constructor(dataTable: DataTable, options = {}) {\n        this.dt = dataTable\n        this.options = {\n            ...defaultConfig,\n            ...options\n        }\n    }\n\n    init() {\n\n        if (this.initialized) {\n            return\n        }\n\n        const buttonSelector = classNamesToSelector(this.options.classes.button)\n        let buttonDOM : (HTMLElement | null) = this.dt.wrapperDOM.querySelector(buttonSelector)\n        if (!buttonDOM) {\n            buttonDOM = createElement(\n                \"button\",\n                {\n                    class: this.options.classes.button,\n                    html: \"▦\"\n                }\n            )\n            // filter button not part of template (could be default template. We add it to search.)\n            const searchSelector = classNamesToSelector(this.dt.options.classes.search)\n            const searchWrapper = this.dt.wrapperDOM.querySelector(searchSelector)\n            if (searchWrapper) {\n                searchWrapper.appendChild(buttonDOM)\n            } else {\n                this.dt.wrapperDOM.appendChild(buttonDOM)\n            }\n            this.addedButtonDOM = true\n        }\n        this.buttonDOM = buttonDOM\n\n\n        this.containerDOM = createElement(\"div\", {\n            id: this.options.classes.container\n        })\n        this.wrapperDOM = createElement(\"div\", {\n            class: this.options.classes.wrapper\n        })\n        this.menuDOM = createElement(\"ul\", {\n            class: this.options.classes.menu,\n            html: this.dt.data.headings.map(\n                (heading, index) => {\n                    const settings = this.dt.columns.settings[index]\n                    if (this.options.hiddenColumns.includes(index)) {\n                        return \"\"\n                    }\n                    return `<li data-column=\"${index}\">\n                        <input type=\"checkbox\" value=\"${heading.text || heading.data}\" ${settings.hidden ? \"\" : \"checked=''\"}>\n                        <label>\n                            ${heading.text || heading.data}\n                        </label>\n                    </li>`\n                }\n            ).join(\"\")\n        })\n        this.wrapperDOM.appendChild(this.menuDOM)\n        this.containerDOM.appendChild(this.wrapperDOM)\n        this._measureSpace()\n\n        this._bind()\n\n        this.initialized = true\n\n    }\n\n    dismiss() {\n        if (this.addedButtonDOM && this.buttonDOM.parentElement) {\n            this.buttonDOM.parentElement.removeChild(this.buttonDOM)\n        }\n        document.removeEventListener(\"click\", this.events.click)\n    }\n\n    _bind() {\n        this.events = {\n            click: this._click.bind(this)\n        }\n        document.addEventListener(\"click\", this.events.click)\n    }\n\n    _openMenu() {\n        document.body.appendChild(this.containerDOM)\n        this._measureSpace()\n        this.menuOpen = true\n        this.dt.emit(\"columnFilter.menu.open\")\n    }\n\n    _closeMenu() {\n        if (this.menuOpen) {\n            this.menuOpen = false\n            document.body.removeChild(this.containerDOM)\n            this.dt.emit(\"columnFilter.menu.close\")\n        }\n    }\n\n    _measureSpace() {\n        const scrollX = window.scrollX || window.pageXOffset\n        const scrollY = window.scrollY || window.pageYOffset\n        this.rect = this.wrapperDOM.getBoundingClientRect()\n        this.limits = {\n            x: window.innerWidth + scrollX - this.rect.width,\n            y: window.innerHeight + scrollY - this.rect.height\n        }\n    }\n\n    _click(event: MouseEvent) {\n        const target = event.target\n        if (!(target instanceof Element)) {\n            return\n        }\n        this.event = event\n\n        if (this.buttonDOM.contains(target)) {\n            event.preventDefault()\n            if (this.menuOpen) {\n                this._closeMenu()\n                return\n            }\n            this._openMenu()\n            // get the mouse position\n            let x = event.pageX\n            let y = event.pageY\n            // check if we're near the right edge of window\n            if (x > this.limits.x) {\n                x -= this.rect.width\n            }\n            // check if we're near the bottom edge of window\n            if (y > this.limits.y) {\n                y -= this.rect.height\n            }\n            this.wrapperDOM.style.top = `${y}px`\n            this.wrapperDOM.style.left = `${x}px`\n        } else if (this.menuDOM.contains(target)) {\n            const menuSelector = classNamesToSelector(this.options.classes.menu)\n            const li = target.closest(`${menuSelector} > li`) as HTMLElement\n            if (!li) {\n                return\n            }\n            const checkbox = li.querySelector(\"input[type=checkbox]\") as HTMLInputElement\n            if (!checkbox.contains(target)) {\n                checkbox.checked = !checkbox.checked\n            }\n            const column = Number(li.dataset.column)\n            if (checkbox.checked) {\n                this.dt.columns.show([column])\n            } else {\n                this.dt.columns.hide([column])\n            }\n        } else if (this.menuOpen) {\n            this._closeMenu()\n        }\n    }\n\n}\n\n\nexport const addColumnFilter = function(dataTable: DataTable, options = {}) {\n    const columnFilter = new ColumnFilter(dataTable, options)\n    if (dataTable.initialized) {\n        columnFilter.init()\n    } else {\n        dataTable.on(\"datatable.init\", () => columnFilter.init())\n    }\n\n    return columnFilter\n}\n"],"names":["isObject","val","Object","prototype","toString","call","isJson","str","t","JSON","parse","e","Array","isArray","createElement","nodeName","attrs","dom","document","attr","innerHTML","setAttribute","objToText","obj","includes","data","childNodes","map","childNode","join","cellToText","hasOwnProperty","cell","text","String","escapeText","replace","visibleToColumnIndex","visibleIndex","columns","counter","columnIndex","hidden","namedNodeMapToObject","name","value","classNamesToSelector","classNames","trim","split","className","containsClass","element","classes","hasMissingClass","some","classList","contains","joinWithSpaces","first","second","__assign","assign","s","arguments$1","arguments","i","n","length","p","apply","this","__spreadArray","to","from","pack","ar","l","slice","concat","SuppressedError","Diff","options","_this","entries","forEach","_a","key","stringify","setValue","aKey","aValue","checkElementType","elementTypeNames","_i","elementTypeName","_b","ownerDocument","defaultView","objToNode","objNode","insideSvg","node","createTextNode","createComment","createElementNS","toLowerCase","attributes","appendChild","valueDiffing","checked","selected","getFromRoute","route","c","splice","applyDiff","tree","diff","newNode","reference","action","_const","addElement","addTextElement","info","preDiffApply","addAttribute","modifyAttribute","newValue","removeAttribute","modifyTextElement","textDiff","oldValue","parentNode","modifyValue","modifyComment","modifyChecked","modifySelected","replaceElement","namespaceURI","replaceChild","relocateGroup","groupLength","removeChild","index","insertBefore","removeElement","parentRoute","removeTextElement","nodeType","console","log","postDiffApply","swap","p1","p2","tmp","undoDOM","diffs","reverse","undoDiff","elementDescriptors","el","output","push","id","findUniqueDescriptors","li","uniqueDescriptors","duplicateDescriptors","descriptor","inUnique","uniqueInBoth","l1","l2","l1Unique","l2Unique","inBoth","keys","removeDone","outerDone","innerDone","valueDone","every","cleanNode","diffNode","elementNode","diffChildNode","isEqual","e1","e2","Boolean","e1Attributes","e2Attributes","attribute","roughlyEqual","sameSiblings","preventRecursion","nodeList1","nodeList2","childUniqueDescriptors_1","makeBooleanArray","v","markSubTrees","oldTree","newTree","oldChildren","newChildren","marked1","marked2","subsets","returnIndex","foundAllSubsets","_loop_1","subset","c1","c2","lcsSize","c1Length","c2Length","matches","subsetsSame","c1Desc","c2Desc","description","c1Index","c1Element","c2Index","c2Element","findCommonSubsets","item","markBoth","subsetsAge","DiffTracker","list","add","fn","getFromVirtualRoute","nodeIndex","undefined","applyVirtual","routeInfo","newSubsets","preVirtualDiffApply","movedNode","splitLength","c_1","c_2","filter","postVirtualDiffApply","applyVirtualDiff","nodeToObj","aNode","type","tagRE","attrRE","unescape","string","lookup","area","base","br","col","embed","hr","img","input","keygen","link","menuItem","meta","param","source","track","wbr","parseTag","tag","caseSensitive","res","voidElement","tagMatch","match","toUpperCase","charAt","startsWith","endIndex","indexOf","reg","RegExp","result","done","exec","arr","lastIndex","substring","stringToObj","html","current","level","end","isOpen","isComment","start","nextChar","comment","parent_1","parent_2","DiffFinder","t1Node","t2Node","t1","Element","t2","diffcount","foundAll","debug","t1Orig","t2Orig","tracker","init","findDiffs","diffcap","Error","findNextDiff","error","fdiffs","maxDepth","findOuterDiff","filterOuterDiff","findInnerDiff","findValueDiff","attr1","attr2","attrLength","pos","Math","abs","sort","t1ChildNodes","t2ChildNodes","last","max","childNodesLengthDifference","maxChildCount","cachedSubtrees","subtrees","attemptGroupRelocation","destinationDifferent","toGroup","group","similarNode","gapInformation","stable","gaps1","gaps2","endOld","endNew","j","getGapInformation","shortest","min","index2","index1","testI","DEFAULT_OPTIONS","currentValue","expectedValue","compress","window","components","DiffDOM","varNames","constNames_1","varName","applyDOM","undo","headingsToVirtualHeaderRowDOM","headings","columnSettings","columnsState","format","hiddenHeader","sortable","scrollY","noColumnWidths","unhideHeader","heading","column","searchable","headerClass","class","directionClass","dir","ascending","descending","filters","filterActive","widths","style","headerNodes","sorter","dataToVirtualDOM","tableAttributes","rows","rowCursor","header","footer","rowRender","tabIndex","renderHeader","footers","captions","table","row","tr","cells","cIndex","td","cellClass","render","renderedCell","cursor","renderedRow","headerRow","thead","unshift","tfoot","structuredClone","foot","caption","tabindex","r","u","a","o","f","h","d","$","y","M","weekdays","months","ordinal","m","z","utcOffset","floor","date","year","month","clone","ceil","w","D","ms","Q","g","S","_","O","args","b","locale","$L","utc","$u","x","$x","$offset","$d","Date","NaN","test","UTC","$y","getFullYear","$M","getMonth","$D","getDate","$W","getDay","$H","getHours","$m","getMinutes","$s","getSeconds","$ms","getMilliseconds","$utils","isValid","isSame","startOf","endOf","isAfter","isBefore","$g","set","unix","valueOf","getTime","toDate","$locale","weekStart","$set","daysInMonth","get","Number","round","subtract","invalidDate","meridiem","monthsShort","weekdaysMin","weekdaysShort","getTimezoneOffset","toJSON","toISOString","toUTCString","k","extend","$i","isDayjs","en","Ls","exports","LTS","LT","L","LL","LLL","LLLL","zone","offset","A","afternoon","milliseconds","SS","SSS","ss","mm","H","HH","hh","DD","Do","day","MM","MMM","MMMM","Y","YY","YYYY","Z","ZZ","formats","regex","parser","hours","customParseFormat","parseTwoDigitYear","minutes","seconds","dayjs","parseDate","content","readDataCell","constructor","find","cellData","order","parseFloat","readHeaderCell","readTableData","dataOption","defaultType","defaultFormat","tHead","querySelectorAll","th","innerText","readDOMHeaderCell","settings","dataset","getAttribute","firstRow","firstRowCells","_cell","tBodies","readDOMDataCell","isNaN","Rows","dt","setCursor","oldCursor","_renderTable","cursorSelector","cursorDOM","querySelector","scrollIntoView","block","emit","hasRows","update","remove","select","_row","findRowIndex","findIndex","findRow","cols","updateRow","Columns","_state","columnOptions","selector","numeric","caseFirst","sensitivity","ignorePunctuation","sortSequence","searchItemSeparator","readColumnSettings","size","_node","hide","show","visible","newColumnSelector","_heading","currentFilter","newFilterState","returnNext","_currentPage","currentDir","currentDirIndex","collator","Intl","Collator","usage","row1","row2","cell1","cell2","order1","order2","temp","compare","_searchQueries","multiSearch","_measureWidths","activeHeadings","fixedColumns","renderOptions","noPaging","headerDOM","parentElement","activeDOMHeadings","firstElementChild","domCounter","absoluteColumnWidths","width","offsetWidth","totalOffsetWidth","reduce","total","cellWidth","defaultConfig","destroyable","searchQuerySeparator","searchAnd","paging","perPage","perPageSelect","nextPrev","firstLast","prevText","nextText","firstText","lastText","ellipsisText","truncatePager","pagerDelta","fixedHeight","rowNavigation","pagerRender","tableRender","diffDomOptions","labels","placeholder","searchTitle","pageTitle","noRows","noResults","template","top","dropdown","search","container","bottom","pagination","active","disabled","ellipsis","empty","headercontainer","loading","paginationList","paginationListItem","paginationListItemLink","wrapper","page","label","state","createVirtualPagerDOM","onFirstPage","onLastPage","currentPage","totalPages","pagerListItems","prev","pages","paginationListItems","pagesLength","doublePagerDelta","previousPage","nextPage","paginationListItemsToModify","previousLi","modifiedLis","pageNumber","parseInt","previousPageNumber","newLi","truncate","next","DataTable","containerDOM","_dd","_events","hasHeadings","_initialHTML","initialized","_label","lastPage","_listeners","_pagerDOMs","_virtualPagerDOM","_rect","_searchData","_tableAttributes","_tableFooters","_tableCaptions","_virtualDOM","_virtualHeaderDOM","wrapperDOM","HTMLTableElement","outerHTML","onResize","_onResize","_render","setTimeout","selectorClassSelector","choice","lab","option","Option","containerSelector","paginationSelector","HTMLElement","infoSelector","getBoundingClientRect","_fixHeight","_bindEvents","newVirtualDOM","renderedTableVirtualDOM","_renderPage","lastRowCursor","setMessage","items","_renderPagers","newPagerVirtualDOM","renderedPagerVirtualDOM","pagerDOM","_renderSeparateHeader","tableVirtualDOM","newVirtualHeaderDOM","paddingRight","clientWidth","paddedVirtualHeaderDOM","scrollHeight","clientHeight","overflowY","HTMLSelectElement","addEventListener","event","inputSelector","target","HTMLInputElement","preventDefault","searches","andSearch","and","terms","querySeparator","term","hyperlink","closest","hasAttribute","children","lastRow","stopPropagation","foundRow","nextRow","destroy","oldDOM","removeEventListener","measureWidths","_paginate","filterState","height","rawQueries","queries","query","queryWords","columnQueries","normalize","idx","searchRow","queryWord","searchItem","insert","rIndex","refresh","print","tableDOM","newTableVirtualDOM","open","body","message","colspan","on","callback","off","convertCSV","userOptions","lineDelimiter","columnDelimiter","removeDoubleQuotes","shift","values","convertJSON","json","warn","exportCSV","download","skipColumn","columnShown","headers","selectedRows","selection","href","encodeURI","filename","click","exportJSON","replacer","space","blob","Blob","url","URL","createObjectURL","revokeObjectURL","exportSQL","tableName","exportTXT","form","menu","save","cancel","close","inner","modal","editable","separator","closeX","editCell","editRow","removeRow","reallyRemove","reallyCancel","cancelModal","editor","confirm","inline","hiddenColumns","contextMenu","clickEvent","excludeColumns","menuItems","_event","Editor","menuOpen","editing","editingCell","editingRow","events","limits","menuDOM","modalDOM","originalRowRender","rect","dataTable","newTr","updateMenu","bindEvents","keydown","bind","context","dismissMenu","reset","func","timeout","timer","_args","clearTimeout","debounce","pageX","pageY","left","openMenu","saveCell","closeModal","saveRow","cellIndex","closeMenu","rowIndex","editCellModal","openModal","focus","selectionStart","selectionEnd","oldData","stringValue","editRowModal","lastElementChild","inputs","updatedRow","valueCounter","oldItem","colIndex","newData","scrollX","pageXOffset","pageYOffset","innerWidth","innerHeight","valid","columnToVisibleIndex","dataCell","makeEditable","button","ColumnFilter","addedButtonDOM","buttonDOM","buttonSelector","searchSelector","searchWrapper","_measureSpace","_bind","dismiss","_click","_openMenu","_closeMenu","menuSelector","checkbox","addColumnFilter","columnFilter"],"mappings":"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","x_google_ignoreList":[1,3,4]}