tblAddListener(tblSelector, options = {}, out = {}) {
    const table = _a.doc.querySelector(tblSelector);
    if (!table) throw new Error(`Table with CSS Selector "${tblSelector}" not found`);
    if (typeof out !== "object") throw new Error('The "out" argument MUST be an object');
    if (!options.eventScope) options.eventScope = "row";
    if (!options.returnType) options.returnType = "text";
    if (!options.eventType) options.eventType = "click";
    if (!options.pad) options.pad = 3;
    if (!options.logLevel) options.logLevel = 2;
    if (!("send" in options)) options.send = true;
    table.querySelector("tbody").addEventListener(options.eventType, (event) => {
      Object.keys(out).forEach((key) => delete out[key]);
      const clickedRow = event.target.closest("tr");
      const clickedCell = event.target.closest("td");
      if (clickedRow) {
        out.clickType = options.eventScope;
        out.eventType = options.eventType;
        const rowIndex = out.rowIndex = clickedRow.rowIndex;
        const cellIndex = out.cellIndex = clickedCell.cellIndex + 1;
        if (clickedRow.id) out.rowId = clickedRow.id;
        if (options.eventScope === "row") {
          clickedRow.querySelectorAll("td").forEach((cell) => {
            const colName = this.tblGetCellName(cell, options.pad);
            out[colName] = options.returnType === "text" ? cell.textContent.trim() : cell.innerHTML;
          });
        } else {
          const colName = this.tblGetCellName(clickedCell, options.pad);
          out[colName] = options.returnType === "text" ? clickedCell.textContent.trim() : clickedCell.innerHTML;
        }
        _a.log(options.logLevel, "Ui:tblAddClickListener", `${options.eventScope} ${options.eventType} on row=${rowIndex}, col=${cellIndex}, data: `, out)();
        if (options.send === true && _a.win["uibuilder"]) _a.win["uibuilder"].send({
          topic: `${tblSelector} ${options.eventScope} ${options.eventType}`,
          payload: out
        });
      }
    });
  }
Add table event listener that returns the text or html content of either the full row or a single cell
NOTE: Assumes that the table has a `tbody` element.
If cells have a `data-col-name` attribute, it will be used in the output as the column name.
@example tblAddListener('#eltest-tbl-table', {}, myVar)
@example tblAddListener('#eltest-tbl-table', {eventScope: 'cell'}, myVar2)

@param {string} tblSelector The table CSS Selector
@param {object} [options] Additional options. Default={}
  @param {"row"|"cell"=} options.eventScope Optional, default=row. Return data for either the whole row (as an object) or for the single cell clicked
  @param {"text"|"html"=} options.returnType Optional, default=text. Return text or html data
  @param {number=} options.pad Optional, default=3. Will be used to front-pad unnamed column references with zeros. e.g. 3 => "C002"/"C012"/"C342"
  @param {boolean=} options.send Optional, default=true. If uibuilder is present, will automatically send a message back to Node-RED.
  @param {string|number=} options.logLevel Optional, default=3/info. Numeric or string log level matching uibuilder's log levels.
  @param {string} [options.eventType] Optional, default=click. What event to listen for.
@param {object=} out A variable reference that will be updated with the output data upon a click event