/*! SearchPanes 2.3.0
 * © SpryMedia Ltd - datatables.net/license
 */

(function (factory) {
  if (typeof define === "function" && define.amd) {
    // AMD
    define(["jquery", "datatables.net"], function ($) {
      return factory($, window, document);
    });
  } else if (typeof exports === "object") {
    // CommonJS
    var jq = require_once("jquery");
    var cjsRequires = function (root, $) {
      if (!$.fn.dataTable) {
        require_once("datatables.net")(root, $);
      }
    };

    if (typeof window === "undefined") {
      module.exports = function (root, $) {
        if (!root) {
          // CommonJS environments without a window global must pass a
          // root. This will give an error otherwise
          root = window;
        }

        if (!$) {
          $ = jq(root);
        }

        cjsRequires(root, $);
        return factory($, root, root.document);
      };
    } else {
      cjsRequires(window, jq);
      module.exports = factory(jq, window, window.document);
    }
  } else {
    // Browser
    factory(jQuery, window, document);
  }
})(function ($, window, document) {
  "use strict";
  var DataTable = $.fn.dataTable;

  (function () {
    "use strict";

    var $$5;
    var dataTable$2;
    function setJQuery$4(jq) {
      $$5 = jq;
      dataTable$2 = jq.fn.dataTable;
    }
    var SearchPane = /** @class */ (function () {
      /**
       * Creates the panes, sets up the search function
       *
       * @param paneSettings The settings for the searchPanes
       * @param opts The options for the default features
       * @param index the index of the column for this pane
       * @param panesContainer The overall container for SearchPanes that this pane will be attached to
       * @param panes The custom pane settings if this is a custom pane
       * @returns {object} the pane that has been created, including the table and the index of the pane
       */
      function SearchPane(paneSettings, opts, index, panesContainer, panes) {
        var _this = this;
        if (panes === void 0) {
          panes = null;
        }
        // Check that the required version of DataTables is included
        if (!dataTable$2 || !dataTable$2.versionCheck || !dataTable$2.versionCheck("1.10.0")) {
          throw new Error("SearchPane requires DataTables 1.10 or newer");
        }
        // Check that Select is included
        // eslint-disable-next-line no-extra-parens
        if (!dataTable$2.select) {
          throw new Error("SearchPane requires Select");
        }
        var table = new dataTable$2.Api(paneSettings);
        this.classes = $$5.extend(true, {}, SearchPane.classes);
        // Get options from user
        this.c = $$5.extend(true, {}, SearchPane.defaults, opts, panes);
        if (opts && opts.hideCount && opts.viewCount === undefined) {
          this.c.viewCount = !this.c.hideCount;
        }
        var rowLength = table.columns().eq(0).toArray().length;
        this.s = {
          colExists: index < rowLength,
          colOpts: undefined,
          customPaneSettings: panes,
          displayed: false,
          dt: table,
          dtPane: undefined,
          firstSet: true,
          index: index,
          indexes: [],
          listSet: false,
          name: undefined,
          rowData: {
            arrayFilter: [],
            arrayOriginal: [],
            bins: {},
            binsOriginal: {},
            filterMap: new Map(),
            totalOptions: 0,
          },
          scrollTop: 0,
          searchFunction: undefined,
          selections: [],
          serverSelect: [],
          serverSelecting: false,
          tableLength: null,
          updating: false,
        };
        this.s.colOpts = this.s.colExists ? this._getOptions() : this._getBonusOptions();
        this.dom = {
          buttonGroup: $$5("<div/>").addClass(this.classes.buttonGroup),
          clear: $$5('<button type="button">&#215;</button>').attr("disabled", "true").addClass(this.classes.disabledButton).addClass(this.classes.paneButton).addClass(this.classes.clearButton).html(this.s.dt.i18n("searchPanes.clearPane", this.c.i18n.clearPane)),
          collapseButton: $$5('<button type="button"><span class="' + this.classes.caret + '">&#x5e;</span></button>')
            .addClass(this.classes.paneButton)
            .addClass(this.classes.collapseButton),
          container: $$5("<div/>")
            .addClass(this.classes.container)
            .addClass(this.s.colOpts.className)
            .addClass(this.classes.layout + (parseInt(this.c.layout.split("-")[1], 10) < 10 ? this.c.layout : this.c.layout.split("-")[0] + "-9"))
            .addClass(this.s.customPaneSettings && this.s.customPaneSettings.className ? this.s.customPaneSettings.className : ""),
          countButton: $$5('<button type="button"><span></span></button>').addClass(this.classes.paneButton).addClass(this.classes.countButton),
          dtP: $$5('<table width="100%"><thead><tr><th>' + (this.s.colExists ? $$5(this.s.dt.column(this.s.index).header()).text() : this.s.customPaneSettings.header || "Custom Pane") + "</th><th/></tr></thead></table>"),
          lower: $$5("<div/>").addClass(this.classes.subRow2).addClass(this.classes.narrowButton),
          nameButton: $$5('<button type="button"><span></span></button>').addClass(this.classes.paneButton).addClass(this.classes.nameButton),
          panesContainer: $$5(panesContainer),
          searchBox: $$5("<input/>").addClass(this.classes.paneInputButton).addClass(this.classes.search),
          searchButton: $$5('<button type="button"><span></span></button>').addClass(this.classes.searchIcon).addClass(this.classes.paneButton),
          searchCont: $$5("<div/>").addClass(this.classes.searchCont),
          searchLabelCont: $$5("<div/>").addClass(this.classes.searchLabelCont),
          topRow: $$5("<div/>").addClass(this.classes.topRow),
          upper: $$5("<div/>").addClass(this.classes.subRow1).addClass(this.classes.narrowSearch),
        };
        // Set the value of name incase ordering is desired
        if (this.s.colOpts.name) {
          this.s.name = this.s.colOpts.name;
        } else if (this.s.customPaneSettings && this.s.customPaneSettings.name) {
          this.s.name = this.s.customPaneSettings.name;
        } else {
          this.s.name = this.s.colExists ? $$5(this.s.dt.column(this.s.index).header()).text() : this.s.customPaneSettings.header || "Custom Pane";
        }
        var tableNode = this.s.dt.table(0).node();
        // Custom search function for table
        this.s.searchFunction = function (settings, searchData, dataIndex) {
          // If no data has been selected then show all
          if (_this.s.selections.length === 0) {
            return true;
          }
          if (settings.nTable !== tableNode) {
            return true;
          }
          var filter = null;
          if (_this.s.colExists) {
            // Get the current filtered data
            filter = searchData[_this.s.index];
            if (_this.s.colOpts.orthogonal.filter !== "filter") {
              // get the filter value from the map
              filter = _this.s.rowData.filterMap.get(dataIndex);
              if (filter instanceof $$5.fn.dataTable.Api) {
                // eslint-disable-next-line no-extra-parens
                filter = filter.toArray();
              }
            }
          }
          return _this._search(filter, dataIndex);
        };
        $$5.fn.dataTable.ext.search.push(this.s.searchFunction);
        // If the clear button for this pane is clicked clear the selections
        if (this.c.clear) {
          this.dom.clear.on("click.dtsp", function () {
            var searches = _this.dom.container.find("." + _this.classes.search.replace(/\s+/g, "."));
            searches.each(function () {
              $$5(this).val("").trigger("input");
            });
            _this.clearPane();
          });
        }
        // Sometimes the top row of the panes containing the search box and ordering buttons appears
        //  weird if the width of the panes is lower than expected, this fixes the design.
        // Equally this may occur when the table is resized.
        this.s.dt.on("draw.dtsp", function () {
          return _this.adjustTopRow();
        });
        this.s.dt.on("buttons-action.dtsp", function () {
          return _this.adjustTopRow();
        });
        // When column-reorder is present and the columns are moved, it is necessary to
        //  reassign all of the panes indexes to the new index of the column.
        this.s.dt.on("column-reorder.dtsp", function (e, settings, details) {
          _this.s.index = details.mapping[_this.s.index];
        });
        return this;
      }
      /**
       * Adds a row to the panes table
       *
       * @param display the value to be displayed to the user
       * @param filter the value to be filtered on when searchpanes is implemented
       * @param shown the number of rows in the table that are currently visible matching this criteria
       * @param total the total number of rows in the table that match this criteria
       * @param sort the value to be sorted in the pane table
       * @param type the value of which the type is to be derived from
       */
      SearchPane.prototype.addRow = function (display, filter, sort, type, className, total, shown) {
        if (!total) {
          total = this.s.rowData.bins[filter] ? this.s.rowData.bins[filter] : 0;
        }
        if (!shown) {
          shown = this._getShown(filter);
        }
        var index;
        for (var _i = 0, _a = this.s.indexes; _i < _a.length; _i++) {
          var entry = _a[_i];
          if (entry.filter === filter) {
            index = entry.index;
          }
        }
        if (index === undefined) {
          index = this.s.indexes.length;
          this.s.indexes.push({ filter: filter, index: index });
        }
        return this.s.dtPane.row.add({
          className: className,
          display: display !== "" ? display : this.emptyMessage(),
          filter: filter,
          index: index,
          shown: shown,
          sort: sort,
          total: total,
          type: type,
        });
      };
      /**
       * Adjusts the layout of the top row when the screen is resized
       */
      SearchPane.prototype.adjustTopRow = function () {
        var subContainers = this.dom.container.find("." + this.classes.subRowsContainer.replace(/\s+/g, "."));
        var subRow1 = this.dom.container.find("." + this.classes.subRow1.replace(/\s+/g, "."));
        var subRow2 = this.dom.container.find("." + this.classes.subRow2.replace(/\s+/g, "."));
        var topRow = this.dom.container.find("." + this.classes.topRow.replace(/\s+/g, "."));
        // If the width is 0 then it is safe to assume that the pane has not yet been displayed.
        //  Even if it has, if the width is 0 it won't make a difference if it has the narrow class or not
        if (($$5(subContainers[0]).width() < 252 || $$5(topRow[0]).width() < 252) && $$5(subContainers[0]).width() !== 0) {
          $$5(subContainers[0]).addClass(this.classes.narrow);
          $$5(subRow1[0]).addClass(this.classes.narrowSub).removeClass(this.classes.narrowSearch);
          $$5(subRow2[0]).addClass(this.classes.narrowSub).removeClass(this.classes.narrowButton);
        } else {
          $$5(subContainers[0]).removeClass(this.classes.narrow);
          $$5(subRow1[0]).removeClass(this.classes.narrowSub).addClass(this.classes.narrowSearch);
          $$5(subRow2[0]).removeClass(this.classes.narrowSub).addClass(this.classes.narrowButton);
        }
      };
      /**
       * In the case of a rebuild there is potential for new data to have been included or removed
       * so all of the rowData must be reset as a precaution.
       */
      SearchPane.prototype.clearData = function () {
        this.s.rowData = {
          arrayFilter: [],
          arrayOriginal: [],
          bins: {},
          binsOriginal: {},
          filterMap: new Map(),
          totalOptions: 0,
        };
      };
      /**
       * Clear the selections in the pane
       */
      SearchPane.prototype.clearPane = function () {
        // Deselect all rows which are selected and update the table and filter count.
        this.s.dtPane.rows({ selected: true }).deselect();
        this.updateTable();
        return this;
      };
      /**
       * Collapses the pane so that only the header is displayed
       */
      SearchPane.prototype.collapse = function () {
        var _this = this;
        if (
          !this.s.displayed ||
          // If collapsing is disabled globally, and not enabled specifically for this column
          (!this.c.collapse && this.s.colOpts.collapse !== true) ||
          // OR, collapsing could be enabled globally and this column specifically
          // is not to be collapsed.
          // We can't just take !this.s.colOpts.collapse here as if it is undefined
          // then the global should be used
          this.s.colOpts.collapse === false
        ) {
          return;
        }
        $$5(this.s.dtPane.table().container()).addClass(this.classes.hidden);
        this.dom.topRow.addClass(this.classes.bordered);
        this.dom.nameButton.addClass(this.classes.disabledButton);
        this.dom.countButton.addClass(this.classes.disabledButton);
        this.dom.searchButton.addClass(this.classes.disabledButton);
        this.dom.collapseButton.addClass(this.classes.rotated);
        this.dom.topRow.one("click.dtsp", function () {
          return _this.show();
        });
        this.dom.topRow.trigger("collapse.dtsps");
      };
      /**
       * Strips all of the SearchPanes elements from the document and turns all of the listeners for the buttons off
       */
      SearchPane.prototype.destroy = function () {
        if (this.s.dtPane) {
          this.s.dtPane.off(".dtsp");
        }
        this.s.dt.off(".dtsp");
        this.dom.clear.off(".dtsp");
        this.dom.nameButton.off(".dtsp");
        this.dom.countButton.off(".dtsp");
        this.dom.searchButton.off(".dtsp");
        this.dom.collapseButton.off(".dtsp");
        $$5(this.s.dt.table().node()).off(".dtsp");
        this.dom.container.detach();
        var searchIdx = $$5.fn.dataTable.ext.search.indexOf(this.s.searchFunction);
        while (searchIdx !== -1) {
          $$5.fn.dataTable.ext.search.splice(searchIdx, 1);
          searchIdx = $$5.fn.dataTable.ext.search.indexOf(this.s.searchFunction);
        }
        // If the datatables have been defined for the panes then also destroy these
        if (this.s.dtPane) {
          this.s.dtPane.destroy();
        }
        this.s.listSet = false;
      };
      /**
       * Getting the legacy message is a little complex due a legacy parameter
       */
      SearchPane.prototype.emptyMessage = function () {
        var def = this.c.i18n.emptyMessage;
        // Legacy parameter support
        if (this.c.emptyMessage) {
          def = this.c.emptyMessage;
        }
        // Override per column
        if (this.s.colOpts.emptyMessage !== false && this.s.colOpts.emptyMessage !== null) {
          def = this.s.colOpts.emptyMessage;
        }
        return this.s.dt.i18n("searchPanes.emptyMessage", def);
      };
      /**
       * Updates the number of filters that have been applied in the title
       */
      SearchPane.prototype.getPaneCount = function () {
        return this.s.dtPane ? this.s.dtPane.rows({ selected: true }).data().toArray().length : 0;
      };
      /**
       * Rebuilds the panes from the start having deleted the old ones
       *
       * @param? dataIn data to be used in buildPane
       * @param? maintainSelection Whether the current selections are to be maintained over rebuild
       */
      SearchPane.prototype.rebuildPane = function (dataIn, maintainSelection) {
        if (dataIn === void 0) {
          dataIn = null;
        }
        if (maintainSelection === void 0) {
          maintainSelection = false;
        }
        this.clearData();
        var selectedRows = [];
        this.s.serverSelect = [];
        var prevEl = null;
        // When rebuilding strip all of the HTML Elements out of the container and start from scratch
        if (this.s.dtPane) {
          if (maintainSelection) {
            if (!this.s.dt.page.info().serverSide) {
              selectedRows = this.s.dtPane.rows({ selected: true }).data().toArray();
            } else {
              this.s.serverSelect = this.s.dtPane.rows({ selected: true }).data().toArray();
            }
          }
          this.s.dtPane.clear().destroy();
          prevEl = this.dom.container.prev();
          this.destroy();
          this.s.dtPane = undefined;
          $$5.fn.dataTable.ext.search.push(this.s.searchFunction);
        }
        this.dom.container.removeClass(this.classes.hidden);
        this.s.displayed = false;
        this._buildPane(!this.s.dt.page.info().serverSide ? selectedRows : this.s.serverSelect, dataIn, prevEl);
        return this;
      };
      /**
       * Resizes the pane based on the layout that is passed in
       *
       * @param layout the layout to be applied to this pane
       */
      SearchPane.prototype.resize = function (layout) {
        this.c.layout = layout;
        this.dom.container
          .removeClass()
          .addClass(this.classes.show)
          .addClass(this.classes.container)
          .addClass(this.s.colOpts.className)
          .addClass(this.classes.layout + (parseInt(layout.split("-")[1], 10) < 10 ? layout : layout.split("-")[0] + "-9"))
          .addClass(this.s.customPaneSettings !== null && this.s.customPaneSettings.className ? this.s.customPaneSettings.className : "");
        this.adjustTopRow();
      };
      /**
       * Sets the listeners for the pane.
       *
       * Having it in it's own function makes it easier to only set them once
       */
      SearchPane.prototype.setListeners = function () {
        var _this = this;
        if (!this.s.dtPane) {
          return;
        }
        // When an item is selected on the pane, add these to the array which holds selected items.
        // Custom search will perform.
        this.s.dtPane.off("select.dtsp").on("select.dtsp", function () {
          clearTimeout(_this.s.deselectTimeout);
          _this._updateSelection(!_this.s.updating);
          _this.dom.clear.removeClass(_this.classes.disabledButton).removeAttr("disabled");
        });
        // When an item is deselected on the pane, re add the currently selected items to the array
        // which holds selected items. Custom search will be performed.
        this.s.dtPane.off("deselect.dtsp").on("deselect.dtsp", function () {
          _this.s.deselectTimeout = setTimeout(function () {
            _this._updateSelection(true);
            if (_this.s.dtPane.rows({ selected: true }).data().toArray().length === 0) {
              _this.dom.clear.addClass(_this.classes.disabledButton).attr("disabled", "true");
            }
          }, 50);
        });
        // If we attempty to turn off this event then it will ruin behaviour in other panes
        //  so need to make sure that it is only done once
        if (this.s.firstSet) {
          this.s.firstSet = false;
          // When saving the state store all of the selected rows for preselection next time around
          this.s.dt.on("stateSaveParams.dtsp", function (e, settings, data) {
            // If the data being passed in is empty then state clear must have occured
            // so clear the panes state as well
            if ($$5.isEmptyObject(data)) {
              _this.s.dtPane.state.clear();
              return;
            }
            var bins;
            var order;
            var selected = [];
            var collapsed;
            var searchTerm;
            var arrayFilter;
            // Get all of the data needed for the state save from the pane
            if (_this.s.dtPane) {
              selected = _this.s.dtPane
                .rows({ selected: true })
                .data()
                .map(function (item) {
                  return item.filter !== null ? item.filter.toString() : null;
                })
                .toArray();
              searchTerm = _this.dom.searchBox.val();
              order = _this.s.dtPane.order();
              bins = _this.s.rowData.binsOriginal;
              arrayFilter = _this.s.rowData.arrayOriginal;
              collapsed = _this.dom.collapseButton.hasClass(_this.classes.rotated);
            }
            if (data.searchPanes === undefined) {
              data.searchPanes = {};
            }
            if (data.searchPanes.panes === undefined) {
              data.searchPanes.panes = [];
            }
            for (var i = 0; i < data.searchPanes.panes.length; i++) {
              if (data.searchPanes.panes[i].id === _this.s.index) {
                data.searchPanes.panes.splice(i, 1);
                i--;
              }
            }
            // Add the panes data to the state object
            data.searchPanes.panes.push({
              arrayFilter: arrayFilter,
              bins: bins,
              collapsed: collapsed,
              id: _this.s.index,
              order: order,
              searchTerm: searchTerm,
              selected: selected,
            });
          });
        }
        this.s.dtPane.off("user-select.dtsp").on("user-select.dtsp", function (e, _dt, type, cell, originalEvent) {
          originalEvent.stopPropagation();
        });
        this.s.dtPane.off("draw.dtsp").on("draw.dtsp", function () {
          return _this.adjustTopRow();
        });
        // When the button to order by the name of the options is clicked then
        //  change the ordering to whatever it isn't currently
        this.dom.nameButton.off("click.dtsp").on("click.dtsp", function () {
          var currentOrder = _this.s.dtPane.order()[0][1];
          _this.s.dtPane.order([0, currentOrder === "asc" ? "desc" : "asc"]).draw();
          // This state save is required so that the ordering of the panes is maintained
          _this.s.dt.state.save();
        });
        // When the button to order by the number of entries in the column is clicked then
        //  change the ordering to whatever it isn't currently
        this.dom.countButton.off("click.dtsp").on("click.dtsp", function () {
          var currentOrder = _this.s.dtPane.order()[0][1];
          _this.s.dtPane.order([1, currentOrder === "asc" ? "desc" : "asc"]).draw();
          // This state save is required so that the ordering of the panes is maintained
          _this.s.dt.state.save();
        });
        // When the button to order by the number of entries in the column is clicked then
        //  change the ordering to whatever it isn't currently
        this.dom.collapseButton.off("click.dtsp").on("click.dtsp", function (e) {
          e.stopPropagation();
          var container = $$5(_this.s.dtPane.table().container());
          // Toggle the classes
          container.toggleClass(_this.classes.hidden);
          _this.dom.topRow.toggleClass(_this.classes.bordered);
          _this.dom.nameButton.toggleClass(_this.classes.disabledButton);
          _this.dom.countButton.toggleClass(_this.classes.disabledButton);
          _this.dom.searchButton.toggleClass(_this.classes.disabledButton);
          _this.dom.collapseButton.toggleClass(_this.classes.rotated);
          if (container.hasClass(_this.classes.hidden)) {
            _this.dom.topRow.on("click.dtsp", function () {
              return _this.dom.collapseButton.click();
            });
          } else {
            _this.dom.topRow.off("click.dtsp");
          }
          _this.s.dt.state.save();
          _this.dom.topRow.trigger("collapse.dtsps");
        });
        // When the clear button is clicked reset the pane
        this.dom.clear.off("click.dtsp").on("click.dtsp", function () {
          var searches = _this.dom.container.find("." + _this.classes.search.replace(/ /g, "."));
          searches.each(function () {
            // set the value of the search box to be an empty string and then search on that, effectively reseting
            $$5(this).val("").trigger("input");
          });
          _this.clearPane();
        });
        // When the search button is clicked then draw focus to the search box
        this.dom.searchButton.off("click.dtsp").on("click.dtsp", function () {
          return _this.dom.searchBox.focus();
        });
        // When a character is inputted into the searchbox search the pane for matching values.
        // Doing it this way means that no button has to be clicked to trigger a search, it is done asynchronously
        this.dom.searchBox.off("click.dtsp").on("input.dtsp", function () {
          var searchval = _this.dom.searchBox.val();
          _this.s.dtPane.search(searchval).draw();
          if (typeof searchval === "string" && (searchval.length > 0 || (searchval.length === 0 && _this.s.dtPane.rows({ selected: true }).data().toArray().length > 0))) {
            _this.dom.clear.removeClass(_this.classes.disabledButton).removeAttr("disabled");
          } else {
            _this.dom.clear.addClass(_this.classes.disabledButton).attr("disabled", "true");
          }
          // This state save is required so that the searching on the panes is maintained
          _this.s.dt.state.save();
        });
        this.s.dtPane.select.style(this.s.colOpts.dtOpts && this.s.colOpts.dtOpts.select && this.s.colOpts.dtOpts.select.style ? this.s.colOpts.dtOpts.select.style : this.c.dtOpts && this.c.dtOpts.select && this.c.dtOpts.select.style ? this.c.dtOpts.select.style : "os");
      };
      /**
       * Populates the SearchPane based off of the data that has been recieved from the server
       *
       * This method is overriden by SearchPaneST
       *
       * @param dataIn The data that has been sent from the server
       */
      SearchPane.prototype._serverPopulate = function (dataIn) {
        if (dataIn.tableLength) {
          this.s.tableLength = dataIn.tableLength;
          this.s.rowData.totalOptions = this.s.tableLength;
        } else if (this.s.tableLength === null || this.s.dt.rows()[0].length > this.s.tableLength) {
          this.s.tableLength = this.s.dt.rows()[0].length;
          this.s.rowData.totalOptions = this.s.tableLength;
        }
        var colTitle = this.s.dt.column(this.s.index).dataSrc();
        // If there is SP data for this column add it to the data array and bin
        if (dataIn.searchPanes.options[colTitle]) {
          for (var _i = 0, _a = dataIn.searchPanes.options[colTitle]; _i < _a.length; _i++) {
            var dataPoint = _a[_i];
            this.s.rowData.arrayFilter.push({
              display: dataPoint.label,
              filter: dataPoint.value,
              sort: dataPoint.label,
              type: dataPoint.label,
            });
            this.s.rowData.bins[dataPoint.value] = dataPoint.total;
          }
        }
        var binLength = Object.keys(this.s.rowData.bins).length;
        var uniqueRatio = this._uniqueRatio(binLength, this.s.tableLength);
        // Don't show the pane if there isnt enough variance in the data, or there is only 1 entry for that pane
        if (this.s.displayed === false && ((this.s.colOpts.show === undefined && this.s.colOpts.threshold === null ? uniqueRatio > this.c.threshold : uniqueRatio > this.s.colOpts.threshold) || (this.s.colOpts.show !== true && binLength <= 1))) {
          this.dom.container.addClass(this.classes.hidden);
          this.s.displayed = false;
          return;
        }
        // Store the original data
        this.s.rowData.arrayOriginal = this.s.rowData.arrayFilter;
        this.s.rowData.binsOriginal = this.s.rowData.bins;
        // Flag this pane as being displayed
        this.s.displayed = true;
      };
      /**
       * Expands the pane from the collapsed state
       */
      SearchPane.prototype.show = function () {
        if (!this.s.displayed) {
          return;
        }
        this.dom.topRow.removeClass(this.classes.bordered);
        this.dom.nameButton.removeClass(this.classes.disabledButton);
        this.dom.countButton.removeClass(this.classes.disabledButton);
        this.dom.searchButton.removeClass(this.classes.disabledButton);
        this.dom.collapseButton.removeClass(this.classes.rotated);
        $$5(this.s.dtPane.table().container()).removeClass(this.classes.hidden);
        this.dom.topRow.trigger("collapse.dtsps");
      };
      /**
       * Finds the ratio of the number of different options in the table to the number of rows
       *
       * @param bins the number of different options in the table
       * @param rowCount the total number of rows in the table
       * @returns {number} returns the ratio
       */
      SearchPane.prototype._uniqueRatio = function (bins, rowCount) {
        if (rowCount > 0 && ((this.s.rowData.totalOptions > 0 && !this.s.dt.page.info().serverSide) || (this.s.dt.page.info().serverSide && this.s.tableLength > 0))) {
          return bins / this.s.rowData.totalOptions;
        }
        return 1;
      };
      /**
       * Updates the panes if one of the options to do so has been set to true
       * rather than the filtered message when using viewTotal.
       */
      SearchPane.prototype.updateTable = function () {
        var selectedRows = this.s.dtPane
          .rows({ selected: true })
          .data()
          .toArray()
          .map(function (el) {
            return el.filter;
          });
        this.s.selections = selectedRows;
        this._searchExtras();
      };
      /**
       * Adds the custom options to the pane
       *
       * @returns {Array} Returns the array of rows which have been added to the pane
       */
      SearchPane.prototype._getComparisonRows = function () {
        // Find the appropriate options depending on whether this is a pane for a specific column or a custom pane
        var options = this.s.colOpts.options ? this.s.colOpts.options : this.s.customPaneSettings && this.s.customPaneSettings.options ? this.s.customPaneSettings.options : undefined;
        if (options === undefined) {
          return;
        }
        var allRows = this.s.dt.rows();
        var tableValsTotal = allRows.data().toArray();
        var rows = [];
        // Clear all of the other rows from the pane, only custom options are to be displayed when they are defined
        this.s.dtPane.clear();
        this.s.indexes = [];
        for (var _i = 0, options_1 = options; _i < options_1.length; _i++) {
          var comp = options_1[_i];
          // Initialise the object which is to be placed in the row
          var insert = comp.label !== "" ? comp.label : this.emptyMessage();
          var comparisonObj = {
            className: comp.className,
            display: insert,
            filter: typeof comp.value === "function" ? comp.value : [],
            sort: comp.order !== undefined ? comp.order : insert,
            total: 0,
            type: insert,
          };
          // If a custom function is in place
          if (typeof comp.value === "function") {
            // Count the number of times the function evaluates to true for the original data in the Table
            for (var i = 0; i < tableValsTotal.length; i++) {
              if (comp.value.call(this.s.dt, tableValsTotal[i], allRows[0][i])) {
                comparisonObj.total++;
              }
            }
            // Update the comparisonObj
            if (typeof comparisonObj.filter !== "function") {
              comparisonObj.filter.push(comp.filter);
            }
          }
          rows.push(this.addRow(comparisonObj.display, comparisonObj.filter, comparisonObj.sort, comparisonObj.type, comparisonObj.className, comparisonObj.total));
        }
        return rows;
      };
      SearchPane.prototype._getMessage = function (row) {
        return this.s.dt.i18n("searchPanes.count", this.c.i18n.count).replace(/{total}/g, row.total);
      };
      /**
       * Overridden in SearchPaneViewTotal and SearchPaneCascade to get the number of times a specific value is shown
       *
       * Here it is blanked so that it takes no action
       *
       * @param filter The filter value
       * @returns undefined
       */
      SearchPane.prototype._getShown = function (filter) {
        return undefined;
      };
      /**
       * Get's the pane config appropriate to this class
       *
       * @returns The config needed to create a pane of this type
       */
      SearchPane.prototype._getPaneConfig = function () {
        var _this = this;
        // eslint-disable-next-line no-extra-parens
        var haveScroller = dataTable$2.Scroller;
        var langOpts = this.s.dt.settings()[0].oLanguage;
        langOpts.url = undefined;
        langOpts.sUrl = undefined;
        return {
          columnDefs: [
            {
              className: "dtsp-nameColumn",
              data: "display",
              render: function (data, type, row) {
                if (type === "sort") {
                  return row.sort;
                } else if (type === "type") {
                  return row.type;
                }
                var message = _this._getMessage(row);
                // We are displaying the count in the same columne as the name of the search option.
                // This is so that there is not need to call columns.adjust()
                //  which in turn speeds up the code
                var pill = '<span class="' + _this.classes.pill + '">' + message + "</span>";
                if (!_this.c.viewCount || !_this.s.colOpts.viewCount) {
                  pill = "";
                }
                if (type === "filter") {
                  return typeof data === "string" && data.match(/<[^>]*>/) !== null ? data.replace(/<[^>]*>/g, "") : data;
                }
                return '<div class="' + _this.classes.nameCont + '"><span title="' + (typeof data === "string" && data.match(/<[^>]*>/) !== null ? data.replace(/<[^>]*>/g, "") : data) + '" class="' + _this.classes.name + '">' + data + "</span>" + pill + "</div>";
              },
              targets: 0,
              // Accessing the private datatables property to set type based on the original table.
              // This is null if not defined by the user, meaning that automatic type detection
              //  would take place
              type: this.s.dt.settings()[0].aoColumns[this.s.index] ? this.s.dt.settings()[0].aoColumns[this.s.index]._sManualType : null,
            },
            {
              className: "dtsp-countColumn " + this.classes.badgePill,
              data: "total",
              searchable: false,
              targets: 1,
              visible: false,
            },
          ],
          deferRender: true,
          info: false,
          language: langOpts,
          paging: haveScroller ? true : false,
          scrollX: false,
          scrollY: "200px",
          scroller: haveScroller ? true : false,
          select: true,
          stateSave: this.s.dt.settings()[0].oFeatures.bStateSave ? true : false,
        };
      };
      /**
       * This method allows for changes to the panes and table to be made when a selection or a deselection occurs
       */
      SearchPane.prototype._makeSelection = function () {
        this.updateTable();
        this.s.updating = true;
        this.s.dt.draw();
        this.s.updating = false;
      };
      /**
       * Populates an array with all of the data for the table
       *
       * @param rowIdx The current row index to be compared
       * @param arrayFilter The array that is to be populated with row Details
       * @param settings The DataTable settings object
       * @param bins The bins object that is to be populated with the row counts
       */
      SearchPane.prototype._populatePaneArray = function (rowIdx, arrayFilter, settings, bins) {
        if (bins === void 0) {
          bins = this.s.rowData.bins;
        }
        // Retrieve the rendered data from the cell using the fastData function
        // rather than the cell().render API method for optimisation
        var fastData = settings.fastData;
        if (typeof this.s.colOpts.orthogonal === "string") {
          var rendered = fastData(rowIdx, this.s.index, this.s.colOpts.orthogonal);
          this.s.rowData.filterMap.set(rowIdx, rendered);
          this._addOption(rendered, rendered, rendered, rendered, arrayFilter, bins);
          this.s.rowData.totalOptions++;
        } else {
          var filter = fastData(rowIdx, this.s.index, this.s.colOpts.orthogonal.search);
          // Null and empty string are to be considered the same value
          if (filter === null) {
            filter = "";
          }
          if (typeof filter === "string") {
            filter = filter.replace(/<[^>]*>/g, "");
          }
          this.s.rowData.filterMap.set(rowIdx, filter);
          if (!bins[filter]) {
            bins[filter] = 1;
            this._addOption(filter, fastData(rowIdx, this.s.index, this.s.colOpts.orthogonal.display), fastData(rowIdx, this.s.index, this.s.colOpts.orthogonal.sort), fastData(rowIdx, this.s.index, this.s.colOpts.orthogonal.type), arrayFilter, bins);
            this.s.rowData.totalOptions++;
          } else {
            bins[filter]++;
            this.s.rowData.totalOptions++;
          }
        }
      };
      /**
       * Reloads all of the previous selects into the panes
       *
       * @param loadedFilter The loaded filters from a previous state
       */
      SearchPane.prototype._reloadSelect = function (loadedFilter) {
        // If the state was not saved don't selected any
        if (loadedFilter === undefined) {
          return;
        }
        var idx;
        // For each pane, check that the loadedFilter list exists and is not null,
        // find the id of each search item and set it to be selected.
        for (var i = 0; i < loadedFilter.searchPanes.panes.length; i++) {
          if (loadedFilter.searchPanes.panes[i].id === this.s.index) {
            idx = i;
            break;
          }
        }
        if (idx) {
          var table = this.s.dtPane;
          var rows = table
            .rows({ order: "index" })
            .data()
            .map(function (item) {
              return item.filter !== null ? item.filter.toString() : null;
            })
            .toArray();
          for (var _i = 0, _a = loadedFilter.searchPanes.panes[idx].selected; _i < _a.length; _i++) {
            var filter = _a[_i];
            var id = -1;
            if (filter !== null) {
              id = rows.indexOf(filter.toString());
            }
            if (id > -1) {
              this.s.serverSelecting = true;
              table.row(id).select();
              this.s.serverSelecting = false;
            }
          }
        }
      };
      /**
       * Notes the rows that have been selected within this pane and stores them internally
       *
       * @param notUpdating Whether the panes are updating themselves or not
       */
      SearchPane.prototype._updateSelection = function (notUpdating) {
        var _this = this;
        var processing = function (state) {
          if (DataTable.versionCheck("2")) {
            _this.s.dt.processing(state);
          } else {
            // Legacy v1
            var settings = _this.s.dt.settings()[0];
            var oApi = settings.oApi;
            oApi._fnProcessingDisplay(settings, false);
          }
        };
        var run = function () {
          _this.s.scrollTop = $$5(_this.s.dtPane.table().node()).parent()[0].scrollTop;
          if (_this.s.dt.page.info().serverSide && !_this.s.updating) {
            if (!_this.s.serverSelecting) {
              _this.s.serverSelect = _this.s.dtPane.rows({ selected: true }).data().toArray();
              _this.s.dt.draw(false);
            }
          } else if (notUpdating) {
            _this._makeSelection();
          }
          processing(false);
        };
        processing(true);
        setTimeout(run, 1);
      };
      /**
       * Takes in potentially undetected rows and adds them to the array if they are not yet featured
       *
       * @param filter the filter value of the potential row
       * @param display the display value of the potential row
       * @param sort the sort value of the potential row
       * @param type the type value of the potential row
       * @param arrayFilter the array to be populated
       * @param bins the bins to be populated
       */
      SearchPane.prototype._addOption = function (filter, display, sort, type, arrayFilter, bins) {
        // If the filter is an array then take a note of this, and add the elements to the arrayFilter array
        if (Array.isArray(filter) || filter instanceof dataTable$2.Api) {
          // Convert to an array so that we can work with it
          if (filter instanceof dataTable$2.Api) {
            filter = filter.toArray();
            display = display.toArray();
          }
          if (filter.length === display.length) {
            for (var i = 0; i < filter.length; i++) {
              // If we haven't seen this row before add it
              if (!bins[filter[i]]) {
                bins[filter[i]] = 1;
                arrayFilter.push({
                  display: display[i],
                  filter: filter[i],
                  sort: sort[i],
                  type: type[i],
                });
              }
              // Otherwise just increment the count
              else {
                bins[filter[i]]++;
              }
              this.s.rowData.totalOptions++;
            }
            return;
          }
          throw new Error("display and filter not the same length");
        }
        // If the values were affected by othogonal data and are not an array then check if it is already present
        else if (typeof this.s.colOpts.orthogonal === "string") {
          if (!bins[filter]) {
            bins[filter] = 1;
            arrayFilter.push({
              display: display,
              filter: filter,
              sort: sort,
              type: type,
            });
            this.s.rowData.totalOptions++;
          } else {
            bins[filter]++;
            this.s.rowData.totalOptions++;
          }
        }
        // Otherwise we must just be adding an option
        else {
          arrayFilter.push({
            display: display,
            filter: filter,
            sort: sort,
            type: type,
          });
        }
      };
      /**
       * Method to construct the actual pane.
       *
       * @param selectedRows previously selected Rows to be reselected
       * @param dataIn Data that should be used to populate this pane
       * @param prevEl Reference to the previous element, used to ensure insert is in the correct location
       * @returns boolean to indicate whether this pane was the last one to have a selection made
       */
      SearchPane.prototype._buildPane = function (selectedRows, dataIn, prevEl) {
        var _this = this;
        if (selectedRows === void 0) {
          selectedRows = [];
        }
        if (dataIn === void 0) {
          dataIn = null;
        }
        if (prevEl === void 0) {
          prevEl = null;
        }
        // Aliases
        this.s.selections = [];
        // Other Variables
        var loadedFilter = this.s.dt.state.loaded();
        var row;
        // If the listeners have not been set yet then using the latest state may result in funny errors
        if (this.s.listSet) {
          loadedFilter = this.s.dt.state();
        }
        // If it is not a custom pane in place
        if (this.s.colExists) {
          var idx = -1;
          if (loadedFilter && loadedFilter.searchPanes && loadedFilter.searchPanes.panes) {
            for (var i = 0; i < loadedFilter.searchPanes.panes.length; i++) {
              if (loadedFilter.searchPanes.panes[i].id === this.s.index) {
                idx = i;
                break;
              }
            }
          }
          // Perform checks that do not require populate pane to run
          if ((this.s.colOpts.show === false || (this.s.colOpts.show !== undefined && this.s.colOpts.show !== true)) && idx === -1) {
            this.dom.container.addClass(this.classes.hidden);
            this.s.displayed = false;
            return false;
          } else if (this.s.colOpts.show === true || idx !== -1) {
            this.s.displayed = true;
          }
          if (!this.s.dt.page.info().serverSide && (!dataIn || !dataIn.searchPanes || !dataIn.searchPanes.options)) {
            // Only run populatePane if the data has not been collected yet
            if (this.s.rowData.arrayFilter.length === 0) {
              this.s.rowData.totalOptions = 0;
              this._populatePane();
              this.s.rowData.arrayOriginal = this.s.rowData.arrayFilter;
              this.s.rowData.binsOriginal = this.s.rowData.bins;
            }
            var binLength = Object.keys(this.s.rowData.binsOriginal).length;
            var uniqueRatio = this._uniqueRatio(binLength, this.s.dt.rows()[0].length);
            // Don't show the pane if there isn't enough variance in the data, or there is only 1 entry
            //  for that pane
            if (this.s.displayed === false && ((this.s.colOpts.show === undefined && this.s.colOpts.threshold === null ? uniqueRatio > this.c.threshold : uniqueRatio > this.s.colOpts.threshold) || (this.s.colOpts.show !== true && binLength <= 1))) {
              this.dom.container.addClass(this.classes.hidden);
              this.s.displayed = false;
              return;
            }
            this.dom.container.addClass(this.classes.show);
            this.s.displayed = true;
          } else if (dataIn && dataIn.searchPanes && dataIn.searchPanes.options) {
            this._serverPopulate(dataIn);
          }
        } else {
          this.s.displayed = true;
        }
        // If the variance is accceptable then display the search pane
        this._displayPane();
        if (!this.s.listSet) {
          // Here, when the state is loaded if the data object on the original table is empty,
          //  then a state.clear() must have occurred, so delete all of the panes tables state objects too.
          this.dom.dtP.on("stateLoadParams.dtsp", function (e, settings, data) {
            if ($$5.isEmptyObject(_this.s.dt.state.loaded())) {
              $$5.each(data, function (index) {
                delete data[index];
              });
            }
          });
        }
        // Add the container to the document in its original location
        if (prevEl !== null && this.dom.panesContainer.has(prevEl).length > 0) {
          this.dom.container.insertAfter(prevEl);
        } else {
          this.dom.panesContainer.prepend(this.dom.container);
        }
        // Declare the datatable for the pane
        var errMode = $$5.fn.dataTable.ext.errMode;
        $$5.fn.dataTable.ext.errMode = "none";
        // eslint-disable-next-line no-extra-parens
        // For async loading of a DataTable (e.g. language file)
        // we need to set the select style to make sure the event
        // handlers are added.
        this.dom.dtP.on("init.dt", function (e, s) {
          var dt = _this.dom.dtP.DataTable();
          var style = dt.select.style();
          dt.select.style(style);
        });
        this.s.dtPane = this.dom.dtP.DataTable(
          $$5.extend(
            true,
            this._getPaneConfig(),
            this.c.dtOpts,
            this.s.colOpts ? this.s.colOpts.dtOpts : {},
            this.s.colOpts.options || !this.s.colExists
              ? {
                  createdRow: function (row, data) {
                    $$5(row).addClass(data.className);
                  },
                }
              : undefined,
            this.s.customPaneSettings !== null && this.s.customPaneSettings.dtOpts ? this.s.customPaneSettings.dtOpts : {},
            $$5.fn.dataTable.versionCheck("2")
              ? {
                  layout: {
                    bottomStart: null,
                    bottomEnd: null,
                    topStart: null,
                    topEnd: null,
                  },
                }
              : { dom: "t" }
          )
        );
        this.dom.dtP.addClass(this.classes.table);
        // Getting column titles is a little messy
        var headerText = "Custom Pane";
        if (this.s.customPaneSettings && this.s.customPaneSettings.header) {
          headerText = this.s.customPaneSettings.header;
        } else if (this.s.colOpts.header) {
          headerText = this.s.colOpts.header;
        } else if (this.s.colExists) {
          headerText = $$5.fn.dataTable.versionCheck("2") ? this.s.dt.column(this.s.index).title() : this.s.dt.settings()[0].aoColumns[this.s.index].sTitle;
        }
        headerText = this._escapeHTML(headerText);
        this.dom.searchBox.attr("placeholder", headerText);
        $$5.fn.dataTable.ext.errMode = errMode;
        // If it is not a custom pane
        if (this.s.colExists) {
          // Add all of the search options to the pane
          for (var j = 0, jen = this.s.rowData.arrayFilter.length; j < jen; j++) {
            if (this.s.dt.page.info().serverSide) {
              row = this.addRow(this.s.rowData.arrayFilter[j].display, this.s.rowData.arrayFilter[j].filter, this.s.rowData.arrayFilter[j].sort, this.s.rowData.arrayFilter[j].type);
              for (var _i = 0, _a = this.s.serverSelect; _i < _a.length; _i++) {
                var option = _a[_i];
                if (option.filter === this.s.rowData.arrayFilter[j].filter) {
                  this.s.serverSelecting = true;
                  row.select();
                  this.s.serverSelecting = false;
                }
              }
            } else if (!this.s.dt.page.info().serverSide && this.s.rowData.arrayFilter[j]) {
              this.addRow(this.s.rowData.arrayFilter[j].display, this.s.rowData.arrayFilter[j].filter, this.s.rowData.arrayFilter[j].sort, this.s.rowData.arrayFilter[j].type);
            } else if (!this.s.dt.page.info().serverSide) {
              // Just pass an empty string as the message will be calculated based on that in addRow()
              this.addRow("", "", "", "");
            }
          }
        }
        // If there are custom options set or it is a custom pane then get them
        if (this.s.colOpts.options || (this.s.customPaneSettings && this.s.customPaneSettings.options)) {
          this._getComparisonRows();
        }
        // Display the pane
        this.s.dtPane.draw();
        this.s.dtPane.table().node().parentNode.scrollTop = this.s.scrollTop;
        this.adjustTopRow();
        this.setListeners();
        this.s.listSet = true;
        for (var _b = 0, selectedRows_1 = selectedRows; _b < selectedRows_1.length; _b++) {
          var selection = selectedRows_1[_b];
          if (selection) {
            for (var _c = 0, _d = this.s.dtPane.rows().indexes().toArray(); _c < _d.length; _c++) {
              row = _d[_c];
              if (this.s.dtPane.row(row).data() && selection.filter === this.s.dtPane.row(row).data().filter) {
                // If this is happening when serverSide processing is happening then
                //  different behaviour is needed
                if (this.s.dt.page.info().serverSide) {
                  this.s.serverSelecting = true;
                  this.s.dtPane.row(row).select();
                  this.s.serverSelecting = false;
                } else {
                  this.s.dtPane.row(row).select();
                }
              }
            }
          }
        }
        //  If SSP and the table is ready, apply the search for the pane
        if (this.s.dt.page.info().serverSide) {
          this.s.dtPane.search(this.dom.searchBox.val()).draw();
        }
        if (((this.c.initCollapsed && this.s.colOpts.initCollapsed !== false) || this.s.colOpts.initCollapsed) && ((this.c.collapse && this.s.colOpts.collapse !== false) || this.s.colOpts.collapse)) {
          // If the pane has not initialised yet then we need to wait for it to do so before collapsing
          // Otherwise the container that the class is added to does not exist
          if (this.s.dtPane.settings()[0]._bInitComplete) {
            this.collapse();
          } else {
            this.s.dtPane.one("init", function () {
              return _this.collapse();
            });
          }
        }
        // Reload the selection, searchbox entry and ordering from the previous state
        // Need to check here if SSP that this is the first draw, otherwise it will infinite loop
        if (loadedFilter && loadedFilter.searchPanes && loadedFilter.searchPanes.panes && (!dataIn || dataIn.draw === 1)) {
          this._reloadSelect(loadedFilter);
          for (var _e = 0, _f = loadedFilter.searchPanes.panes; _e < _f.length; _e++) {
            var pane = _f[_e];
            if (pane.id === this.s.index) {
              // Save some time by only triggering an input if there is a value
              if (pane.searchTerm && pane.searchTerm.length > 0) {
                this.dom.searchBox.val(pane.searchTerm).trigger("input");
              }
              if (pane.order) {
                this.s.dtPane.order(pane.order).draw();
              }
              // Is the pane to be hidden or shown?
              if (pane.collapsed) {
                this.collapse();
              } else {
                this.show();
              }
            }
          }
        }
        return true;
      };
      /**
       * Appends all of the HTML elements to their relevant parent Elements
       */
      SearchPane.prototype._displayPane = function () {
        // Empty everything to start again
        this.dom.dtP.empty();
        this.dom.topRow.empty().addClass(this.classes.topRow);
        // If there are more than 3 columns defined then make there be a smaller gap between the panes
        if (parseInt(this.c.layout.split("-")[1], 10) > 3) {
          this.dom.container.addClass(this.classes.smallGap);
        }
        this.dom.topRow.addClass(this.classes.subRowsContainer).append(this.dom.upper.append(this.dom.searchCont)).append(this.dom.lower.append(this.dom.buttonGroup));
        // If no selections have been made in the pane then disable the clear button
        if (
          this.c.dtOpts.searching === false ||
          (this.s.colOpts.dtOpts && this.s.colOpts.dtOpts.searching === false) ||
          !this.c.controls ||
          !this.s.colOpts.controls ||
          (this.s.customPaneSettings && this.s.customPaneSettings.dtOpts && this.s.customPaneSettings.dtOpts.searching !== undefined && !this.s.customPaneSettings.dtOpts.searching)
        ) {
          this.dom.searchBox.removeClass(this.classes.paneInputButton).addClass(this.classes.disabledButton).attr("disabled", "true");
        }
        this.dom.searchBox.appendTo(this.dom.searchCont);
        // Create the contents of the searchCont div. Worth noting that this function will change when using semantic ui
        this._searchContSetup();
        // If the clear button is allowed to show then display it
        if (this.c.clear && this.c.controls && this.s.colOpts.controls) {
          this.dom.clear.appendTo(this.dom.buttonGroup);
        }
        if (this.c.orderable && this.s.colOpts.orderable && this.c.controls && this.s.colOpts.controls) {
          this.dom.nameButton.appendTo(this.dom.buttonGroup);
        }
        // If the count column is hidden then don't display the ordering button for it
        if (this.c.viewCount && this.s.colOpts.viewCount && this.c.orderable && this.s.colOpts.orderable && this.c.controls && this.s.colOpts.controls) {
          this.dom.countButton.appendTo(this.dom.buttonGroup);
        }
        if (((this.c.collapse && this.s.colOpts.collapse !== false) || this.s.colOpts.collapse) && this.c.controls && this.s.colOpts.controls) {
          this.dom.collapseButton.appendTo(this.dom.buttonGroup);
        }
        this.dom.container.prepend(this.dom.topRow).append(this.dom.dtP).show();
      };
      /**
       * Escape html characters within a string
       *
       * @param txt the string to be escaped
       * @returns the escaped string
       */
      SearchPane.prototype._escapeHTML = function (txt) {
        return txt
          .toString()
          .replace(/&amp;/g, "&")
          .replace(/&lt;/g, "<")
          .replace(/&gt;/g, ">")
          .replace(/&quot;/g, '"');
      };
      /**
       * Gets the options for the row for the customPanes
       *
       * @returns {object} The options for the row extended to include the options from the user.
       */
      SearchPane.prototype._getBonusOptions = function () {
        // We need to reset the thresholds as if they have a value in colOpts then that value will be used
        var defaultMutator = {
          threshold: null,
        };
        return $$5.extend(true, {}, SearchPane.defaults, defaultMutator, this.c ? this.c : {});
      };
      /**
       * Gets the options for the row for the customPanes
       *
       * @returns {object} The options for the row extended to include the options from the user.
       */
      SearchPane.prototype._getOptions = function () {
        var table = this.s.dt;
        // We need to reset the thresholds as if they have a value in colOpts then that value will be used
        var defaultMutator = {
          collapse: null,
          emptyMessage: false,
          initCollapsed: null,
          threshold: null,
        };
        var columnOptions = table.settings()[0].aoColumns[this.s.index].searchPanes;
        var colOpts = $$5.extend(true, {}, SearchPane.defaults, defaultMutator, columnOptions);
        if (columnOptions && columnOptions.hideCount && columnOptions.viewCount === undefined) {
          colOpts.viewCount = !columnOptions.hideCount;
        }
        return colOpts;
      };
      /**
       * Fill the array with the values that are currently being displayed in the table
       */
      SearchPane.prototype._populatePane = function () {
        this.s.rowData.arrayFilter = [];
        this.s.rowData.bins = {};
        var settings = this.s.dt.context[0];
        if (!this.s.dt.page.info().serverSide) {
          for (var _i = 0, _a = this.s.dt.rows().indexes().toArray(); _i < _a.length; _i++) {
            var index = _a[_i];
            this._populatePaneArray(index, this.s.rowData.arrayFilter, settings);
          }
        }
      };
      /**
       * This method decides whether a row should contribute to the pane or not
       *
       * @param filter the value that the row is to be filtered on
       * @param dataIndex the row index
       */
      SearchPane.prototype._search = function (filter, dataIndex) {
        var colOpts = this.s.colOpts;
        var table = this.s.dt;
        // For each item selected in the pane, check if it is available in the cell
        for (var _i = 0, _a = this.s.selections; _i < _a.length; _i++) {
          var colSelect = _a[_i];
          if (typeof colSelect === "string" && typeof filter === "string") {
            // The filter value will not have the &amp; in place but a &,
            // so we need to do a replace to make sure that they will match
            colSelect = this._escapeHTML(colSelect);
          }
          // if the filter is an array then is the column present in it
          if (Array.isArray(filter)) {
            if (colOpts.combiner === "and") {
              if (!filter.includes(colSelect)) {
                return false;
              }
            } else if (filter.includes(colSelect)) {
              return true;
            }
          }
          // if the filter is a function then does it meet the criteria of that function or not
          else if (typeof colSelect === "function") {
            if (colSelect.call(table, table.row(dataIndex).data(), dataIndex)) {
              if (colOpts.combiner === "or") {
                return true;
              }
            }
            // If the combiner is an "and" then we need to check against all possible selections
            // so if it fails here then the and is not met and return false
            else if (colOpts.combiner === "and") {
              return false;
            }
          }
          // otherwise if the two filter values are equal then return true
          else if (
            filter === colSelect ||
            // Loose type checking incase number type in column comparing to a string
            // eslint-disable-next-line eqeqeq
            (!(typeof filter === "string" && filter.length === 0) && filter == colSelect) ||
            (colSelect === null && typeof filter === "string" && filter === "")
          ) {
            return true;
          }
        }
        // If the combiner is an and then we need to check against all possible selections
        // so return true here if so because it would have returned false earlier if it had failed
        if (colOpts.combiner === "and") {
          return true;
        }
        // Otherwise it hasn't matched with anything by this point so it must be false
        return false;
      };
      /**
       * Creates the contents of the searchCont div
       *
       * NOTE This is overridden when semantic ui styling in order to integrate the search button into the text box.
       */
      SearchPane.prototype._searchContSetup = function () {
        if (this.c.controls && this.s.colOpts.controls) {
          this.dom.searchButton.appendTo(this.dom.searchLabelCont);
        }
        if (!(this.c.dtOpts.searching === false || this.s.colOpts.dtOpts.searching === false || (this.s.customPaneSettings && this.s.customPaneSettings.dtOpts && this.s.customPaneSettings.dtOpts.searching !== undefined && !this.s.customPaneSettings.dtOpts.searching))) {
          this.dom.searchLabelCont.appendTo(this.dom.searchCont);
        }
      };
      /**
       * Adds outline to the pane when a selection has been made
       */
      SearchPane.prototype._searchExtras = function () {
        var updating = this.s.updating;
        this.s.updating = true;
        var filters = this.s.dtPane.rows({ selected: true }).data().pluck("filter").toArray();
        var nullIndex = filters.indexOf(this.emptyMessage());
        var container = $$5(this.s.dtPane.table().container());
        // If null index is found then search for empty cells as a filter.
        if (nullIndex > -1) {
          filters[nullIndex] = "";
        }
        // If a filter has been applied then outline the respective pane, remove it when it no longer is.
        if (filters.length > 0) {
          container.addClass(this.classes.selected);
        } else if (filters.length === 0) {
          container.removeClass(this.classes.selected);
        }
        this.s.updating = updating;
      };
      SearchPane.version = "2.1.2";
      SearchPane.classes = {
        bordered: "dtsp-bordered",
        buttonGroup: "dtsp-buttonGroup",
        buttonSub: "dtsp-buttonSub",
        caret: "dtsp-caret",
        clear: "dtsp-clear",
        clearAll: "dtsp-clearAll",
        clearButton: "clearButton",
        collapseAll: "dtsp-collapseAll",
        collapseButton: "dtsp-collapseButton",
        container: "dtsp-searchPane",
        countButton: "dtsp-countButton",
        disabledButton: "dtsp-disabledButton",
        hidden: "dtsp-hidden",
        hide: "dtsp-hide",
        layout: "dtsp-",
        name: "dtsp-name",
        nameButton: "dtsp-nameButton",
        nameCont: "dtsp-nameCont",
        narrow: "dtsp-narrow",
        paneButton: "dtsp-paneButton",
        paneInputButton: "dtsp-paneInputButton",
        pill: "dtsp-pill",
        rotated: "dtsp-rotated",
        search: "dtsp-search",
        searchCont: "dtsp-searchCont",
        searchIcon: "dtsp-searchIcon",
        searchLabelCont: "dtsp-searchButtonCont",
        selected: "dtsp-selected",
        smallGap: "dtsp-smallGap",
        subRow1: "dtsp-subRow1",
        subRow2: "dtsp-subRow2",
        subRowsContainer: "dtsp-subRowsContainer",
        title: "dtsp-title",
        topRow: "dtsp-topRow",
      };
      // Define SearchPanes default options
      SearchPane.defaults = {
        clear: true,
        collapse: true,
        combiner: "or",
        container: function (dt) {
          return dt.table().container();
        },
        controls: true,
        dtOpts: {},
        emptyMessage: null,
        hideCount: false,
        i18n: {
          clearPane: "&times;",
          count: "{total}",
          emptyMessage: "<em>No data</em>",
        },
        initCollapsed: false,
        layout: "auto",
        name: undefined,
        orderable: true,
        orthogonal: {
          display: "display",
          filter: "filter",
          hideCount: false,
          search: "filter",
          show: undefined,
          sort: "sort",
          threshold: 0.6,
          type: "type",
          viewCount: true,
        },
        preSelect: [],
        threshold: 0.6,
        viewCount: true,
      };
      return SearchPane;
    })();

    var __extends$4 =
      (window && window.__extends) ||
      (function () {
        var extendStatics = function (d, b) {
          extendStatics =
            Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array &&
              function (d, b) {
                d.__proto__ = b;
              }) ||
            function (d, b) {
              for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
            };
          return extendStatics(d, b);
        };
        return function (d, b) {
          extendStatics(d, b);
          function __() {
            this.constructor = d;
          }
          d.prototype = b === null ? Object.create(b) : ((__.prototype = b.prototype), new __());
        };
      })();
    var SearchPaneST = /** @class */ (function (_super) {
      __extends$4(SearchPaneST, _super);
      function SearchPaneST(paneSettings, opts, index, panesContainer, panes) {
        return _super.call(this, paneSettings, opts, index, panesContainer, panes) || this;
      }
      /**
       * When server-side processing is enabled, SP will remove rows and then readd them,
       * resulting in Select's reference to the last selected cell being lost.
       * This function is provided to update that reference.
       *
       * @returns Function
       */
      SearchPaneST.prototype._emptyPane = function () {
        var dt = this.s.dtPane;
        if (DataTable.versionCheck("2")) {
          var last = dt.select.last();
          var selectedIndex_1;
          if (last && dt.row(last.row).any()) {
            selectedIndex_1 = dt.row(last.row).data().index;
          }
          dt.rows().remove();
          return function () {
            if (selectedIndex_1 !== undefined) {
              var idx = dt
                .row(function (i, data) {
                  return data.index === selectedIndex_1;
                })
                .index();
              dt.select.last({ row: idx, column: 0 });
            }
          };
        }
        dt.rows().remove();
        return function () {};
      };
      /**
       * Populates the SearchPane based off of the data that has been recieved from the server
       *
       * This method overrides SearchPane's _serverPopulate() method
       *
       * @param dataIn The data that has been sent from the server
       */
      SearchPaneST.prototype._serverPopulate = function (dataIn) {
        var selection, row, data;
        this.s.rowData.binsShown = {};
        this.s.rowData.arrayFilter = [];
        if (dataIn.tableLength !== undefined) {
          this.s.tableLength = dataIn.tableLength;
          this.s.rowData.totalOptions = this.s.tableLength;
        } else if (this.s.tableLength === null || this.s.dt.rows()[0].length > this.s.tableLength) {
          this.s.tableLength = this.s.dt.rows()[0].length;
          this.s.rowData.totalOptions = this.s.tableLength;
        }
        var colTitle = this.s.dt.column(this.s.index).dataSrc();
        // If there is SP data for this column add it to the data array and bin
        if (dataIn.searchPanes.options[colTitle] !== undefined) {
          for (var _i = 0, _a = dataIn.searchPanes.options[colTitle]; _i < _a.length; _i++) {
            var dataPoint = _a[_i];
            this.s.rowData.arrayFilter.push({
              display: dataPoint.label,
              filter: dataPoint.value,
              shown: +dataPoint.count,
              sort: dataPoint.label,
              total: +dataPoint.total,
              type: dataPoint.label,
            });
            this.s.rowData.binsShown[dataPoint.value] = +dataPoint.count;
            this.s.rowData.bins[dataPoint.value] = +dataPoint.total;
          }
        }
        var binLength = Object.keys(this.s.rowData.bins).length;
        var uniqueRatio = this._uniqueRatio(binLength, this.s.tableLength);
        // Don't show the pane if there isnt enough variance in the data, or there is only 1 entry for that pane
        if (!this.s.colOpts.show && this.s.displayed === false && ((this.s.colOpts.show === undefined && this.s.colOpts.threshold === null ? uniqueRatio > this.c.threshold : uniqueRatio > this.s.colOpts.threshold) || (this.s.colOpts.show !== true && binLength <= 1))) {
          this.dom.container.addClass(this.classes.hidden);
          this.s.displayed = false;
          return;
        }
        // Store the original data
        this.s.rowData.arrayOriginal = this.s.rowData.arrayFilter;
        this.s.rowData.binsOriginal = this.s.rowData.bins;
        // Flag this pane as being displayed
        this.s.displayed = true;
        // If the pane exists
        if (this.s.dtPane) {
          // Not the selections that have been made and remove all of the rows
          var selected = this.s.serverSelect;
          var reselect = this._emptyPane();
          // Add the rows that are to be shown into the pane
          for (var _b = 0, _c = this.s.rowData.arrayFilter; _b < _c.length; _b++) {
            data = _c[_b];
            if (this._shouldAddRow(data)) {
              row = this.addRow(data.display, data.filter, data.sort, data.type);
              // Select the row if it was selected before
              for (var i = 0; i < selected.length; i++) {
                selection = selected[i];
                if (selection.filter === data.filter) {
                  // This flag stops another request being made to the server
                  this.s.serverSelecting = true;
                  row.select();
                  this.s.serverSelecting = false;
                  // Remove the selection from the to select list and add it to the selected list
                  selected.splice(i, 1);
                  this.s.selections.push(data.filter);
                  break;
                }
              }
            }
          }
          // Remake any selections that are no longer present
          for (var _d = 0, selected_1 = selected; _d < selected_1.length; _d++) {
            selection = selected_1[_d];
            for (var _e = 0, _f = this.s.rowData.arrayOriginal; _e < _f.length; _e++) {
              data = _f[_e];
              if (data.filter === selection.filter) {
                row = this.addRow(data.display, data.filter, data.sort, data.type);
                this.s.serverSelecting = true;
                row.select();
                this.s.serverSelecting = false;
                this.s.selections.push(data.filter);
              }
            }
          }
          // Store the selected rows
          this.s.serverSelect = this.s.dtPane.rows({ selected: true }).data().toArray();
          // Update the pane
          this.s.dtPane.draw();
          reselect();
        }
      };
      /**
       * This method updates the rows and their data within the SearchPanes
       *
       * SearchPaneCascade overrides this method
       */
      SearchPaneST.prototype.updateRows = function () {
        if (!this.s.dt.page.info().serverSide) {
          // Get the latest count values from the table
          this.s.rowData.binsShown = {};
          for (var _i = 0, _a = this.s.dt.rows({ search: "applied" }).indexes().toArray(); _i < _a.length; _i++) {
            var index = _a[_i];
            this._updateShown(index, this.s.dt.settings()[0], this.s.rowData.binsShown);
          }
        }
        var _loop_1 = function (row) {
          row.shown = typeof this_1.s.rowData.binsShown[row.filter] === "number" ? this_1.s.rowData.binsShown[row.filter] : 0;
          this_1.s.dtPane
            .row(function (idx, data) {
              return data && data.index === row.index;
            })
            .data(row);
        };
        var this_1 = this;
        // Update the rows data to show the current counts
        for (var _b = 0, _c = this.s.dtPane.rows().data().toArray(); _b < _c.length; _b++) {
          var row = _c[_b];
          _loop_1(row);
        }
        // Show updates in the pane
        this.s.dtPane.draw();
        this.s.dtPane.table().node().parentNode.scrollTop = this.s.scrollTop;
      };
      /**
       * Remove functionality from makeSelection - needs to be more advanced when tracking selections
       */
      SearchPaneST.prototype._makeSelection = function () {
        return;
      };
      /**
       * Blank method to remove reloading of selected rows - needs to be more advanced when tracking selections
       */
      SearchPaneST.prototype._reloadSelect = function () {
        return;
      };
      /**
       * Decides if a row should be added when being added from the server
       *
       * Overridden by SearchPaneCascade
       *
       * @param data the row data
       * @returns boolean indicating if the row should be added or not
       */
      SearchPaneST.prototype._shouldAddRow = function (data) {
        return true;
      };
      /**
       * Updates the server selection list where appropriate
       */
      SearchPaneST.prototype._updateSelection = function () {
        if (this.s.dt.page.info().serverSide && !this.s.updating && !this.s.serverSelecting) {
          this.s.serverSelect = this.s.dtPane.rows({ selected: true }).data().toArray();
        }
      };
      /**
       * Used when binning the data for a column
       *
       * @param rowIdx The current row that is to be added to the bins
       * @param settings The datatables settings object
       * @param bins The bins object that is to be incremented
       */
      SearchPaneST.prototype._updateShown = function (rowIdx, settings, bins) {
        if (bins === void 0) {
          bins = this.s.rowData.binsShown;
        }
        var orth = typeof this.s.colOpts.orthogonal === "string" ? this.s.colOpts.orthogonal : this.s.colOpts.orthogonal.search;
        var fastData = this.s.dt.settings()[0].fastData;
        var filter = fastData(rowIdx, this.s.index, orth);
        var add = function (f) {
          if (!bins[f]) {
            bins[f] = 1;
          } else {
            bins[f]++;
          }
        };
        if (Array.isArray(filter)) {
          for (var _i = 0, filter_1 = filter; _i < filter_1.length; _i++) {
            var f = filter_1[_i];
            add(f);
          }
        } else {
          add(filter);
        }
      };
      return SearchPaneST;
    })(SearchPane);

    var __extends$3 =
      (window && window.__extends) ||
      (function () {
        var extendStatics = function (d, b) {
          extendStatics =
            Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array &&
              function (d, b) {
                d.__proto__ = b;
              }) ||
            function (d, b) {
              for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
            };
          return extendStatics(d, b);
        };
        return function (d, b) {
          extendStatics(d, b);
          function __() {
            this.constructor = d;
          }
          d.prototype = b === null ? Object.create(b) : ((__.prototype = b.prototype), new __());
        };
      })();
    var $$4;
    function setJQuery$3(jq) {
      $$4 = jq;
    }
    var SearchPaneViewTotal = /** @class */ (function (_super) {
      __extends$3(SearchPaneViewTotal, _super);
      function SearchPaneViewTotal(paneSettings, opts, index, panesContainer, panes) {
        var _this = this;
        var override = {
          i18n: {
            countFiltered: "{shown} ({total})",
          },
        };
        _this = _super.call(this, paneSettings, $$4.extend(override, opts), index, panesContainer, panes) || this;
        return _this;
      }
      /**
       * Gets the message that is to be used to indicate the count for each SearchPane row
       *
       * This method overrides _getMessage() in SearchPane and is overridden by SearchPaneCascadeViewTotal
       *
       * @param row The row object that is being processed
       * @returns string - the message that is to be shown for the count of each entry
       */
      SearchPaneViewTotal.prototype._getMessage = function (row) {
        var countMessage = this.s.dt.i18n("searchPanes.count", this.c.i18n.count);
        var filteredMessage = this.s.dt.i18n("searchPanes.countFiltered", this.c.i18n.countFiltered);
        return (this.s.filteringActive ? filteredMessage : countMessage).replace(/{total}/g, row.total).replace(/{shown}/g, row.shown);
      };
      /**
       * Overrides the blank method in SearchPane to return the number of times a given value is currently being displayed
       *
       * @param filter The filter value
       * @returns number - The number of times the value is shown
       */
      SearchPaneViewTotal.prototype._getShown = function (filter) {
        return this.s.rowData.binsShown && this.s.rowData.binsShown[filter] ? this.s.rowData.binsShown[filter] : 0;
      };
      return SearchPaneViewTotal;
    })(SearchPaneST);

    var __extends$2 =
      (window && window.__extends) ||
      (function () {
        var extendStatics = function (d, b) {
          extendStatics =
            Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array &&
              function (d, b) {
                d.__proto__ = b;
              }) ||
            function (d, b) {
              for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
            };
          return extendStatics(d, b);
        };
        return function (d, b) {
          extendStatics(d, b);
          function __() {
            this.constructor = d;
          }
          d.prototype = b === null ? Object.create(b) : ((__.prototype = b.prototype), new __());
        };
      })();
    var $$3;
    function setJQuery$2(jq) {
      $$3 = jq;
    }
    var SearchPaneCascade = /** @class */ (function (_super) {
      __extends$2(SearchPaneCascade, _super);
      function SearchPaneCascade(paneSettings, opts, index, panesContainer, panes) {
        var _this = this;
        var override = {
          i18n: {
            count: "{shown}",
          },
        };
        _this = _super.call(this, paneSettings, $$3.extend(override, opts), index, panesContainer, panes) || this;
        return _this;
      }
      /**
       * This method updates the rows and their data within the SearchPanes
       *
       * This overrides the method in SearchPane
       */
      SearchPaneCascade.prototype.updateRows = function () {
        // Note the currently selected values in the pane and remove all of the rows
        var selected = this.s.dtPane.rows({ selected: true }).data().toArray();
        var selection;
        if (this.s.colOpts.options || (this.s.customPaneSettings && this.s.customPaneSettings.options)) {
          // If there are custom options set or it is a custom pane then get them
          this._getComparisonRows();
          var rows = this.s.dtPane.rows().toArray()[0];
          for (var i = 0; i < rows.length; i++) {
            var row = this.s.dtPane.row(rows[i]);
            var rowData = row.data();
            if (rowData === undefined) {
              continue;
            }
            if (rowData.shown === 0) {
              row.remove();
              rows = this.s.dtPane.rows().toArray()[0];
              i--;
              continue;
            }
            for (var _i = 0, selected_1 = selected; _i < selected_1.length; _i++) {
              selection = selected_1[_i];
              if (rowData.filter === selection.filter) {
                row.select();
                selected.splice(i, 1);
                this.s.selections.push(rowData.filter);
                break;
              }
            }
          }
        } else {
          if (!this.s.dt.page.info().serverSide) {
            // Get the latest count values from the table
            this._activePopulatePane();
            this.s.rowData.binsShown = {};
            for (var _a = 0, _b = this.s.dt.rows({ search: "applied" }).indexes().toArray(); _a < _b.length; _a++) {
              var index = _b[_a];
              this._updateShown(index, this.s.dt.settings()[0], this.s.rowData.binsShown);
            }
          }
          this.s.dtPane.rows().remove();
          // Go over all of the rows that could be displayed
          for (var _c = 0, _d = this.s.rowData.arrayFilter; _c < _d.length; _c++) {
            var data = _d[_c];
            // Cascade - If there are no rows present in the table don't show the option
            if (data.shown === 0) {
              continue;
            }
            // Add the row to the pane
            var newRow = this.addRow(data.display, data.filter, data.sort, data.type, undefined);
            // Check if this row was selected
            for (var j = 0; j < selected.length; j++) {
              var selectedRow = selected[j];
              if (selectedRow.filter === data.filter) {
                newRow.select();
                // Remove the row from the to find list and then add it to the selections list
                selected.splice(j, 1);
                this.s.selections.push(data.filter);
                break;
              }
            }
          }
          // Add all of the rows that were previously selected but aren't any more
          for (var _e = 0, selected_2 = selected; _e < selected_2.length; _e++) {
            selection = selected_2[_e];
            for (var _f = 0, _g = this.s.rowData.arrayOriginal; _f < _g.length; _f++) {
              var origData = _g[_f];
              if (origData.filter === selection.filter) {
                var addedRow = this.addRow(origData.display, origData.filter, origData.sort, origData.type, undefined);
                addedRow.select();
                this.s.selections.push(origData.filter);
              }
            }
          }
        }
        // Show updates in the pane
        this.s.dtPane.draw();
        this.s.dtPane.table().node().parentNode.scrollTop = this.s.scrollTop;
        // If client side updated the tables results
        if (!this.s.dt.page.info().serverSide) {
          this.s.dt.draw(false);
        }
      };
      /**
       * Fill the array with the values that are currently being displayed in the table
       */
      SearchPaneCascade.prototype._activePopulatePane = function () {
        this.s.rowData.arrayFilter = [];
        this.s.rowData.bins = {};
        var settings = this.s.dt.settings()[0];
        if (!this.s.dt.page.info().serverSide) {
          for (var _i = 0, _a = this.s.dt.rows({ search: "applied" }).indexes().toArray(); _i < _a.length; _i++) {
            var index = _a[_i];
            this._populatePaneArray(index, this.s.rowData.arrayFilter, settings);
          }
        }
      };
      SearchPaneCascade.prototype._getComparisonRows = function () {
        // Find the appropriate options depending on whether this is a pane for a specific column or a custom pane
        var options = this.s.colOpts.options ? this.s.colOpts.options : this.s.customPaneSettings && this.s.customPaneSettings.options ? this.s.customPaneSettings.options : undefined;
        if (options === undefined) {
          return;
        }
        var allRows = this.s.dt.rows();
        var shownRows = this.s.dt.rows({ search: "applied" });
        var tableValsTotal = allRows.data().toArray();
        var tableValsShown = shownRows.data().toArray();
        var rows = [];
        // Clear all of the other rows from the pane, only custom options are to be displayed when they are defined
        this.s.dtPane.clear();
        this.s.indexes = [];
        for (var _i = 0, options_1 = options; _i < options_1.length; _i++) {
          var comp = options_1[_i];
          // Initialise the object which is to be placed in the row
          var insert = comp.label !== "" ? comp.label : this.emptyMessage();
          var comparisonObj = {
            className: comp.className,
            display: insert,
            filter: typeof comp.value === "function" ? comp.value : [],
            shown: 0,
            sort: insert,
            total: 0,
            type: insert,
          };
          // If a custom function is in place
          if (typeof comp.value === "function") {
            // Count the number of times the function evaluates to true for the original data in the Table
            for (var i = 0; i < tableValsTotal.length; i++) {
              if (comp.value.call(this.s.dt, tableValsTotal[i], allRows[0][i])) {
                comparisonObj.total++;
              }
            }
            for (var j = 0; j < tableValsShown.length; j++) {
              if (comp.value.call(this.s.dt, tableValsShown[j], shownRows[0][j])) {
                comparisonObj.shown++;
              }
            }
            // Update the comparisonObj
            if (typeof comparisonObj.filter !== "function") {
              comparisonObj.filter.push(comp.filter);
            }
          }
          rows.push(this.addRow(comparisonObj.display, comparisonObj.filter, comparisonObj.sort, comparisonObj.type, comparisonObj.className, comparisonObj.total, comparisonObj.shown));
        }
        return rows;
      };
      /**
       * Gets the message that is to be used to indicate the count for each SearchPane row
       *
       * This method overrides _getMessage() in SearchPane and is overridden by SearchPaneCascadeViewTotal
       *
       * @param row The row object that is being processed
       * @returns string - the message that is to be shown for the count of each entry
       */
      SearchPaneCascade.prototype._getMessage = function (row) {
        return this.s.dt
          .i18n("searchPanes.count", this.c.i18n.count)
          .replace(/{total}/g, row.total)
          .replace(/{shown}/g, row.shown);
      };
      /**
       * Overrides the blank method in SearchPane to return the number of times a given value is currently being displayed
       *
       * @param filter The filter value
       * @returns number - The number of times the value is shown
       */
      SearchPaneCascade.prototype._getShown = function (filter) {
        return this.s.rowData.binsShown && this.s.rowData.binsShown[filter] ? this.s.rowData.binsShown[filter] : 0;
      };
      /**
       * Decides if a row should be added when being added from the server
       *
       * Overrides method in by SearchPaneST
       *
       * @param data the row data
       * @returns boolean indicating if the row should be added or not
       */
      SearchPaneCascade.prototype._shouldAddRow = function (data) {
        return data.shown > 0;
      };
      return SearchPaneCascade;
    })(SearchPaneST);

    var __extends$1 =
      (window && window.__extends) ||
      (function () {
        var extendStatics = function (d, b) {
          extendStatics =
            Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array &&
              function (d, b) {
                d.__proto__ = b;
              }) ||
            function (d, b) {
              for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
            };
          return extendStatics(d, b);
        };
        return function (d, b) {
          extendStatics(d, b);
          function __() {
            this.constructor = d;
          }
          d.prototype = b === null ? Object.create(b) : ((__.prototype = b.prototype), new __());
        };
      })();
    var $$2;
    function setJQuery$1(jq) {
      $$2 = jq;
    }
    var SearchPaneCascadeViewTotal = /** @class */ (function (_super) {
      __extends$1(SearchPaneCascadeViewTotal, _super);
      function SearchPaneCascadeViewTotal(paneSettings, opts, index, panesContainer, panes) {
        var _this = this;
        var override = {
          i18n: {
            count: "{total}",
            countFiltered: "{shown} ({total})",
          },
        };
        _this = _super.call(this, paneSettings, $$2.extend(override, opts), index, panesContainer, panes) || this;
        return _this;
      }
      /**
       * Fill the array with the values that are currently being displayed in the table
       *
       * This method overrides _activePopulatePane() in SearchPaneCascade
       */
      SearchPaneCascadeViewTotal.prototype._activePopulatePane = function () {
        this.s.rowData.arrayFilter = [];
        this.s.rowData.binsShown = {};
        var settings = this.s.dt.settings()[0];
        if (!this.s.dt.page.info().serverSide) {
          for (var _i = 0, _a = this.s.dt.rows({ search: "applied" }).indexes().toArray(); _i < _a.length; _i++) {
            var index = _a[_i];
            this._populatePaneArray(index, this.s.rowData.arrayFilter, settings, this.s.rowData.binsShown);
          }
        }
      };
      /**
       * Gets the message that is to be used to indicate the count for each SearchPane row
       *
       * This method overrides _getMessage() in SearchPaneCascade
       *
       * @param row The row object that is being processed
       * @returns string - the message that is to be shown for the count of each entry
       */
      SearchPaneCascadeViewTotal.prototype._getMessage = function (row) {
        var countMessage = this.s.dt.i18n("searchPanes.count", this.c.i18n.count);
        var filteredMessage = this.s.dt.i18n("searchPanes.countFiltered", this.c.i18n.countFiltered);
        return (this.s.filteringActive ? filteredMessage : countMessage).replace(/{total}/g, row.total).replace(/{shown}/g, row.shown);
      };
      return SearchPaneCascadeViewTotal;
    })(SearchPaneCascade);

    var $$1;
    var dataTable$1;
    function setJQuery(jq) {
      $$1 = jq;
      dataTable$1 = jq.fn.dataTable;
    }
    var SearchPanes = /** @class */ (function () {
      function SearchPanes(paneSettings, opts, fromPreInit, paneClass) {
        var _this = this;
        if (fromPreInit === void 0) {
          fromPreInit = false;
        }
        if (paneClass === void 0) {
          paneClass = SearchPane;
        }
        // Check that the required version of DataTables is included
        if (!dataTable$1 || !dataTable$1.versionCheck || !dataTable$1.versionCheck("1.10.0")) {
          throw new Error("SearchPane requires DataTables 1.10 or newer");
        }
        // Check that Select is included
        // eslint-disable-next-line no-extra-parens
        if (!dataTable$1.select) {
          throw new Error("SearchPane requires Select");
        }
        var table = new dataTable$1.Api(paneSettings);
        this.classes = $$1.extend(true, {}, SearchPanes.classes);
        // Get options from user
        this.c = $$1.extend(true, {}, SearchPanes.defaults, opts);
        // Add extra elements to DOM object including clear
        this.dom = {
          clearAll: $$1('<button type="button"/>').addClass(this.classes.clearAll).html(table.i18n("searchPanes.clearMessage", this.c.i18n.clearMessage)),
          collapseAll: $$1('<button type="button"/>').addClass(this.classes.collapseAll).html(table.i18n("searchPanes.collapseMessage", this.c.i18n.collapseMessage)),
          container: $$1("<div/>").addClass(this.classes.panes).html(table.i18n("searchPanes.loadMessage", this.c.i18n.loadMessage)),
          emptyMessage: $$1("<div/>").addClass(this.classes.emptyMessage),
          panes: $$1("<div/>").addClass(this.classes.container),
          showAll: $$1('<button type="button"/>').addClass(this.classes.showAll).addClass(this.classes.disabledButton).attr("disabled", "true").html(table.i18n("searchPanes.showMessage", this.c.i18n.showMessage)),
          title: $$1("<div/>").addClass(this.classes.title),
          titleRow: $$1("<div/>").addClass(this.classes.titleRow),
        };
        this.s = {
          colOpts: [],
          dt: table,
          filterCount: 0,
          minPaneWidth: 260.0,
          page: 0,
          paging: false,
          pagingST: false,
          paneClass: paneClass,
          panes: [],
          selectionList: [],
          serverData: {},
          stateRead: false,
          updating: false,
        };
        // Do not reinitialise if already initialised on table
        if (table.settings()[0]._searchPanes) {
          return;
        }
        // When the panes update, we check it the clear buttons needs to be updated
        $$1(document).on("draw.dt", function (e) {
          if (_this.dom.container.find(e.target).length) {
            _this._updateFilterCount();
          }
        });
        this._getState();
        if (this.s.dt.page.info().serverSide) {
          var hostSettings = this.s.dt.settings()[0];
          // Listener to get the data into the server request before it is made
          this.s.dt.on("preXhr.dtsps", function (e, settings, data) {
            if (hostSettings !== settings) {
              return;
            }
            if (data.searchPanes === undefined) {
              data.searchPanes = {};
            }
            if (data.searchPanes_null === undefined) {
              data.searchPanes_null = {};
            }
            var src;
            for (var _i = 0, _a = _this.s.selectionList; _i < _a.length; _i++) {
              var selection = _a[_i];
              src = _this.s.dt.column(selection.column).dataSrc();
              if (data.searchPanes[src] === undefined) {
                data.searchPanes[src] = {};
              }
              if (data.searchPanes_null[src] === undefined) {
                data.searchPanes_null[src] = {};
              }
              for (var i = 0; i < selection.rows.length; i++) {
                data.searchPanes[src][i] = selection.rows[i];
                if (data.searchPanes[src][i] === null) {
                  data.searchPanes_null[src][i] = true;
                } else {
                  data.searchPanes_null[src][i] = false;
                }
              }
            }
            if (_this.s.selectionList.length > 0) {
              data.searchPanesLast = src;
            }
            // Config options that will change how the querying is done
            data.searchPanes_options = {
              cascade: _this.c.cascadePanes,
              viewCount: _this.c.viewCount,
              viewTotal: _this.c.viewTotal,
            };
          });
        }
        this._setXHR();
        table.settings()[0]._searchPanes = this;
        if (this.s.dt.settings()[0]._bInitComplete || fromPreInit) {
          this._paneDeclare(table, paneSettings, opts);
        } else {
          table.one("preInit.dtsps", function () {
            _this._paneDeclare(table, paneSettings, opts);
          });
        }
        return this;
      }
      /**
       * Clear the selections of all of the panes
       */
      SearchPanes.prototype.clearSelections = function () {
        var pane;
        for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
          pane = _a[_i];
          if (pane.s.dtPane) {
            pane.s.scrollTop = pane.s.dtPane.table().node().parentNode.scrollTop;
          }
        }
        // Load in all of the searchBoxes in the documents
        var searches = this.dom.container.find("." + this.classes.search.replace(/\s+/g, "."));
        // For each searchBox set the input text to be empty and then trigger
        // an input on them so that they no longer filter the panes
        searches.each(function () {
          $$1(this).val("").trigger("input");
        });
        // Clear the selectionList
        this.s.selectionList = [];
        var returnArray = [];
        for (var _b = 0, _c = this.s.panes; _b < _c.length; _b++) {
          pane = _c[_b];
          if (pane.s.dtPane) {
            returnArray.push(pane.clearPane());
          }
        }
        return returnArray;
      };
      /**
       * returns the container node for the searchPanes
       */
      SearchPanes.prototype.getNode = function () {
        return this.dom.container;
      };
      /**
       * rebuilds all of the panes
       */
      SearchPanes.prototype.rebuild = function (targetIdx, maintainSelection) {
        if (targetIdx === void 0) {
          targetIdx = false;
        }
        if (maintainSelection === void 0) {
          maintainSelection = false;
        }
        this.dom.emptyMessage.detach();
        // As a rebuild from scratch is required, empty the searchpanes container.
        if (targetIdx === false) {
          this.dom.panes.empty();
        }
        // Rebuild each pane individually, if a specific pane has been selected then only rebuild that one
        var returnArray = [];
        for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
          var pane = _a[_i];
          if (targetIdx === false || pane.s.index === targetIdx) {
            pane.clearData();
            pane.rebuildPane(this.s.dt.page.info().serverSide ? this.s.serverData : undefined, maintainSelection);
            this.dom.panes.append(pane.dom.container);
            returnArray.push(pane);
          }
        }
        this._updateSelection();
        // Attach panes, clear buttons, and title bar to the document
        this._updateFilterCount();
        this._attachPaneContainer();
        this._initSelectionListeners(false);
        // If the selections are to be maintained, then it is safe to assume that paging is also to be maintained
        // Otherwise, the paging should be reset
        this.s.dt.draw(!maintainSelection);
        // Resize the panes incase there has been a change
        this.resizePanes();
        // If a single pane has been rebuilt then return only that pane
        return returnArray.length === 1 ? returnArray[0] : returnArray;
      };
      /**
       * Resizes all of the panes
       */
      SearchPanes.prototype.resizePanes = function () {
        var pane;
        if (this.c.layout === "auto") {
          var contWidth = $$1(this.s.dt.searchPanes.container()).width();
          var target = Math.floor(contWidth / this.s.minPaneWidth); // The neatest number of panes per row
          var highest_1 = 1;
          var highestmod_1 = 0;
          // Get the indexes of all of the displayed panes
          var dispIndex = [];
          for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
            pane = _a[_i];
            if (pane.s.displayed) {
              dispIndex.push(pane.s.index);
            }
          }
          var displayCount = dispIndex.length;
          // If the neatest number is the number we have then use this.
          if (target === displayCount) {
            highest_1 = target;
          } else {
            // Go from the target down and find the value with the most panes left over, this will be the best fit
            for (var ppr = target; ppr > 1; ppr--) {
              var rem = displayCount % ppr;
              if (rem === 0) {
                highest_1 = ppr;
                highestmod_1 = 0;
                break;
              }
              // If there are more left over at this amount of panes per row (ppr)
              // then it fits better so new values
              else if (rem > highestmod_1) {
                highest_1 = ppr;
                highestmod_1 = rem;
              }
            }
          }
          // If there is a perfect fit then none are to be wider
          var widerIndexes_1 = highestmod_1 !== 0 ? dispIndex.slice(dispIndex.length - highestmod_1, dispIndex.length) : [];
          this.s.panes.forEach(function (pane) {
            // Resize the pane with the new layout
            if (pane.s.displayed) {
              pane.resize("columns-" + (!widerIndexes_1.includes(pane.s.index) ? highest_1 : highestmod_1));
            }
          });
        } else {
          for (var _b = 0, _c = this.s.panes; _b < _c.length; _b++) {
            pane = _c[_b];
            pane.adjustTopRow();
          }
        }
        return this;
      };
      /**
       * Holder method that is userd in SearchPanesST to set listeners that have an effect on other panes
       *
       * @param isPreselect boolean to indicate if the preselect array is to override the current selection list.
       */
      SearchPanes.prototype._initSelectionListeners = function (isPreselect) {
        return;
      };
      /**
       * Blank method that is overridden in SearchPanesST to retrieve the totals from the server data
       */
      SearchPanes.prototype._serverTotals = function () {
        return;
      };
      /**
       * Set's the xhr listener so that SP can extact appropriate data from the response
       */
      SearchPanes.prototype._setXHR = function () {
        var _this = this;
        var hostSettings = this.s.dt.settings()[0];
        var run = function (json) {
          if (json && json.searchPanes && json.searchPanes.options) {
            _this.s.serverData = json;
            _this.s.serverData.tableLength = json.recordsTotal;
            _this._serverTotals();
          }
        };
        // We are using the xhr event to rebuild the panes if required due to viewTotal being enabled
        // If viewTotal is not enabled then we simply update the data from the server
        this.s.dt.on("xhr.dtsps", function (e, settings, json) {
          if (hostSettings === settings) {
            run(json);
          }
        });
        // Account for the initial JSON fetch having already completed
        run(this.s.dt.ajax.json());
      };
      /**
       * Set's the function that is to be performed when a state is loaded
       *
       * Overridden by the method in SearchPanesST
       */
      SearchPanes.prototype._stateLoadListener = function () {
        var _this = this;
        var hostSettings = this.s.dt.settings()[0];
        this.s.dt.on("stateLoadParams.dtsps", function (e, settings, data) {
          if (data.searchPanes === undefined || settings !== hostSettings) {
            return;
          }
          _this.clearSelections();
          // Set the selection list for the panes so that the correct
          // rows can be reselected and in the right order
          _this.s.selectionList = data.searchPanes.selectionList ? data.searchPanes.selectionList : [];
          // Find the panes that match from the state and the actual instance
          if (data.searchPanes.panes) {
            for (var _i = 0, _a = data.searchPanes.panes; _i < _a.length; _i++) {
              var loadedPane = _a[_i];
              for (var _b = 0, _c = _this.s.panes; _b < _c.length; _b++) {
                var pane = _c[_b];
                if (loadedPane.id === pane.s.index && pane.s.dtPane) {
                  // Set the value of the searchbox
                  pane.dom.searchBox.val(loadedPane.searchTerm);
                  // Set the value of the order
                  pane.s.dtPane.order(loadedPane.order);
                }
              }
            }
          }
          _this._makeSelections(_this.s.selectionList);
        });
      };
      /**
       * Updates the selectionList when cascade is not in place
       *
       * Overridden in SearchPanesST
       */
      SearchPanes.prototype._updateSelection = function () {
        this.s.selectionList = [];
        for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
          var pane = _a[_i];
          if (pane.s.dtPane) {
            var rows = pane.s.dtPane
              .rows({ selected: true })
              .data()
              .toArray()
              .map(function (el) {
                return el.filter;
              });
            if (rows.length) {
              this.s.selectionList.push({
                column: pane.s.index,
                rows: rows,
              });
            }
          }
        }
      };
      /**
       * Attach the panes, buttons and title to the document
       */
      SearchPanes.prototype._attach = function () {
        var _this = this;
        this.dom.titleRow.removeClass(this.classes.hide).detach().append(this.dom.title);
        // If the clear button is permitted attach it
        if (this.c.clear) {
          this.dom.clearAll
            .appendTo(this.dom.titleRow)
            .off("click.dtsps")
            .on("click.dtsps", function () {
              return _this.clearSelections();
            });
        }
        if (this.c.collapse) {
          this.dom.showAll.appendTo(this.dom.titleRow);
          this.dom.collapseAll.appendTo(this.dom.titleRow);
          this._setCollapseListener();
        }
        // Attach the container for each individual pane to the overall container
        for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
          var pane = _a[_i];
          this.dom.panes.append(pane.dom.container);
        }
        // Attach everything to the document
        this.dom.container.text("").removeClass(this.classes.hide).append(this.dom.titleRow).append(this.dom.panes);
        // WORKAROUND
        this.s.panes.forEach(function (pane) {
          return pane.setListeners();
        });
        if ($$1("div." + this.classes.container).length === 0) {
          this.dom.container.prependTo(this.s.dt);
        }
      };
      /**
       * If there are no panes to display then this method is called to either
       * display a message in their place or hide them completely.
       */
      SearchPanes.prototype._attachMessage = function () {
        // Create a message to display on the screen
        var message;
        try {
          message = this.s.dt.i18n("searchPanes.emptyPanes", this.c.i18n.emptyPanes);
        } catch (error) {
          message = null;
        }
        // If the message is an empty string then searchPanes.emptyPanes is undefined,
        // therefore the pane container should be removed from the display
        if (message === null) {
          this.dom.container.addClass(this.classes.hide);
          this.dom.titleRow.removeClass(this.classes.hide);
          return;
        }
        // Otherwise display the message
        this.dom.container.removeClass(this.classes.hide);
        this.dom.titleRow.addClass(this.classes.hide);
        this.dom.emptyMessage.html(message).appendTo(this.dom.container);
      };
      /**
       * Attaches the panes to the document and displays a message or hides if there are none
       */
      SearchPanes.prototype._attachPaneContainer = function () {
        // If a pane is to be displayed then attach the normal pane output
        for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
          var pane = _a[_i];
          if (pane.s.displayed === true) {
            this._attach();
            return;
          }
        }
        // Otherwise attach the custom message or remove the container from the display
        this._attachMessage();
      };
      /**
       * Checks which panes are collapsed and then performs relevant actions to the collapse/show all buttons
       */
      SearchPanes.prototype._checkCollapse = function () {
        var disableClose = true;
        var disableShow = true;
        for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
          var pane = _a[_i];
          if (pane.s.displayed) {
            // If the pane is not collapsed
            if (!pane.dom.collapseButton.hasClass(pane.classes.rotated)) {
              // Enable the collapse all button
              this.dom.collapseAll.removeClass(this.classes.disabledButton).removeAttr("disabled");
              disableClose = false;
            } else {
              // Otherwise enable the show all button
              this.dom.showAll.removeClass(this.classes.disabledButton).removeAttr("disabled");
              disableShow = false;
            }
          }
        }
        // If this flag is still true, no panes are open so the close button should be disabled
        if (disableClose) {
          this.dom.collapseAll.addClass(this.classes.disabledButton).attr("disabled", "true");
        }
        // If this flag is still true, no panes are closed so the show button should be disabled
        if (disableShow) {
          this.dom.showAll.addClass(this.classes.disabledButton).attr("disabled", "true");
        }
      };
      /**
       * Attaches the message to the document but does not add any panes
       */
      SearchPanes.prototype._checkMessage = function () {
        // If a pane is to be displayed then attach the normal pane output
        for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
          var pane = _a[_i];
          if (pane.s.displayed === true) {
            // Ensure that the empty message is removed if a pane is displayed
            this.dom.emptyMessage.detach();
            this.dom.titleRow.removeClass(this.classes.hide);
            return;
          }
        }
        // Otherwise attach the custom message or remove the container from the display
        this._attachMessage();
      };
      /**
       * Collapses all of the panes
       */
      SearchPanes.prototype._collapseAll = function () {
        for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
          var pane = _a[_i];
          pane.collapse();
        }
      };
      /**
       * Finds a pane based upon the name of that pane
       *
       * @param name string representing the name of the pane
       * @returns SearchPane The pane which has that name
       */
      SearchPanes.prototype._findPane = function (name) {
        for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
          var pane = _a[_i];
          if (name === pane.s.name) {
            return pane;
          }
        }
      };
      /**
       * Gets the selection list from the previous state and stores it in the selectionList Property
       */
      SearchPanes.prototype._getState = function () {
        var loadedFilter = this.s.dt.state.loaded();
        if (loadedFilter && loadedFilter.searchPanes && loadedFilter.searchPanes.selectionList) {
          this.s.selectionList = loadedFilter.searchPanes.selectionList;
        }
      };
      SearchPanes.prototype._makeSelections = function (selectList) {
        for (var _i = 0, selectList_1 = selectList; _i < selectList_1.length; _i++) {
          var selection = selectList_1[_i];
          var pane = void 0;
          for (var _a = 0, _b = this.s.panes; _a < _b.length; _a++) {
            var p = _b[_a];
            if (p.s.index === selection.column) {
              pane = p;
              break;
            }
          }
          if (pane && pane.s.dtPane) {
            for (var j = 0; j < pane.s.dtPane.rows().data().toArray().length; j++) {
              if (selection.rows.includes(typeof pane.s.dtPane.row(j).data().filter === "function" ? pane.s.dtPane.cell(j, 0).data() : pane.s.dtPane.row(j).data().filter)) {
                pane.s.dtPane.row(j).select();
              }
            }
            pane.updateTable();
          }
        }
      };
      /**
       * Declares the instances of individual searchpanes dependant on the number of columns.
       * It is necessary to run this once preInit has completed otherwise no panes will be
       * created as the column count will be 0.
       *
       * @param table the DataTable api for the parent table
       * @param paneSettings the settings passed into the constructor
       * @param opts the options passed into the constructor
       */
      SearchPanes.prototype._paneDeclare = function (table, paneSettings, opts) {
        var _this = this;
        // Create Panes
        table
          .columns(this.c.columns.length > 0 ? this.c.columns : undefined)
          .eq(0)
          .each(function (idx) {
            _this.s.panes.push(new _this.s.paneClass(paneSettings, opts, idx, _this.dom.panes));
          });
        // If there is any extra custom panes defined then create panes for them too
        var colCount = table.columns().eq(0).toArray().length;
        for (var i = 0; i < this.c.panes.length; i++) {
          var id = colCount + i;
          this.s.panes.push(new this.s.paneClass(paneSettings, opts, id, this.dom.panes, this.c.panes[i]));
        }
        // If a custom ordering is being used
        if (this.c.order.length > 0) {
          // Make a new Array of panes based upon the order
          this.s.panes = this.c.order.map(function (name) {
            return _this._findPane(name);
          });
        }
        // If this internal property is true then the DataTable has been initialised already
        if (this.s.dt.settings()[0]._bInitComplete) {
          this._startup(table);
        } else {
          // Otherwise add the paneStartup function to the list of functions
          // that are to be run when the table is initialised. This will garauntee that the
          // panes are initialised before the init event and init Complete callback is fired
          this.s.dt.settings()[0].aoInitComplete.push(function () {
            return _this._startup(table);
          });
        }
      };
      /**
       * Sets the listeners for the collapse and show all buttons
       * Also sets and performs checks on current panes to see if they are collapsed
       */
      SearchPanes.prototype._setCollapseListener = function () {
        var _this = this;
        this.dom.collapseAll.off("click.dtsps").on("click.dtsps", function () {
          _this._collapseAll();
          _this.dom.collapseAll.addClass(_this.classes.disabledButton).attr("disabled", "true");
          _this.dom.showAll.removeClass(_this.classes.disabledButton).removeAttr("disabled");
          _this.s.dt.state.save();
        });
        this.dom.showAll.off("click.dtsps").on("click.dtsps", function () {
          _this._showAll();
          _this.dom.showAll.addClass(_this.classes.disabledButton).attr("disabled", "true");
          _this.dom.collapseAll.removeClass(_this.classes.disabledButton).removeAttr("disabled");
          _this.s.dt.state.save();
        });
        for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
          var pane = _a[_i];
          // We want to make the same check whenever there is a collapse/expand
          pane.dom.topRow.off("collapse.dtsps").on("collapse.dtsps", function () {
            return _this._checkCollapse();
          });
        }
        this._checkCollapse();
      };
      /**
       * Shows all of the panes
       */
      SearchPanes.prototype._showAll = function () {
        for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
          var pane = _a[_i];
          pane.show();
        }
      };
      /**
       * Initialises the tables previous/preset selections and initialises callbacks for events
       *
       * @param table the parent table for which the searchPanes are being created
       */
      SearchPanes.prototype._startup = function (table) {
        var _this = this;
        // Attach clear button and title bar to the document
        this._attach();
        this.dom.panes.empty();
        var hostSettings = this.s.dt.settings()[0];
        for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
          var pane = _a[_i];
          pane.rebuildPane(Object.keys(this.s.serverData).length > 0 ? this.s.serverData : undefined);
          this.dom.panes.append(pane.dom.container);
        }
        // If the layout is set to auto then the panes need to be resized to their best fit
        if (this.c.layout === "auto") {
          this.resizePanes();
        }
        var loadedFilter = this.s.dt.state.loaded();
        // Reset the paging if that has been saved in the state
        if (!this.s.stateRead && loadedFilter) {
          this.s.dt.page(loadedFilter.start / this.s.dt.page.len()).draw("page");
        }
        this.s.stateRead = true;
        this._checkMessage();
        // When a draw is called on the DataTable, update all of the panes incase the data in the DataTable has changed
        table.on("preDraw.dtsps", function () {
          // Check that the panes are not updating to avoid infinite loops
          // Also check that this draw is not due to paging
          if (!_this.s.updating && !_this.s.paging) {
            _this._updateFilterCount();
            _this._updateSelection();
          }
          // Paging flag reset - we only need to dodge the draw once
          _this.s.paging = false;
        });
        $$1(window).on(
          "resize.dtsps",
          dataTable$1.util.throttle(function () {
            return _this.resizePanes();
          })
        );
        // Whenever a state save occurs store the selection list in the state object
        this.s.dt.on("stateSaveParams.dtsps", function (e, settings, data) {
          if (settings !== hostSettings) {
            return;
          }
          if (data.searchPanes === undefined) {
            data.searchPanes = {};
          }
          data.searchPanes.selectionList = _this.s.selectionList;
        });
        this._stateLoadListener();
        // Listener for paging on main table
        table.off("page.dtsps page-nc.dtsps").on("page.dtsps page-nc.dtsps", function (e, s) {
          _this.s.paging = true;
          // This is an indicator to any selection tracking classes that paging has occured
          // It has to happen here so that we don't stack event listeners unnecessarily
          // The value is only ever set back to false in the SearchPanesST class
          // Equally it is never read in this class
          _this.s.pagingST = true;
          _this.s.page = _this.s.dt.page();
        });
        if (this.s.dt.page.info().serverSide) {
          table.off("preXhr.dtsps").on("preXhr.dtsps", function (e, settings, data) {
            if (settings !== hostSettings) {
              return;
            }
            if (!data.searchPanes) {
              data.searchPanes = {};
            }
            if (!data.searchPanes_null) {
              data.searchPanes_null = {};
            }
            // Count how many filters are being applied
            var filterCount = 0;
            for (var _i = 0, _a = _this.s.panes; _i < _a.length; _i++) {
              var pane = _a[_i];
              var src = _this.s.dt.column(pane.s.index).dataSrc();
              if (!data.searchPanes[src]) {
                data.searchPanes[src] = {};
              }
              if (!data.searchPanes_null[src]) {
                data.searchPanes_null[src] = {};
              }
              if (pane.s.dtPane) {
                var rowData = pane.s.dtPane.rows({ selected: true }).data().toArray();
                for (var i = 0; i < rowData.length; i++) {
                  data.searchPanes[src][i] = rowData[i].filter;
                  if (!data.searchPanes[src][i]) {
                    data.searchPanes_null[src][i] = true;
                  } else {
                    data.searchPanes_null[src][i] = false;
                  }
                  filterCount++;
                }
              }
            }
            // If there is a filter to be applied, then we need to read from the start of the result set
            // and set the paging to 0. This matches the behaviour of client side processing
            if (filterCount > 0) {
              // If the number of filters has changed we need to read from the start of the
              // result set and reset the paging
              if (filterCount !== _this.s.filterCount) {
                data.start = 0;
                _this.s.page = 0;
              }
              // Otherwise it is a paging request and we need to read from whatever the paging has been set to
              else {
                data.start = _this.s.page * _this.s.dt.page.len();
              }
              _this.s.dt.page(_this.s.page);
              _this.s.filterCount = filterCount;
            }
            if (_this.s.selectionList.length > 0) {
              data.searchPanesLast = _this.s.dt.column(_this.s.selectionList[_this.s.selectionList.length - 1].column).dataSrc();
            }
            // Config options that will change how the querying is done
            data.searchPanes_options = {
              cascade: _this.c.cascadePanes,
              viewCount: _this.c.viewCount,
              viewTotal: _this.c.viewTotal,
            };
          });
        } else {
          table.on("preXhr.dtsps", function () {
            return _this.s.panes.forEach(function (pane) {
              return pane.clearData();
            });
          });
        }
        // If the data is reloaded from the server then it is possible that it has changed completely,
        // so we need to rebuild the panes
        this.s.dt.on("xhr.dtsps", function (e, settings) {
          if (settings.nTable !== _this.s.dt.table().node()) {
            return;
          }
          if (!_this.s.dt.page.info().serverSide) {
            var processing_1 = false;
            _this.s.dt.one("preDraw.dtsps", function () {
              if (processing_1) {
                return;
              }
              var page = _this.s.dt.page();
              processing_1 = true;
              _this.s.updating = true;
              _this.dom.panes.empty();
              for (var _i = 0, _a = _this.s.panes; _i < _a.length; _i++) {
                var pane = _a[_i];
                pane.clearData(); // Clears all of the bins and will mean that the data has to be re-read
                // Pass a boolean to say whether this is the last choice made for maintaining selections
                // when rebuilding
                pane.rebuildPane(undefined, true);
                _this.dom.panes.append(pane.dom.container);
              }
              if (!_this.s.dt.page.info().serverSide) {
                _this.s.dt.draw();
              }
              _this.s.updating = false;
              _this._updateSelection();
              _this._checkMessage();
              _this.s.dt.one("draw.dtsps", function () {
                _this.s.updating = true;
                _this.s.dt.page(page).draw(false);
                _this.s.updating = false;
              });
            });
          }
        });
        // PreSelect any selections which have been defined using the preSelect option
        var selectList = this.c.preSelect;
        if (loadedFilter && loadedFilter.searchPanes && loadedFilter.searchPanes.selectionList) {
          selectList = loadedFilter.searchPanes.selectionList;
        }
        this._makeSelections(selectList);
        // Update the title bar to show how many filters have been selected
        this._updateFilterCount();
        // If the table is destroyed and restarted then clear the selections so that they do not persist.
        table.on("destroy.dtsps", function (e, settings) {
          if (settings !== hostSettings) {
            return;
          }
          for (var _i = 0, _a = _this.s.panes; _i < _a.length; _i++) {
            var pane = _a[_i];
            pane.destroy();
          }
          table.off(".dtsps");
          _this.dom.showAll.off(".dtsps");
          _this.dom.clearAll.off(".dtsps");
          _this.dom.collapseAll.off(".dtsps");
          $$1(table.table().node()).off(".dtsps");
          _this.dom.container.detach();
          _this.clearSelections();
        });
        if (this.c.collapse) {
          this._setCollapseListener();
        }
        // When the clear All button has been pressed clear all of the selections in the panes
        if (this.c.clear) {
          this.dom.clearAll.off("click.dtsps").on("click.dtsps", function () {
            return _this.clearSelections();
          });
        }
        hostSettings._searchPanes = this;
        // This state save is required so that state is maintained over multiple refreshes if no actions are made
        this.s.dt.state.save();
      };
      /**
       * Updates the number of filters that have been applied in the title
       */
      SearchPanes.prototype._updateFilterCount = function () {
        var filterCount = 0;
        var tableSearch = 0;
        // Add the number of all of the filters throughout the panes
        for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
          var pane = _a[_i];
          if (pane.s.dtPane) {
            filterCount += pane.getPaneCount();
            if (pane.s.dtPane.search()) {
              tableSearch++;
            }
          }
        }
        // Run the message through the internationalisation method to improve readability
        this.dom.title.html(this.s.dt.i18n("searchPanes.title", this.c.i18n.title, filterCount));
        if (this.c.filterChanged && typeof this.c.filterChanged === "function") {
          this.c.filterChanged.call(this.s.dt, filterCount);
        }
        if (filterCount === 0 && tableSearch === 0) {
          this.dom.clearAll.addClass(this.classes.disabledButton).attr("disabled", "true");
        } else {
          this.dom.clearAll.removeClass(this.classes.disabledButton).removeAttr("disabled");
        }
      };
      SearchPanes.version = "2.3.0";
      SearchPanes.classes = {
        clear: "dtsp-clear",
        clearAll: "dtsp-clearAll",
        collapseAll: "dtsp-collapseAll",
        container: "dtsp-searchPanes",
        disabledButton: "dtsp-disabledButton",
        emptyMessage: "dtsp-emptyMessage",
        hide: "dtsp-hidden",
        panes: "dtsp-panesContainer",
        search: "dtsp-search",
        showAll: "dtsp-showAll",
        title: "dtsp-title",
        titleRow: "dtsp-titleRow",
      };
      // Define SearchPanes default options
      SearchPanes.defaults = {
        cascadePanes: false,
        clear: true,
        collapse: true,
        columns: [],
        container: function (dt) {
          return dt.table().container();
        },
        filterChanged: undefined,
        i18n: {
          clearMessage: "Clear All",
          clearPane: "&times;",
          collapse: {
            0: "SearchPanes",
            _: "SearchPanes (%d)",
          },
          collapseMessage: "Collapse All",
          count: "{total}",
          emptyMessage: "<em>No data</em>",
          emptyPanes: "No SearchPanes",
          loadMessage: "Loading Search Panes...",
          showMessage: "Show All",
          title: "Filters Active - %d",
        },
        layout: "auto",
        order: [],
        panes: [],
        preSelect: [],
        viewCount: true,
        viewTotal: false,
      };
      return SearchPanes;
    })();

    var __extends =
      (window && window.__extends) ||
      (function () {
        var extendStatics = function (d, b) {
          extendStatics =
            Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array &&
              function (d, b) {
                d.__proto__ = b;
              }) ||
            function (d, b) {
              for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
            };
          return extendStatics(d, b);
        };
        return function (d, b) {
          extendStatics(d, b);
          function __() {
            this.constructor = d;
          }
          d.prototype = b === null ? Object.create(b) : ((__.prototype = b.prototype), new __());
        };
      })();
    var SearchPanesST = /** @class */ (function (_super) {
      __extends(SearchPanesST, _super);
      function SearchPanesST(paneSettings, opts, fromPreInit) {
        if (fromPreInit === void 0) {
          fromPreInit = false;
        }
        var _this = this;
        var paneClass;
        if (opts.cascadePanes && opts.viewTotal) {
          paneClass = SearchPaneCascadeViewTotal;
        } else if (opts.cascadePanes) {
          paneClass = SearchPaneCascade;
        } else if (opts.viewTotal) {
          paneClass = SearchPaneViewTotal;
        }
        _this = _super.call(this, paneSettings, opts, fromPreInit, paneClass) || this;
        var dt = _this.s.dt;
        var loadedFilter = dt.state.loaded();
        var loadFn = function () {
          return _this._initSelectionListeners(true, loadedFilter && loadedFilter.searchPanes && loadedFilter.searchPanes.selectionList ? loadedFilter.searchPanes.selectionList : _this.c.preSelect);
        };
        if (dt.settings()[0]._bInitComplete) {
          loadFn();
        } else {
          dt.off("init.dtsps").on("init.dtsps", loadFn);
        }
        return _this;
      }
      /**
       * Ensures that the correct selection listeners are set for selection tracking
       *
       * @param preSelect Any values that are to be preselected
       */
      SearchPanesST.prototype._initSelectionListeners = function (isPreselect, preSelect) {
        if (isPreselect === void 0) {
          isPreselect = true;
        }
        if (preSelect === void 0) {
          preSelect = [];
        }
        if (isPreselect) {
          this.s.selectionList = preSelect;
        }
        // Set selection listeners for each pane
        for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
          var pane = _a[_i];
          if (pane.s.displayed) {
            pane.s.dtPane.off("select.dtsp").on("select.dtsp", this._update(pane)).off("deselect.dtsp").on("deselect.dtsp", this._updateTimeout(pane));
          }
        }
        // Update on every draw
        this.s.dt.off("draw.dtsps").on("draw.dtsps", this._update());
        // Also update right now as table has just initialised
        this._updateSelectionList();
      };
      /**
       * Retrieve the total values from the server data
       */
      SearchPanesST.prototype._serverTotals = function () {
        for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
          var pane = _a[_i];
          if (pane.s.colOpts.show) {
            var colTitle = this.s.dt.column(pane.s.index).dataSrc();
            var blockVT = true;
            // If any of the counts are not equal to the totals filtering must be active
            if (this.s.serverData.searchPanes.options[colTitle]) {
              for (var _b = 0, _c = this.s.serverData.searchPanes.options[colTitle]; _b < _c.length; _b++) {
                var data = _c[_b];
                if (data.total !== data.count) {
                  blockVT = false;
                  break;
                }
              }
            }
            // Set if filtering is present on the pane and populate the data arrays
            pane.s.filteringActive = !blockVT;
            pane._serverPopulate(this.s.serverData);
          }
        }
      };
      /**
       * Set's the function that is to be performed when a state is loaded
       *
       * Overrides the method in SearchPanes
       */
      SearchPanesST.prototype._stateLoadListener = function () {
        var _this = this;
        var stateLoadFunction = function (e, settings, data) {
          if (data.searchPanes === undefined) {
            return;
          }
          // Set the selection list for the panes so that the correct
          // rows can be reselected and in the right order
          _this.s.selectionList = data.searchPanes.selectionList ? data.searchPanes.selectionList : [];
          // Find the panes that match from the state and the actual instance
          if (data.searchPanes.panes) {
            for (var _i = 0, _a = data.searchPanes.panes; _i < _a.length; _i++) {
              var loadedPane = _a[_i];
              for (var _b = 0, _c = _this.s.panes; _b < _c.length; _b++) {
                var pane = _c[_b];
                if (loadedPane.id === pane.s.index && pane.s.dtPane) {
                  // Set the value of the searchbox
                  pane.dom.searchBox.val(loadedPane.searchTerm);
                  // Set the value of the order
                  pane.s.dtPane.order(loadedPane.order);
                }
              }
            }
          }
          _this._updateSelectionList();
        };
        this.s.dt.off("stateLoadParams.dtsps", stateLoadFunction).on("stateLoadParams.dtsps", stateLoadFunction);
      };
      /**
       * Remove the function's actions when using cascade
       *
       * Overrides the method in SearchPanes
       */
      SearchPanesST.prototype._updateSelection = function () {
        return;
      };
      /**
       * Returns a function that updates the selection list based on a specific pane
       * Also clears the timeout to stop the deselect from running
       *
       * @param pane the pane that is to have it's selections loaded
       */
      SearchPanesST.prototype._update = function (pane) {
        var _this = this;
        if (pane === void 0) {
          pane = undefined;
        }
        return function () {
          if (pane) {
            clearTimeout(pane.s.deselectTimeout);
          }
          _this._updateSelectionList(pane);
        };
      };
      /**
       * Returns a function that updates the selection list based on a specific pane
       * Also sets a timeout incase a select is about to be made
       *
       * @param pane the pane that is to have it's selections loaded
       */
      SearchPanesST.prototype._updateTimeout = function (pane) {
        var _this = this;
        if (pane === void 0) {
          pane = undefined;
        }
        return function () {
          return pane
            ? (pane.s.deselectTimeout = setTimeout(function () {
                return _this._updateSelectionList(pane);
              }, 50))
            : _this._updateSelectionList();
        };
      };
      /**
       * Updates the selection list to include the latest selections for a given pane
       *
       * @param index The index of the pane that is to be updated
       * @param selected Which rows are selected within the pane
       */
      SearchPanesST.prototype._updateSelectionList = function (paneIn) {
        if (paneIn === void 0) {
          paneIn = undefined;
        }
        // Bail if any of these flags are set
        if (this.s.pagingST) {
          // Reset pagingST flag
          this.s.pagingST = false;
          return;
        } else if (this.s.updating || (paneIn && paneIn.s.serverSelecting)) {
          return;
        }
        if (paneIn !== undefined) {
          if (this.s.dt.page.info().serverSide) {
            paneIn._updateSelection();
          }
          // Get filter values for all of the rows and the selections
          var rows = paneIn.s.dtPane
            .rows({ selected: true })
            .data()
            .toArray()
            .map(function (el) {
              return el.filter;
            });
          this.s.selectionList = this.s.selectionList.filter(function (selection) {
            return selection.column !== paneIn.s.index;
          });
          if (rows.length > 0) {
            this.s.selectionList.push({
              column: paneIn.s.index,
              rows: rows,
            });
            paneIn.dom.clear.removeClass(this.classes.disabledButton).removeAttr("disabled");
          } else {
            paneIn.dom.clear.addClass(this.classes.disabledButton).attr("disabled", "true");
          }
          if (this.s.dt.page.info().serverSide) {
            this.s.dt.draw(false);
          }
        }
        this._remakeSelections();
        this._updateFilterCount();
      };
      /**
       * Remake the selections that were present before new data or calculations have occured
       */
      SearchPanesST.prototype._remakeSelections = function () {
        var currPane;
        var pane;
        this.s.updating = true;
        if (!this.s.dt.page.info().serverSide) {
          var tmpSL = this.s.selectionList;
          var anotherFilter = false;
          this.clearSelections();
          this.s.dt.draw(false);
          // When there are no selections present if the length of the data does not match the searched data
          // then another filter is present
          if (this.s.dt.rows().toArray()[0].length > this.s.dt.rows({ search: "applied" }).toArray()[0].length) {
            anotherFilter = true;
          }
          this.s.selectionList = tmpSL;
          // Update the rows in each pane
          for (var _i = 0, _a = this.s.panes; _i < _a.length; _i++) {
            pane = _a[_i];
            if (pane.s.displayed) {
              pane.s.filteringActive = anotherFilter;
              pane.updateRows();
            }
          }
          for (var _b = 0, _c = this.s.selectionList; _b < _c.length; _b++) {
            var selection = _c[_b];
            pane = null;
            for (var _d = 0, _e = this.s.panes; _d < _e.length; _d++) {
              var paneCheck = _e[_d];
              if (paneCheck.s.index === selection.column) {
                pane = paneCheck;
                break;
              }
            }
            if (!pane.s.dtPane) {
              continue;
            }
            var ids = pane.s.dtPane.rows().indexes().toArray();
            // Select the rows that are present in the selection list
            for (var i = 0; i < selection.rows.length; i++) {
              var rowFound = false;
              for (var _f = 0, ids_1 = ids; _f < ids_1.length; _f++) {
                var id = ids_1[_f];
                var currRow = pane.s.dtPane.row(id);
                var data = currRow.data();
                if (selection.rows[i] === data.filter) {
                  currRow.select();
                  rowFound = true;
                }
              }
              if (!rowFound) {
                selection.rows.splice(i, 1);
                i--;
              }
            }
            pane.s.selections = selection.rows;
            // If there are no rows selected then don't bother continuing past here
            // Will just increase processing time and skew the rows that are shown in the table
            if (selection.rows.length === 0) {
              continue;
            }
            // Update the table to display the current results
            this.s.dt.draw();
            var filteringActive = false;
            var filterCount = 0;
            var prevSelectedPanes = 0;
            var selectedPanes = 0;
            // Add the number of all of the filters throughout the panes
            for (var _g = 0, _h = this.s.panes; _g < _h.length; _g++) {
              currPane = _h[_g];
              if (currPane.s.dtPane) {
                filterCount += currPane.getPaneCount();
                if (filterCount > prevSelectedPanes) {
                  selectedPanes++;
                  prevSelectedPanes = filterCount;
                }
              }
            }
            filteringActive = filterCount > 0;
            for (var _j = 0, _k = this.s.panes; _j < _k.length; _j++) {
              currPane = _k[_j];
              if (currPane.s.displayed) {
                // Set the filtering active flag
                if (anotherFilter || pane.s.index !== currPane.s.index || !filteringActive) {
                  currPane.s.filteringActive = filteringActive || anotherFilter;
                } else if (selectedPanes === 1) {
                  currPane.s.filteringActive = false;
                }
                // Update the rows to show correct counts
                if (currPane.s.index !== pane.s.index) {
                  currPane.updateRows();
                }
              }
            }
          }
          // Update table to show final search results
          this.s.dt.draw(false);
        } else {
          // Identify the last pane to have a change in selection
          if (this.s.selectionList.length > 0) {
            pane = this.s.panes[this.s.selectionList[this.s.selectionList.length - 1].column];
          }
          // Update the rows of all of the other panes
          for (var _l = 0, _m = this.s.panes; _l < _m.length; _l++) {
            currPane = _m[_l];
            if (currPane.s.displayed && (!pane || currPane.s.index !== pane.s.index)) {
              currPane.updateRows();
            }
          }
        }
        this.s.updating = false;
      };
      return SearchPanesST;
    })(SearchPanes);

    /*! SearchPanes 2.3.0
     * © SpryMedia Ltd - datatables.net/license
     */
    setJQuery$4($);
    setJQuery($);
    setJQuery$3($);
    setJQuery$2($);
    setJQuery$1($);
    var dataTable = $.fn.dataTable;
    // eslint-disable-next-line no-extra-parens
    dataTable.SearchPanes = SearchPanes;
    // eslint-disable-next-line no-extra-parens
    DataTable.SearchPanes = SearchPanes;
    // eslint-disable-next-line no-extra-parens
    dataTable.SearchPanesST = SearchPanesST;
    // eslint-disable-next-line no-extra-parens
    DataTable.SearchPanesST = SearchPanesST;
    // eslint-disable-next-line no-extra-parens
    dataTable.SearchPane = SearchPane;
    // eslint-disable-next-line no-extra-parens
    DataTable.SearchPane = SearchPane;
    // eslint-disable-next-line no-extra-parens
    dataTable.SearchPaneViewTotal = SearchPaneViewTotal;
    // eslint-disable-next-line no-extra-parens
    DataTable.SearchPaneViewTotal = SearchPaneViewTotal;
    // eslint-disable-next-line no-extra-parens
    dataTable.SearchPaneCascade = SearchPaneCascade;
    // eslint-disable-next-line no-extra-parens
    DataTable.SearchPaneCascade = SearchPaneCascade;
    // eslint-disable-next-line no-extra-parens
    dataTable.SearchPaneCascadeViewTotal = SearchPaneCascadeViewTotal;
    // eslint-disable-next-line no-extra-parens
    DataTable.SearchPaneCascadeViewTotal = SearchPaneCascadeViewTotal;
    // eslint-disable-next-line no-extra-parens
    var apiRegister = $.fn.dataTable.Api.register;
    apiRegister("searchPanes()", function () {
      return this;
    });
    apiRegister("searchPanes.clearSelections()", function () {
      return this.iterator("table", function (ctx) {
        if (ctx._searchPanes) {
          ctx._searchPanes.clearSelections();
        }
      });
    });
    apiRegister("searchPanes.rebuildPane()", function (targetIdx, maintainSelections) {
      return this.iterator("table", function (ctx) {
        if (ctx._searchPanes) {
          ctx._searchPanes.rebuild(targetIdx, maintainSelections);
        }
      });
    });
    apiRegister("searchPanes.resizePanes()", function () {
      var ctx = this.context[0];
      return ctx._searchPanes ? ctx._searchPanes.resizePanes() : null;
    });
    apiRegister("searchPanes.container()", function () {
      var ctx = this.context[0];
      return ctx._searchPanes ? ctx._searchPanes.getNode() : null;
    });
    DataTable.ext.buttons.searchPanesClear = {
      action: function (e, dt) {
        dt.searchPanes.clearSelections();
      },
      text: "Clear Panes",
    };
    DataTable.ext.buttons.searchPanes = {
      action: function (e, dt, node, config) {
        var _this = this;
        var that = this;
        if (!config._panes) {
          // No SearchPanes on this button yet - initialise and show
          this.processing(true);
          setTimeout(function () {
            _buttonSourced(dt, node, config);
            _this.popover(config._panes.getNode(), {
              align: "container",
              span: "container",
            });
            config._panes.rebuild(undefined, true);
            // Tables were hidden in the popover, need to be resized
            $("table.dataTable", config._panes.getNode()).DataTable().columns.adjust();
            that.processing(false);
          }, 10);
        } else {
          // Already got SP - show it
          this.popover(config._panes.getNode(), {
            align: "container",
            span: "container",
          });
          config._panes.rebuild(undefined, true);
        }
      },
      init: function (dt, node, config) {
        dt.button(node).text(config.text || dt.i18n("searchPanes.collapse", "SearchPanes", 0));
        // For cases when we need to initialise the SearchPane immediately
        if (dt.init().stateSave || config.delayInit === false) {
          _buttonSourced(dt, node, config);
        }
      },
      config: {},
      text: "",
      delayInit: true,
    };
    function _buttonSourced(dt, node, config) {
      var buttonOpts = $.extend(
        {
          filterChanged: function (count) {
            dt.button(node).text(dt.i18n("searchPanes.collapse", dt.context[0].oLanguage.searchPanes !== undefined ? dt.context[0].oLanguage.searchPanes.collapse : dt.context[0]._searchPanes.c.i18n.collapse, count));
          },
        },
        config.config
      );
      var panes = buttonOpts && (buttonOpts.cascadePanes || buttonOpts.viewTotal) ? new DataTable.SearchPanesST(dt, buttonOpts) : new DataTable.SearchPanes(dt, buttonOpts);
      dt.button(node).text(config.text || dt.i18n("searchPanes.collapse", panes.c.i18n.collapse, 0));
      config._panes = panes;
    }
    function _init(settings, options, fromPre) {
      if (options === void 0) {
        options = null;
      }
      if (fromPre === void 0) {
        fromPre = false;
      }
      var api = new dataTable.Api(settings);
      var opts = options ? options : api.init().searchPanes || dataTable.defaults.searchPanes;
      var searchPanes = opts && (opts.cascadePanes || opts.viewTotal) ? new SearchPanesST(api, opts, fromPre) : new SearchPanes(api, opts, fromPre);
      var node = searchPanes.getNode();
      return node;
    }
    // Attach a listener to the document which listens for DataTables initialisation
    // events so we can automatically initialise
    $(document).on("preInit.dt.dtsp", function (e, settings) {
      if (e.namespace !== "dt") {
        return;
      }
      if (settings.oInit.searchPanes || DataTable.defaults.searchPanes) {
        if (!settings._searchPanes) {
          _init(settings, null, true);
        }
      }
    });
    // DataTables `dom` feature option
    DataTable.ext.feature.push({
      cFeature: "P",
      fnInit: _init,
    });
    // DataTables 2 layout feature
    if (DataTable.feature) {
      DataTable.feature.register("searchPanes", _init);
    }
  })();

  return DataTable;
});
