diff --git a/dist/pivot.js b/dist/pivot.js
index 489e412a..33a5167a 100644
--- a/dist/pivot.js
+++ b/dist/pivot.js
@@ -520,7 +520,7 @@
     rz = /^0/;
     naturalSort = (function(_this) {
       return function(as, bs) {
-        var a, a1, b, b1, nas, nbs;
+        var a, a1, b, b1, nas, nbs, numDiff;
         if ((bs != null) && (as == null)) {
           return -1;
         }
@@ -571,7 +571,12 @@
           b1 = b.shift();
           if (a1 !== b1) {
             if (rd.test(a1) && rd.test(b1)) {
-              return a1.replace(rz, ".0") - b1.replace(rz, ".0");
+              numDiff = a1.replace(rz, ".0") - b1.replace(rz, ".0");
+              if (numDiff !== 0) {
+                return numDiff;
+              } else {
+                return a1.length - b1.length;
+              }
             } else {
               return (a1 > b1 ? 1 : -1);
             }
diff --git a/dist/pivot.js.map b/dist/pivot.js.map
index a45720b3..b7537330 100644
--- a/dist/pivot.js.map
+++ b/dist/pivot.js.map
@@ -1 +1 @@
-{"version":3,"file":"pivot.js","sources":["pivot.coffee"],"names":[],"mappings":"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","sourcesContent":["callWithJQuery = (pivotModule) ->\n    if typeof exports is \"object\" and typeof module is \"object\" # CommonJS\n        pivotModule require(\"jquery\")\n    else if typeof define is \"function\" and define.amd # AMD\n        define [\"jquery\"], pivotModule\n    # Plain browser env\n    else\n        pivotModule jQuery\n\ncallWithJQuery ($) ->\n\n    ###\n    Utilities\n    ###\n\n    addSeparators = (nStr, thousandsSep, decimalSep) ->\n        nStr += ''\n        x = nStr.split('.')\n        x1 = x[0]\n        x2 = if x.length > 1 then  decimalSep + x[1] else ''\n        rgx = /(\\d+)(\\d{3})/\n        x1 = x1.replace(rgx, '$1' + thousandsSep + '$2') while rgx.test(x1)\n        return x1 + x2\n\n    numberFormat = (opts) ->\n        defaults =\n            digitsAfterDecimal: 2, scaler: 1,\n            thousandsSep: \",\", decimalSep: \".\"\n            prefix: \"\", suffix: \"\"\n        opts = $.extend({}, defaults, opts)\n        (x) ->\n            return \"\" if isNaN(x) or not isFinite(x)\n            result = addSeparators (opts.scaler*x).toFixed(opts.digitsAfterDecimal), opts.thousandsSep, opts.decimalSep\n            return \"\"+opts.prefix+result+opts.suffix\n\n    #aggregator templates default to US number formatting but this is overrideable\n    usFmt = numberFormat()\n    usFmtInt = numberFormat(digitsAfterDecimal: 0)\n    usFmtPct = numberFormat(digitsAfterDecimal:1, scaler: 100, suffix: \"%\")\n\n    aggregatorTemplates =\n        count: (formatter=usFmtInt) -> () -> (data, rowKey, colKey) ->\n            count: 0\n            push:  -> @count++\n            value: -> @count\n            format: formatter\n\n        uniques: (fn, formatter=usFmtInt) -> ([attr]) -> (data, rowKey, colKey) ->\n            uniq: []\n            push: (record) -> @uniq.push(record[attr]) if record[attr] not in @uniq\n            value: -> fn(@uniq)\n            format: formatter\n            numInputs: if attr? then 0 else 1\n\n        sum: (formatter=usFmt) -> ([attr]) -> (data, rowKey, colKey) ->\n            sum: 0\n            push: (record) -> @sum += parseFloat(record[attr]) if not isNaN parseFloat(record[attr])\n            value: -> @sum\n            format: formatter\n            numInputs: if attr? then 0 else 1\n\n        extremes: (mode, formatter=usFmt) -> ([attr]) -> (data, rowKey, colKey) ->\n            val: null\n            sorter: getSort(data?.sorters, attr)\n            push: (record) ->\n                x = record[attr]\n                if mode in [\"min\", \"max\"]\n                    x = parseFloat(x)\n                    if not isNaN x then @val = Math[mode](x, @val ? x)\n                if mode == \"first\" then @val = x if @sorter(x, @val ? x) <= 0\n                if mode == \"last\"  then @val = x if @sorter(x, @val ? x) >= 0\n            value: -> @val\n            format: (x) -> if isNaN(x) then x else formatter(x)\n            numInputs: if attr? then 0 else 1\n\n        quantile: (q, formatter=usFmt) -> ([attr]) -> (data, rowKey, colKey) ->\n            vals: []\n            push: (record) ->\n                x = parseFloat(record[attr])\n                @vals.push(x) if not isNaN(x)\n            value: ->\n                return null if @vals.length == 0\n                @vals.sort((a,b) -> a-b)\n                i = (@vals.length-1)*q\n                return (@vals[Math.floor(i)] + @vals[Math.ceil(i)])/2.0\n            format: formatter\n            numInputs: if attr? then 0 else 1\n\n        runningStat: (mode=\"mean\", ddof=1, formatter=usFmt) -> ([attr]) -> (data, rowKey, colKey) ->\n            n: 0.0, m: 0.0, s: 0.0\n            push: (record) ->\n                x = parseFloat(record[attr])\n                return if isNaN(x)\n                @n += 1.0\n                if @n == 1.0\n                    @m = x\n                else\n                    m_new = @m + (x - @m)/@n\n                    @s = @s + (x - @m)*(x - m_new)\n                    @m = m_new\n            value: ->\n                if mode == \"mean\"\n                    return if @n == 0 then 0/0 else @m\n                return 0 if @n <= ddof\n                switch mode\n                    when \"var\"   then @s/(@n-ddof)\n                    when \"stdev\" then Math.sqrt(@s/(@n-ddof))\n            format: formatter\n            numInputs: if attr? then 0 else 1\n\n        sumOverSum: (formatter=usFmt) -> ([num, denom]) -> (data, rowKey, colKey) ->\n            sumNum: 0\n            sumDenom: 0\n            push: (record) ->\n                @sumNum   += parseFloat(record[num])   if not isNaN parseFloat(record[num])\n                @sumDenom += parseFloat(record[denom]) if not isNaN parseFloat(record[denom])\n            value: -> @sumNum/@sumDenom\n            format: formatter\n            numInputs: if num? and denom? then 0 else 2\n\n        sumOverSumBound80: (upper=true, formatter=usFmt) -> ([num, denom]) -> (data, rowKey, colKey) ->\n            sumNum: 0\n            sumDenom: 0\n            push: (record) ->\n                @sumNum   += parseFloat(record[num])   if not isNaN parseFloat(record[num])\n                @sumDenom += parseFloat(record[denom]) if not isNaN parseFloat(record[denom])\n            value: ->\n                sign = if upper then 1 else -1\n                (0.821187207574908/@sumDenom + @sumNum/@sumDenom + 1.2815515655446004*sign*\n                    Math.sqrt(0.410593603787454/ (@sumDenom*@sumDenom) + (@sumNum*(1 - @sumNum/ @sumDenom))/ (@sumDenom*@sumDenom)))/\n                    (1 + 1.642374415149816/@sumDenom)\n            format: formatter\n            numInputs: if num? and denom? then 0 else 2\n\n        fractionOf: (wrapped, type=\"total\", formatter=usFmtPct) -> (x...) -> (data, rowKey, colKey) ->\n            selector: {total:[[],[]],row:[rowKey,[]],col:[[],colKey]}[type]\n            inner: wrapped(x...)(data, rowKey, colKey)\n            push: (record) -> @inner.push record\n            format: formatter\n            value: -> @inner.value() / data.getAggregator(@selector...).inner.value()\n            numInputs: wrapped(x...)().numInputs\n\n    aggregatorTemplates.countUnique = (f) -> aggregatorTemplates.uniques(((x) -> x.length), f)\n    aggregatorTemplates.listUnique =  (s) -> aggregatorTemplates.uniques(((x) -> x.sort(naturalSort).join(s)), ((x)->x))\n    aggregatorTemplates.max =         (f) -> aggregatorTemplates.extremes('max', f)\n    aggregatorTemplates.min =         (f) -> aggregatorTemplates.extremes('min', f)\n    aggregatorTemplates.first =       (f) -> aggregatorTemplates.extremes('first', f)\n    aggregatorTemplates.last =        (f) -> aggregatorTemplates.extremes('last', f)\n    aggregatorTemplates.median =      (f) -> aggregatorTemplates.quantile(0.5, f)\n    aggregatorTemplates.average =     (f) -> aggregatorTemplates.runningStat(\"mean\", 1, f)\n    aggregatorTemplates.var =         (ddof, f) -> aggregatorTemplates.runningStat(\"var\", ddof, f)\n    aggregatorTemplates.stdev =       (ddof, f) -> aggregatorTemplates.runningStat(\"stdev\", ddof, f)\n\n    #default aggregators & renderers use US naming and number formatting\n    aggregators = do (tpl = aggregatorTemplates) ->\n        \"Count\":                tpl.count(usFmtInt)\n        \"Count Unique Values\":  tpl.countUnique(usFmtInt)\n        \"List Unique Values\":   tpl.listUnique(\", \")\n        \"Sum\":                  tpl.sum(usFmt)\n        \"Integer Sum\":          tpl.sum(usFmtInt)\n        \"Average\":              tpl.average(usFmt)\n        \"Median\":               tpl.median(usFmt)\n        \"Sample Variance\":      tpl.var(1, usFmt)\n        \"Sample Standard Deviation\": tpl.stdev(1, usFmt)\n        \"Minimum\":              tpl.min(usFmt)\n        \"Maximum\":              tpl.max(usFmt)\n        \"First\":                tpl.first(usFmt)\n        \"Last\":                 tpl.last(usFmt)\n        \"Sum over Sum\":         tpl.sumOverSum(usFmt)\n        \"80% Upper Bound\":      tpl.sumOverSumBound80(true, usFmt)\n        \"80% Lower Bound\":      tpl.sumOverSumBound80(false, usFmt)\n        \"Sum as Fraction of Total\":     tpl.fractionOf(tpl.sum(),   \"total\", usFmtPct)\n        \"Sum as Fraction of Rows\":      tpl.fractionOf(tpl.sum(),   \"row\",   usFmtPct)\n        \"Sum as Fraction of Columns\":   tpl.fractionOf(tpl.sum(),   \"col\",   usFmtPct)\n        \"Count as Fraction of Total\":   tpl.fractionOf(tpl.count(), \"total\", usFmtPct)\n        \"Count as Fraction of Rows\":    tpl.fractionOf(tpl.count(), \"row\",   usFmtPct)\n        \"Count as Fraction of Columns\": tpl.fractionOf(tpl.count(), \"col\",   usFmtPct)\n\n    renderers =\n        \"Table\":          (data, opts) ->   pivotTableRenderer(data, opts)\n        \"Table Barchart\": (data, opts) -> $(pivotTableRenderer(data, opts)).barchart()\n        \"Heatmap\":        (data, opts) -> $(pivotTableRenderer(data, opts)).heatmap(\"heatmap\",    opts)\n        \"Row Heatmap\":    (data, opts) -> $(pivotTableRenderer(data, opts)).heatmap(\"rowheatmap\", opts)\n        \"Col Heatmap\":    (data, opts) -> $(pivotTableRenderer(data, opts)).heatmap(\"colheatmap\", opts)\n\n    locales =\n        en:\n            aggregators: aggregators\n            renderers: renderers\n            localeStrings:\n                renderError: \"An error occurred rendering the PivotTable results.\"\n                computeError: \"An error occurred computing the PivotTable results.\"\n                uiRenderError: \"An error occurred rendering the PivotTable UI.\"\n                selectAll: \"Select All\"\n                selectNone: \"Select None\"\n                tooMany: \"(too many to list)\"\n                filterResults: \"Filter values\"\n                apply: \"Apply\"\n                cancel: \"Cancel\"\n                totals: \"Totals\" #for table renderer\n                vs: \"vs\" #for gchart renderer\n                by: \"by\" #for gchart renderer\n\n    #dateFormat deriver l10n requires month and day names to be passed in directly\n    mthNamesEn = [\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"]\n    dayNamesEn = [\"Sun\",\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\"]\n    zeroPad = (number) -> (\"0\"+number).substr(-2,2)\n\n    derivers =\n        bin: (col, binWidth) -> (record) -> record[col] - record[col] % binWidth\n        dateFormat: (col, formatString, utcOutput=false, mthNames=mthNamesEn, dayNames=dayNamesEn) ->\n            utc = if utcOutput then \"UTC\" else \"\"\n            (record) -> #thanks http://stackoverflow.com/a/12213072/112871\n                date = new Date(Date.parse(record[col]))\n                if isNaN(date) then return \"\"\n                formatString.replace /%(.)/g, (m, p) ->\n                    switch p\n                        when \"y\" then date[\"get#{utc}FullYear\"]()\n                        when \"m\" then zeroPad(date[\"get#{utc}Month\"]()+1)\n                        when \"n\" then mthNames[date[\"get#{utc}Month\"]()]\n                        when \"d\" then zeroPad(date[\"get#{utc}Date\"]())\n                        when \"w\" then dayNames[date[\"get#{utc}Day\"]()]\n                        when \"x\" then date[\"get#{utc}Day\"]()\n                        when \"H\" then zeroPad(date[\"get#{utc}Hours\"]())\n                        when \"M\" then zeroPad(date[\"get#{utc}Minutes\"]())\n                        when \"S\" then zeroPad(date[\"get#{utc}Seconds\"]())\n                        else \"%\" + p\n\n    rx = /(\\d+)|(\\D+)/g\n    rd = /\\d/\n    rz = /^0/\n    naturalSort = (as, bs) =>\n        #nulls first\n        return -1 if bs? and not as?\n        return  1 if as? and not bs?\n\n        #then raw NaNs\n        return -1 if typeof as == \"number\" and isNaN(as)\n        return  1 if typeof bs == \"number\" and isNaN(bs)\n\n        #numbers and numbery strings group together\n        nas = +as\n        nbs = +bs\n        return -1 if nas < nbs\n        return  1 if nas > nbs\n\n        #within that, true numbers before numbery strings\n        return -1 if typeof as == \"number\" and typeof bs != \"number\"\n        return  1 if typeof bs == \"number\" and typeof as != \"number\"\n        return  0 if typeof as == \"number\" and typeof bs == \"number\"\n\n        # 'Infinity' is a textual number, so less than 'A'\n        return -1 if isNaN(nbs) and not isNaN(nas)\n        return  1 if isNaN(nas) and not isNaN(nbs)\n\n        #finally, \"smart\" string sorting per http://stackoverflow.com/a/4373421/112871\n        a = String(as)\n        b = String(bs)\n        return 0 if a == b\n        return (if a > b then 1 else -1) unless rd.test(a) and rd.test(b)\n\n        #special treatment for strings containing digits\n        a = a.match(rx) #create digits vs non-digit chunks and iterate through\n        b = b.match(rx)\n        while a.length and b.length\n            a1 = a.shift()\n            b1 = b.shift()\n            if a1 != b1\n                if rd.test(a1) and rd.test(b1) #both are digit chunks\n                    return a1.replace(rz, \".0\") - b1.replace(rz, \".0\")\n                else\n                    return (if a1 > b1 then 1 else -1)\n        return a.length - b.length\n\n    sortAs = (order) ->\n        mapping = {}\n        l_mapping = {} # sort lowercased keys similarly\n        for i, x of order\n            mapping[x] = i\n            l_mapping[x.toLowerCase()] = i if typeof x == \"string\"\n        (a, b) ->\n            if mapping[a]? and mapping[b]? then mapping[a] - mapping[b]\n            else if mapping[a]? then -1\n            else if mapping[b]? then 1\n            else if l_mapping[a]? and l_mapping[b]? then l_mapping[a] - l_mapping[b]\n            else if l_mapping[a]? then -1\n            else if l_mapping[b]? then 1\n            else naturalSort(a,b)\n\n    getSort = (sorters, attr) ->\n        if sorters?\n            if $.isFunction(sorters)\n                sort = sorters(attr)\n                return sort if $.isFunction(sort)\n            else if sorters[attr]?\n                return sorters[attr]\n        return naturalSort\n\n    ###\n    Data Model class\n    ###\n\n    class PivotData\n        constructor: (input, opts = {}) ->\n            @input = input\n            @aggregator = opts.aggregator ? aggregatorTemplates.count()()\n            @aggregatorName = opts.aggregatorName ? \"Count\"\n            @colAttrs = opts.cols ? []\n            @rowAttrs = opts.rows ? []\n            @valAttrs = opts.vals ? []\n            @sorters = opts.sorters ? {}\n            @rowOrder = opts.rowOrder ? \"key_a_to_z\"\n            @colOrder = opts.colOrder ? \"key_a_to_z\"\n            @derivedAttributes = opts.derivedAttributes ? {}\n            @filter = opts.filter ? (-> true)\n            @tree = {}\n            @rowKeys = []\n            @colKeys = []\n            @rowTotals = {}\n            @colTotals = {}\n            @allTotal = @aggregator(this, [], [])\n            @sorted = false\n\n            # iterate through input, accumulating data for cells\n            PivotData.forEachRecord @input, @derivedAttributes, (record) =>\n                @processRecord(record) if @filter(record)\n\n        #can handle arrays or jQuery selections of tables\n        @forEachRecord = (input, derivedAttributes, f) ->\n            if $.isEmptyObject derivedAttributes\n                addRecord = f\n            else\n                addRecord = (record) ->\n                    record[k] = v(record) ? record[k] for k, v of derivedAttributes\n                    f(record)\n\n            #if it's a function, have it call us back\n            if $.isFunction(input)\n                input(addRecord)\n            else if $.isArray(input)\n                if $.isArray(input[0]) #array of arrays\n                    for own i, compactRecord of input when i > 0\n                        record = {}\n                        record[k] = compactRecord[j] for own j, k of input[0]\n                        addRecord(record)\n                else #array of objects\n                    addRecord(record) for record in input\n            else if input instanceof $\n                tblCols = []\n                $(\"thead > tr > th\", input).each (i) -> tblCols.push $(this).text()\n                $(\"tbody > tr\", input).each (i) ->\n                    record = {}\n                    $(\"td\", this).each (j) -> record[tblCols[j]] = $(this).text()\n                    addRecord(record)\n            else\n                throw new Error(\"unknown input format\")\n\n        forEachMatchingRecord: (criteria, callback) ->\n            PivotData.forEachRecord @input, @derivedAttributes, (record) =>\n                return if not @filter(record)\n                for k, v of criteria\n                    return if v != (record[k] ? \"null\")\n                callback(record)\n\n        arrSort: (attrs) =>\n            sortersArr = (getSort(@sorters, a) for a in attrs)\n            (a,b) ->\n                for own i, sorter of sortersArr\n                    comparison = sorter(a[i], b[i])\n                    return comparison if comparison != 0\n                return 0\n\n        sortKeys: () =>\n            if not @sorted\n                @sorted = true\n                v = (r,c) => @getAggregator(r,c).value()\n                switch @rowOrder\n                    when \"value_a_to_z\"  then @rowKeys.sort (a,b) =>  naturalSort v(a,[]), v(b,[])\n                    when \"value_z_to_a\" then @rowKeys.sort (a,b) => -naturalSort v(a,[]), v(b,[])\n                    else             @rowKeys.sort @arrSort(@rowAttrs)\n                switch @colOrder\n                    when \"value_a_to_z\"  then @colKeys.sort (a,b) =>  naturalSort v([],a), v([],b)\n                    when \"value_z_to_a\" then @colKeys.sort (a,b) => -naturalSort v([],a), v([],b)\n                    else             @colKeys.sort @arrSort(@colAttrs)\n\n        getColKeys: () =>\n            @sortKeys()\n            return @colKeys\n\n        getRowKeys: () =>\n            @sortKeys()\n            return @rowKeys\n\n        processRecord: (record) -> #this code is called in a tight loop\n            colKey = []\n            rowKey = []\n            colKey.push record[x] ? \"null\" for x in @colAttrs\n            rowKey.push record[x] ? \"null\" for x in @rowAttrs\n            flatRowKey = rowKey.join(String.fromCharCode(0))\n            flatColKey = colKey.join(String.fromCharCode(0))\n\n            @allTotal.push record\n\n            if rowKey.length != 0\n                if not @rowTotals[flatRowKey]\n                    @rowKeys.push rowKey\n                    @rowTotals[flatRowKey] = @aggregator(this, rowKey, [])\n                @rowTotals[flatRowKey].push record\n\n            if colKey.length != 0\n                if not @colTotals[flatColKey]\n                    @colKeys.push colKey\n                    @colTotals[flatColKey] = @aggregator(this, [], colKey)\n                @colTotals[flatColKey].push record\n\n            if colKey.length != 0 and rowKey.length != 0\n                if not @tree[flatRowKey]\n                    @tree[flatRowKey] = {}\n                if not @tree[flatRowKey][flatColKey]\n                    @tree[flatRowKey][flatColKey] = @aggregator(this, rowKey, colKey)\n                @tree[flatRowKey][flatColKey].push record\n\n        getAggregator: (rowKey, colKey) =>\n            flatRowKey = rowKey.join(String.fromCharCode(0))\n            flatColKey = colKey.join(String.fromCharCode(0))\n            if rowKey.length == 0 and colKey.length == 0\n                agg = @allTotal\n            else if rowKey.length == 0\n                agg = @colTotals[flatColKey]\n            else if colKey.length == 0\n                agg = @rowTotals[flatRowKey]\n            else\n                agg = @tree[flatRowKey][flatColKey]\n            return agg ? {value: (-> null), format: -> \"\"}\n\n    #expose these to the outside world\n    $.pivotUtilities = {aggregatorTemplates, aggregators, renderers, derivers, locales,\n        naturalSort, numberFormat, sortAs, PivotData}\n\n    ###\n    Default Renderer for hierarchical table layout\n    ###\n\n    pivotTableRenderer = (pivotData, opts) ->\n\n        defaults =\n            table:\n                clickCallback: null\n                rowTotals: true\n                colTotals: true\n            localeStrings: totals: \"Totals\"\n\n        opts = $.extend(true, {}, defaults, opts)\n\n        colAttrs = pivotData.colAttrs\n        rowAttrs = pivotData.rowAttrs\n        rowKeys = pivotData.getRowKeys()\n        colKeys = pivotData.getColKeys()\n\n        if opts.table.clickCallback\n            getClickHandler = (value, rowValues, colValues) ->\n                filters = {}\n                filters[attr] = colValues[i] for own i, attr of colAttrs when colValues[i]?\n                filters[attr] = rowValues[i] for own i, attr of rowAttrs when rowValues[i]?\n                return (e) -> opts.table.clickCallback(e, value, filters, pivotData)\n\n        #now actually build the output\n        result = document.createElement(\"table\")\n        result.className = \"pvtTable\"\n\n        #helper function for setting row/col-span in pivotTableRenderer\n        spanSize = (arr, i, j) ->\n            if i != 0\n                noDraw = true\n                for x in [0..j]\n                    if arr[i-1][x] != arr[i][x]\n                        noDraw = false\n                if noDraw\n                  return -1 #do not draw cell\n            len = 0\n            while i+len < arr.length\n                stop = false\n                for x in [0..j]\n                    stop = true if arr[i][x] != arr[i+len][x]\n                break if stop\n                len++\n            return len\n\n        #the first few rows are for col headers\n        thead = document.createElement(\"thead\")\n        for own j, c of colAttrs\n            tr = document.createElement(\"tr\")\n            if parseInt(j) == 0 and rowAttrs.length != 0\n                th = document.createElement(\"th\")\n                th.setAttribute(\"colspan\", rowAttrs.length)\n                th.setAttribute(\"rowspan\", colAttrs.length)\n                tr.appendChild th\n            th = document.createElement(\"th\")\n            th.className = \"pvtAxisLabel\"\n            th.textContent = c\n            tr.appendChild th\n            for own i, colKey of colKeys\n                x = spanSize(colKeys, parseInt(i), parseInt(j))\n                if x != -1\n                    th = document.createElement(\"th\")\n                    th.className = \"pvtColLabel\"\n                    th.textContent = colKey[j]\n                    th.setAttribute(\"colspan\", x)\n                    if parseInt(j) == colAttrs.length-1 and rowAttrs.length != 0\n                        th.setAttribute(\"rowspan\", 2)\n                    tr.appendChild th\n            if parseInt(j) == 0 && opts.table.rowTotals\n                th = document.createElement(\"th\")\n                th.className = \"pvtTotalLabel pvtRowTotalLabel\"\n                th.innerHTML = opts.localeStrings.totals\n                th.setAttribute(\"rowspan\", colAttrs.length + (if rowAttrs.length ==0 then 0 else 1))\n                tr.appendChild th\n            thead.appendChild tr\n\n        #then a row for row header headers\n        if rowAttrs.length !=0\n            tr = document.createElement(\"tr\")\n            for own i, r of rowAttrs\n                th = document.createElement(\"th\")\n                th.className = \"pvtAxisLabel\"\n                th.textContent = r\n                tr.appendChild th\n            th = document.createElement(\"th\")\n            if colAttrs.length ==0\n                th.className = \"pvtTotalLabel pvtRowTotalLabel\"\n                th.innerHTML = opts.localeStrings.totals\n            tr.appendChild th\n            thead.appendChild tr\n        result.appendChild thead\n\n        #now the actual data rows, with their row headers and totals\n        tbody = document.createElement(\"tbody\")\n        for own i, rowKey of rowKeys\n            tr = document.createElement(\"tr\")\n            for own j, txt of rowKey\n                x = spanSize(rowKeys, parseInt(i), parseInt(j))\n                if x != -1\n                    th = document.createElement(\"th\")\n                    th.className = \"pvtRowLabel\"\n                    th.textContent = txt\n                    th.setAttribute(\"rowspan\", x)\n                    if parseInt(j) == rowAttrs.length-1 and colAttrs.length !=0\n                        th.setAttribute(\"colspan\",2)\n                    tr.appendChild th\n            for own j, colKey of colKeys #this is the tight loop\n                aggregator = pivotData.getAggregator(rowKey, colKey)\n                val = aggregator.value()\n                td = document.createElement(\"td\")\n                td.className = \"pvtVal row#{i} col#{j}\"\n                td.textContent = aggregator.format(val)\n                td.setAttribute(\"data-value\", val)\n                if getClickHandler?\n                    td.onclick = getClickHandler(val, rowKey, colKey)\n                tr.appendChild td\n\n            if opts.table.rowTotals || colAttrs.length == 0\n                totalAggregator = pivotData.getAggregator(rowKey, [])\n                val = totalAggregator.value()\n                td = document.createElement(\"td\")\n                td.className = \"pvtTotal rowTotal\"\n                td.textContent = totalAggregator.format(val)\n                td.setAttribute(\"data-value\", val)\n                if getClickHandler?\n                    td.onclick = getClickHandler(val, rowKey, [])\n                td.setAttribute(\"data-for\", \"row\"+i)\n                tr.appendChild td\n            tbody.appendChild tr\n\n        #finally, the row for col totals, and a grand total\n        if opts.table.colTotals || rowAttrs.length == 0\n            tr = document.createElement(\"tr\")\n            if opts.table.colTotals || rowAttrs.length == 0\n                th = document.createElement(\"th\")\n                th.className = \"pvtTotalLabel pvtColTotalLabel\"\n                th.innerHTML = opts.localeStrings.totals\n                th.setAttribute(\"colspan\", rowAttrs.length + (if colAttrs.length == 0 then 0 else 1))\n                tr.appendChild th\n            for own j, colKey of colKeys\n                totalAggregator = pivotData.getAggregator([], colKey)\n                val = totalAggregator.value()\n                td = document.createElement(\"td\")\n                td.className = \"pvtTotal colTotal\"\n                td.textContent = totalAggregator.format(val)\n                td.setAttribute(\"data-value\", val)\n                if getClickHandler?\n                    td.onclick = getClickHandler(val, [], colKey)\n                td.setAttribute(\"data-for\", \"col\"+j)\n                tr.appendChild td\n            if opts.table.rowTotals || colAttrs.length == 0\n                totalAggregator = pivotData.getAggregator([], [])\n                val = totalAggregator.value()\n                td = document.createElement(\"td\")\n                td.className = \"pvtGrandTotal\"\n                td.textContent = totalAggregator.format(val)\n                td.setAttribute(\"data-value\", val)\n                if getClickHandler?\n                    td.onclick = getClickHandler(val, [], [])\n                tr.appendChild td\n            tbody.appendChild tr\n        result.appendChild tbody\n\n        #squirrel this away for later\n        result.setAttribute(\"data-numrows\", rowKeys.length)\n        result.setAttribute(\"data-numcols\", colKeys.length)\n\n        return result\n\n    ###\n    Pivot Table core: create PivotData object and call Renderer on it\n    ###\n\n    $.fn.pivot = (input, inputOpts, locale=\"en\") ->\n        locale = \"en\" if not locales[locale]?\n        defaults =\n            cols : [], rows: [], vals: []\n            rowOrder: \"key_a_to_z\", colOrder: \"key_a_to_z\"\n            dataClass: PivotData\n            filter: -> true\n            aggregator: aggregatorTemplates.count()()\n            aggregatorName: \"Count\"\n            sorters: {}\n            derivedAttributes: {}\n            renderer: pivotTableRenderer\n\n        localeStrings = $.extend(true, {}, locales.en.localeStrings, locales[locale].localeStrings)\n        localeDefaults =\n            rendererOptions: {localeStrings}\n            localeStrings: localeStrings\n\n        opts = $.extend(true, {}, localeDefaults, $.extend({}, defaults, inputOpts))\n\n        result = null\n        try\n            pivotData = new opts.dataClass(input, opts)\n            try\n                result = opts.renderer(pivotData, opts.rendererOptions)\n            catch e\n                console.error(e.stack) if console?\n                result = $(\"<span>\").html opts.localeStrings.renderError\n        catch e\n            console.error(e.stack) if console?\n            result = $(\"<span>\").html opts.localeStrings.computeError\n\n        x = this[0]\n        x.removeChild(x.lastChild) while x.hasChildNodes()\n        return @append result\n\n\n    ###\n    Pivot Table UI: calls Pivot Table core above with options set by user\n    ###\n\n    $.fn.pivotUI = (input, inputOpts, overwrite = false, locale=\"en\") ->\n        locale = \"en\" if not locales[locale]?\n        defaults =\n            derivedAttributes: {}\n            aggregators: locales[locale].aggregators\n            renderers: locales[locale].renderers\n            hiddenAttributes: []\n            hiddenFromAggregators: []\n            hiddenFromDragDrop: []\n            menuLimit: 500\n            cols: [], rows: [], vals: []\n            rowOrder: \"key_a_to_z\", colOrder: \"key_a_to_z\"\n            dataClass: PivotData\n            exclusions: {}\n            inclusions: {}\n            unusedAttrsVertical: 85\n            autoSortUnusedAttrs: false\n            onRefresh: null\n            showUI: true\n            filter: -> true\n            sorters: {}\n\n        localeStrings = $.extend(true, {}, locales.en.localeStrings, locales[locale].localeStrings)\n        localeDefaults =\n            rendererOptions: {localeStrings}\n            localeStrings: localeStrings\n\n        existingOpts = @data \"pivotUIOptions\"\n        if not existingOpts? or overwrite\n            opts = $.extend(true, {}, localeDefaults, $.extend({}, defaults, inputOpts))\n        else\n            opts = existingOpts\n\n        try\n            # do a first pass on the data to cache a materialized copy of any\n            # function-valued inputs and to compute dimension cardinalities\n            attrValues = {}\n            materializedInput = []\n            recordsProcessed = 0\n            PivotData.forEachRecord input, opts.derivedAttributes, (record) ->\n                return unless opts.filter(record)\n                materializedInput.push(record)\n                for own attr of record\n                    if not attrValues[attr]?\n                        attrValues[attr] = {}\n                        if recordsProcessed > 0\n                            attrValues[attr][\"null\"] = recordsProcessed\n                for attr of attrValues\n                    value = record[attr] ? \"null\"\n                    attrValues[attr][value] ?= 0\n                    attrValues[attr][value]++\n                recordsProcessed++\n\n            #start building the output\n            uiTable = $(\"<table>\", \"class\": \"pvtUi\").attr(\"cellpadding\", 5)\n\n            #renderer control\n            rendererControl = $(\"<td>\").addClass(\"pvtUiCell\")\n\n            renderer = $(\"<select>\")\n                .addClass('pvtRenderer')\n                .appendTo(rendererControl)\n                .bind \"change\", -> refresh() #capture reference\n            for own x of opts.renderers\n                $(\"<option>\").val(x).html(x).appendTo(renderer)\n\n\n            #axis list, including the double-click menu\n            unused = $(\"<td>\").addClass('pvtAxisContainer pvtUnused pvtUiCell')\n            shownAttributes = (a for a of attrValues when a not in opts.hiddenAttributes)\n            shownInAggregators = (c for c in shownAttributes when c not in opts.hiddenFromAggregators)\n            shownInDragDrop = (c for c in shownAttributes when c not in opts.hiddenFromDragDrop)\n\n\n            unusedAttrsVerticalAutoOverride = false\n            if opts.unusedAttrsVertical == \"auto\"\n                unusedAttrsVerticalAutoCutoff = 120 # legacy support\n            else\n                unusedAttrsVerticalAutoCutoff = parseInt opts.unusedAttrsVertical\n\n            if not isNaN(unusedAttrsVerticalAutoCutoff)\n                attrLength = 0\n                attrLength += a.length for a in shownInDragDrop\n                unusedAttrsVerticalAutoOverride = attrLength > unusedAttrsVerticalAutoCutoff\n\n            if opts.unusedAttrsVertical == true or unusedAttrsVerticalAutoOverride\n                unused.addClass('pvtVertList')\n            else\n                unused.addClass('pvtHorizList')\n\n            for own i, attr of shownInDragDrop\n                do (attr) ->\n                    values = (v for v of attrValues[attr])\n                    hasExcludedItem = false\n                    valueList = $(\"<div>\").addClass('pvtFilterBox').hide()\n\n                    valueList.append $(\"<h4>\").append(\n                        $(\"<span>\").text(attr),\n                        $(\"<span>\").addClass(\"count\").text(\"(#{values.length})\"),\n                        )\n                    if values.length > opts.menuLimit\n                        valueList.append $(\"<p>\").html(opts.localeStrings.tooMany)\n                    else\n                        if values.length > 5\n                            controls = $(\"<p>\").appendTo(valueList)\n                            sorter = getSort(opts.sorters, attr)\n                            placeholder = opts.localeStrings.filterResults\n                            $(\"<input>\", {type: \"text\"}).appendTo(controls)\n                                .attr({placeholder: placeholder, class: \"pvtSearch\"})\n                                .bind \"keyup\", ->\n                                    filter = $(this).val().toLowerCase().trim()\n                                    accept_gen = (prefix, accepted) -> (v) ->\n                                        real_filter = filter.substring(prefix.length).trim()\n                                        return true if real_filter.length == 0\n                                        return Math.sign(sorter(v.toLowerCase(), real_filter)) in accepted\n                                    accept =\n                                        if      filter.indexOf(\">=\") == 0 then accept_gen(\">=\", [1,0])\n                                        else if filter.indexOf(\"<=\") == 0 then accept_gen(\"<=\", [-1,0])\n                                        else if filter.indexOf(\">\") == 0  then accept_gen(\">\",  [1])\n                                        else if filter.indexOf(\"<\") == 0  then accept_gen(\"<\",  [-1])\n                                        else if filter.indexOf(\"~\") == 0  then (v) ->\n                                                return true if filter.substring(1).trim().length == 0\n                                                v.toLowerCase().match(filter.substring(1))\n                                        else (v) -> v.toLowerCase().indexOf(filter) != -1\n\n                                    valueList.find('.pvtCheckContainer p label span.value').each ->\n                                        if accept($(this).text())\n                                            $(this).parent().parent().show()\n                                        else\n                                            $(this).parent().parent().hide()\n                            controls.append $(\"<br>\")\n                            $(\"<button>\", {type:\"button\"}).appendTo(controls)\n                                .html(opts.localeStrings.selectAll)\n                                .bind \"click\", ->\n                                    valueList.find(\"input:visible:not(:checked)\")\n                                        .prop(\"checked\", true).toggleClass(\"changed\")\n                                    return false\n                            $(\"<button>\", {type:\"button\"}).appendTo(controls)\n                                .html(opts.localeStrings.selectNone)\n                                .bind \"click\", ->\n                                    valueList.find(\"input:visible:checked\")\n                                        .prop(\"checked\", false).toggleClass(\"changed\")\n                                    return false\n\n                        checkContainer = $(\"<div>\").addClass(\"pvtCheckContainer\").appendTo(valueList)\n\n                        for value in values.sort(getSort(opts.sorters, attr))\n                             valueCount = attrValues[attr][value]\n                             filterItem = $(\"<label>\")\n                             filterItemExcluded = false\n                             if opts.inclusions[attr]\n                                filterItemExcluded = (value not in opts.inclusions[attr])\n                             else if opts.exclusions[attr]\n                                filterItemExcluded = (value in opts.exclusions[attr])\n                             hasExcludedItem ||= filterItemExcluded\n                             $(\"<input>\")\n                                .attr(\"type\", \"checkbox\").addClass('pvtFilter')\n                                .attr(\"checked\", !filterItemExcluded).data(\"filter\", [attr,value])\n                                .appendTo(filterItem)\n                                .bind \"change\", -> $(this).toggleClass(\"changed\")\n                             filterItem.append $(\"<span>\").addClass(\"value\").text(value)\n                             filterItem.append $(\"<span>\").addClass(\"count\").text(\"(\"+valueCount+\")\")\n                             checkContainer.append $(\"<p>\").append(filterItem)\n\n                    closeFilterBox = ->\n                        if valueList.find(\"[type='checkbox']\").length >\n                               valueList.find(\"[type='checkbox']:checked\").length\n                                attrElem.addClass \"pvtFilteredAttribute\"\n                            else\n                                attrElem.removeClass \"pvtFilteredAttribute\"\n\n                            valueList.find('.pvtSearch').val('')\n                            valueList.find('.pvtCheckContainer p').show()\n                            valueList.hide()\n\n                    finalButtons = $(\"<p>\").appendTo(valueList)\n\n                    if values.length <= opts.menuLimit\n                        $(\"<button>\", {type: \"button\"}).text(opts.localeStrings.apply)\n                            .appendTo(finalButtons).bind \"click\", ->\n                                if valueList.find(\".changed\").removeClass(\"changed\").length\n                                    refresh()\n                                closeFilterBox()\n\n                    $(\"<button>\", {type: \"button\"}).text(opts.localeStrings.cancel)\n                        .appendTo(finalButtons).bind \"click\", ->\n                            valueList.find(\".changed:checked\")\n                                .removeClass(\"changed\").prop(\"checked\", false)\n                            valueList.find(\".changed:not(:checked)\")\n                                .removeClass(\"changed\").prop(\"checked\", true)\n                            closeFilterBox()\n\n                    triangleLink = $(\"<span>\").addClass('pvtTriangle')\n                        .html(\" &#x25BE;\").bind \"click\", (e) ->\n                            {left, top} = $(e.currentTarget).position()\n                            valueList.css(left: left+10, top: top+10).show()\n\n                    attrElem = $(\"<li>\").addClass(\"axis_#{i}\")\n                        .append $(\"<span>\").addClass('pvtAttr').text(attr).data(\"attrName\", attr).append(triangleLink)\n\n                    attrElem.addClass('pvtFilteredAttribute') if hasExcludedItem\n                    unused.append(attrElem).append(valueList)\n\n            tr1 = $(\"<tr>\").appendTo(uiTable)\n\n            #aggregator menu and value area\n\n            aggregator = $(\"<select>\").addClass('pvtAggregator')\n                .bind \"change\", -> refresh() #capture reference\n            for own x of opts.aggregators\n                aggregator.append $(\"<option>\").val(x).html(x)\n\n            ordering =\n                key_a_to_z:   {rowSymbol: \"&varr;\", colSymbol: \"&harr;\", next: \"value_a_to_z\"}\n                value_a_to_z: {rowSymbol: \"&darr;\", colSymbol: \"&rarr;\", next: \"value_z_to_a\"}\n                value_z_to_a: {rowSymbol: \"&uarr;\", colSymbol: \"&larr;\", next: \"key_a_to_z\"}\n\n            rowOrderArrow = $(\"<a>\", role: \"button\").addClass(\"pvtRowOrder\")\n                .data(\"order\", opts.rowOrder).html(ordering[opts.rowOrder].rowSymbol)\n                .bind \"click\", ->\n                    $(this).data(\"order\", ordering[$(this).data(\"order\")].next)\n                    $(this).html(ordering[$(this).data(\"order\")].rowSymbol)\n                    refresh()\n\n            colOrderArrow = $(\"<a>\", role: \"button\").addClass(\"pvtColOrder\")\n                .data(\"order\", opts.colOrder).html(ordering[opts.colOrder].colSymbol)\n                .bind \"click\", ->\n                    $(this).data(\"order\", ordering[$(this).data(\"order\")].next)\n                    $(this).html(ordering[$(this).data(\"order\")].colSymbol)\n                    refresh()\n\n            $(\"<td>\").addClass('pvtVals pvtUiCell')\n              .appendTo(tr1)\n              .append(aggregator)\n              .append(rowOrderArrow)\n              .append(colOrderArrow)\n              .append($(\"<br>\"))\n\n            #column axes\n            $(\"<td>\").addClass('pvtAxisContainer pvtHorizList pvtCols pvtUiCell').appendTo(tr1)\n\n            tr2 = $(\"<tr>\").appendTo(uiTable)\n\n            #row axes\n            tr2.append $(\"<td>\").addClass('pvtAxisContainer pvtRows pvtUiCell').attr(\"valign\", \"top\")\n\n            #the actual pivot table container\n            pivotTable = $(\"<td>\")\n                .attr(\"valign\", \"top\")\n                .addClass('pvtRendererArea')\n                .appendTo(tr2)\n\n            #finally the renderer dropdown and unused attribs are inserted at the requested location\n            if opts.unusedAttrsVertical == true or unusedAttrsVerticalAutoOverride\n                uiTable.find('tr:nth-child(1)').prepend rendererControl\n                uiTable.find('tr:nth-child(2)').prepend unused\n            else\n                uiTable.prepend $(\"<tr>\").append(rendererControl).append(unused)\n\n            #render the UI in its default state\n            @html uiTable\n\n            #set up the UI initial state as requested by moving elements around\n\n            for x in opts.cols\n                @find(\".pvtCols\").append @find(\".axis_#{$.inArray(x, shownInDragDrop)}\")\n            for x in opts.rows\n                @find(\".pvtRows\").append @find(\".axis_#{$.inArray(x, shownInDragDrop)}\")\n            if opts.aggregatorName?\n                @find(\".pvtAggregator\").val opts.aggregatorName\n            if opts.rendererName?\n                @find(\".pvtRenderer\").val opts.rendererName\n\n            @find(\".pvtUiCell\").hide() unless opts.showUI\n\n            initialRender = true\n\n            #set up for refreshing\n            refreshDelayed = =>\n                subopts =\n                    derivedAttributes: opts.derivedAttributes\n                    localeStrings: opts.localeStrings\n                    rendererOptions: opts.rendererOptions\n                    sorters: opts.sorters\n                    cols: [], rows: []\n                    dataClass: opts.dataClass\n\n                numInputsToProcess = opts.aggregators[aggregator.val()]([])().numInputs ? 0\n                vals = []\n                @find(\".pvtRows li span.pvtAttr\").each -> subopts.rows.push $(this).data(\"attrName\")\n                @find(\".pvtCols li span.pvtAttr\").each -> subopts.cols.push $(this).data(\"attrName\")\n                @find(\".pvtVals select.pvtAttrDropdown\").each ->\n                    if numInputsToProcess == 0\n                        $(this).remove()\n                    else\n                        numInputsToProcess--\n                        vals.push $(this).val() if $(this).val() != \"\"\n\n                if numInputsToProcess != 0\n                    pvtVals = @find(\".pvtVals\")\n                    for x in [0...numInputsToProcess]\n                        newDropdown = $(\"<select>\")\n                            .addClass('pvtAttrDropdown')\n                            .append($(\"<option>\"))\n                            .bind \"change\", -> refresh()\n                        for attr in shownInAggregators\n                            newDropdown.append($(\"<option>\").val(attr).text(attr))\n                        pvtVals.append(newDropdown)\n\n                if initialRender\n                    vals = opts.vals\n                    i = 0\n                    @find(\".pvtVals select.pvtAttrDropdown\").each ->\n                        $(this).val vals[i]\n                        i++\n                    initialRender = false\n\n                subopts.aggregatorName = aggregator.val()\n                subopts.vals = vals\n                subopts.aggregator = opts.aggregators[aggregator.val()](vals)\n                subopts.renderer = opts.renderers[renderer.val()]\n                subopts.rowOrder = rowOrderArrow.data(\"order\")\n                subopts.colOrder = colOrderArrow.data(\"order\")\n                #construct filter here\n                exclusions = {}\n                @find('input.pvtFilter').not(':checked').each ->\n                    filter = $(this).data(\"filter\")\n                    if exclusions[filter[0]]?\n                        exclusions[filter[0]].push( filter[1] )\n                    else\n                        exclusions[filter[0]] = [ filter[1] ]\n                #include inclusions when exclusions present\n                inclusions = {}\n                @find('input.pvtFilter:checked').each ->\n                    filter = $(this).data(\"filter\")\n                    if exclusions[filter[0]]?\n                        if inclusions[filter[0]]?\n                            inclusions[filter[0]].push( filter[1] )\n                        else\n                            inclusions[filter[0]] = [ filter[1] ]\n\n                subopts.filter = (record) ->\n                    return false if not opts.filter(record)\n                    for k,excludedItems of exclusions\n                        return false if \"\"+(record[k] ? 'null') in excludedItems\n                    return true\n\n                pivotTable.pivot(materializedInput,subopts)\n                pivotUIOptions = $.extend {}, opts,\n                    cols: subopts.cols\n                    rows: subopts.rows\n                    colOrder: subopts.colOrder\n                    rowOrder: subopts.rowOrder\n                    vals: vals\n                    exclusions: exclusions\n                    inclusions: inclusions\n                    inclusionsInfo: inclusions #duplicated for backwards-compatibility\n                    aggregatorName: aggregator.val()\n                    rendererName: renderer.val()\n\n                @data \"pivotUIOptions\", pivotUIOptions\n\n                # if requested make sure unused columns are in alphabetical order\n                if opts.autoSortUnusedAttrs\n                    unusedAttrsContainer = @find(\"td.pvtUnused.pvtAxisContainer\")\n                    $(unusedAttrsContainer).children(\"li\")\n                        .sort((a, b) => naturalSort($(a).text(), $(b).text()))\n                        .appendTo unusedAttrsContainer\n\n                pivotTable.css(\"opacity\", 1)\n                opts.onRefresh(pivotUIOptions) if opts.onRefresh?\n\n            refresh = =>\n                pivotTable.css(\"opacity\", 0.5)\n                setTimeout refreshDelayed, 10\n\n            #the very first refresh will actually display the table\n            refresh()\n\n            @find(\".pvtAxisContainer\").sortable\n                    update: (e, ui) -> refresh() if not ui.sender?\n                    connectWith: @find(\".pvtAxisContainer\")\n                    items: 'li'\n                    placeholder: 'pvtPlaceholder'\n        catch e\n            console.error(e.stack) if console?\n            @html opts.localeStrings.uiRenderError\n        return this\n\n    ###\n    Heatmap post-processing\n    ###\n\n    $.fn.heatmap = (scope = \"heatmap\", opts) ->\n        numRows = @data \"numrows\"\n        numCols = @data \"numcols\"\n\n        # given a series of values\n        # must return a function to map a given value to a CSS color\n        colorScaleGenerator = opts?.heatmap?.colorScaleGenerator\n        colorScaleGenerator ?= (values) ->\n            min = Math.min(values...)\n            max = Math.max(values...)\n            return (x) ->\n                nonRed = 255 - Math.round 255*(x-min)/(max-min)\n                return \"rgb(255,#{nonRed},#{nonRed})\"\n\n        heatmapper = (scope) =>\n            forEachCell = (f) =>\n                @find(scope).each ->\n                    x = $(this).data(\"value\")\n                    f(x, $(this)) if x? and isFinite(x)\n\n            values = []\n            forEachCell (x) -> values.push x\n            colorScale = colorScaleGenerator(values)\n            forEachCell (x, elem) -> elem.css \"background-color\", colorScale(x)\n\n        switch scope\n            when \"heatmap\"    then heatmapper \".pvtVal\"\n            when \"rowheatmap\" then heatmapper \".pvtVal.row#{i}\" for i in [0...numRows]\n            when \"colheatmap\" then heatmapper \".pvtVal.col#{j}\" for j in [0...numCols]\n\n        heatmapper \".pvtTotal.rowTotal\"\n        heatmapper \".pvtTotal.colTotal\"\n\n        return this\n\n    ###\n    Barchart post-processing\n    ###\n\n    $.fn.barchart = (opts) ->\n        numRows = @data \"numrows\"\n        numCols = @data \"numcols\"\n\n        barcharter = (scope) =>\n            forEachCell = (f) =>\n                @find(scope).each ->\n                    x = $(this).data(\"value\")\n                    f(x, $(this)) if x? and isFinite(x)\n\n            values = []\n            forEachCell (x) -> values.push x\n            max = Math.max(values...)\n            if max < 0\n                max = 0\n            range = max;\n            min = Math.min(values...)\n            if min < 0\n                range = max - min\n            scaler = (x) -> 100*x/(1.4*range)\n            forEachCell (x, elem) ->\n                text = elem.text()\n                wrapper = $(\"<div>\").css\n                    \"position\": \"relative\"\n                    \"height\": \"55px\"\n                bgColor = \"gray\"\n                bBase = 0\n                if min < 0\n                    bBase = scaler(-min)\n                if x < 0\n                    bBase += scaler(x)\n                    bgColor = \"darkred\"\n                    x = -x\n                wrapper.append $(\"<div>\").css\n                    \"position\": \"absolute\"\n                    \"bottom\": bBase + \"%\"\n                    \"left\": 0\n                    \"right\": 0\n                    \"height\": scaler(x) + \"%\"\n                    \"background-color\": bgColor\n                wrapper.append $(\"<div>\").text(text).css\n                    \"position\":\"relative\"\n                    \"padding-left\":\"5px\"\n                    \"padding-right\":\"5px\"\n\n                elem.css(\"padding\": 0,\"padding-top\": \"5px\", \"text-align\": \"center\").html wrapper\n\n        barcharter \".pvtVal.row#{i}\" for i in [0...numRows]\n        barcharter \".pvtTotal.colTotal\"\n\n        return this\n"]}
\ No newline at end of file
+{"version":3,"file":"pivot.js","sources":["pivot.coffee"],"names":[],"mappings":"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","sourcesContent":["callWithJQuery = (pivotModule) ->\n    if typeof exports is \"object\" and typeof module is \"object\" # CommonJS\n        pivotModule require(\"jquery\")\n    else if typeof define is \"function\" and define.amd # AMD\n        define [\"jquery\"], pivotModule\n    # Plain browser env\n    else\n        pivotModule jQuery\n\ncallWithJQuery ($) ->\n\n    ###\n    Utilities\n    ###\n\n    addSeparators = (nStr, thousandsSep, decimalSep) ->\n        nStr += ''\n        x = nStr.split('.')\n        x1 = x[0]\n        x2 = if x.length > 1 then  decimalSep + x[1] else ''\n        rgx = /(\\d+)(\\d{3})/\n        x1 = x1.replace(rgx, '$1' + thousandsSep + '$2') while rgx.test(x1)\n        return x1 + x2\n\n    numberFormat = (opts) ->\n        defaults =\n            digitsAfterDecimal: 2, scaler: 1,\n            thousandsSep: \",\", decimalSep: \".\"\n            prefix: \"\", suffix: \"\"\n        opts = $.extend({}, defaults, opts)\n        (x) ->\n            return \"\" if isNaN(x) or not isFinite(x)\n            result = addSeparators (opts.scaler*x).toFixed(opts.digitsAfterDecimal), opts.thousandsSep, opts.decimalSep\n            return \"\"+opts.prefix+result+opts.suffix\n\n    #aggregator templates default to US number formatting but this is overrideable\n    usFmt = numberFormat()\n    usFmtInt = numberFormat(digitsAfterDecimal: 0)\n    usFmtPct = numberFormat(digitsAfterDecimal:1, scaler: 100, suffix: \"%\")\n\n    aggregatorTemplates =\n        count: (formatter=usFmtInt) -> () -> (data, rowKey, colKey) ->\n            count: 0\n            push:  -> @count++\n            value: -> @count\n            format: formatter\n\n        uniques: (fn, formatter=usFmtInt) -> ([attr]) -> (data, rowKey, colKey) ->\n            uniq: []\n            push: (record) -> @uniq.push(record[attr]) if record[attr] not in @uniq\n            value: -> fn(@uniq)\n            format: formatter\n            numInputs: if attr? then 0 else 1\n\n        sum: (formatter=usFmt) -> ([attr]) -> (data, rowKey, colKey) ->\n            sum: 0\n            push: (record) -> @sum += parseFloat(record[attr]) if not isNaN parseFloat(record[attr])\n            value: -> @sum\n            format: formatter\n            numInputs: if attr? then 0 else 1\n\n        extremes: (mode, formatter=usFmt) -> ([attr]) -> (data, rowKey, colKey) ->\n            val: null\n            sorter: getSort(data?.sorters, attr)\n            push: (record) ->\n                x = record[attr]\n                if mode in [\"min\", \"max\"]\n                    x = parseFloat(x)\n                    if not isNaN x then @val = Math[mode](x, @val ? x)\n                if mode == \"first\" then @val = x if @sorter(x, @val ? x) <= 0\n                if mode == \"last\"  then @val = x if @sorter(x, @val ? x) >= 0\n            value: -> @val\n            format: (x) -> if isNaN(x) then x else formatter(x)\n            numInputs: if attr? then 0 else 1\n\n        quantile: (q, formatter=usFmt) -> ([attr]) -> (data, rowKey, colKey) ->\n            vals: []\n            push: (record) ->\n                x = parseFloat(record[attr])\n                @vals.push(x) if not isNaN(x)\n            value: ->\n                return null if @vals.length == 0\n                @vals.sort((a,b) -> a-b)\n                i = (@vals.length-1)*q\n                return (@vals[Math.floor(i)] + @vals[Math.ceil(i)])/2.0\n            format: formatter\n            numInputs: if attr? then 0 else 1\n\n        runningStat: (mode=\"mean\", ddof=1, formatter=usFmt) -> ([attr]) -> (data, rowKey, colKey) ->\n            n: 0.0, m: 0.0, s: 0.0\n            push: (record) ->\n                x = parseFloat(record[attr])\n                return if isNaN(x)\n                @n += 1.0\n                if @n == 1.0\n                    @m = x\n                else\n                    m_new = @m + (x - @m)/@n\n                    @s = @s + (x - @m)*(x - m_new)\n                    @m = m_new\n            value: ->\n                if mode == \"mean\"\n                    return if @n == 0 then 0/0 else @m\n                return 0 if @n <= ddof\n                switch mode\n                    when \"var\"   then @s/(@n-ddof)\n                    when \"stdev\" then Math.sqrt(@s/(@n-ddof))\n            format: formatter\n            numInputs: if attr? then 0 else 1\n\n        sumOverSum: (formatter=usFmt) -> ([num, denom]) -> (data, rowKey, colKey) ->\n            sumNum: 0\n            sumDenom: 0\n            push: (record) ->\n                @sumNum   += parseFloat(record[num])   if not isNaN parseFloat(record[num])\n                @sumDenom += parseFloat(record[denom]) if not isNaN parseFloat(record[denom])\n            value: -> @sumNum/@sumDenom\n            format: formatter\n            numInputs: if num? and denom? then 0 else 2\n\n        sumOverSumBound80: (upper=true, formatter=usFmt) -> ([num, denom]) -> (data, rowKey, colKey) ->\n            sumNum: 0\n            sumDenom: 0\n            push: (record) ->\n                @sumNum   += parseFloat(record[num])   if not isNaN parseFloat(record[num])\n                @sumDenom += parseFloat(record[denom]) if not isNaN parseFloat(record[denom])\n            value: ->\n                sign = if upper then 1 else -1\n                (0.821187207574908/@sumDenom + @sumNum/@sumDenom + 1.2815515655446004*sign*\n                    Math.sqrt(0.410593603787454/ (@sumDenom*@sumDenom) + (@sumNum*(1 - @sumNum/ @sumDenom))/ (@sumDenom*@sumDenom)))/\n                    (1 + 1.642374415149816/@sumDenom)\n            format: formatter\n            numInputs: if num? and denom? then 0 else 2\n\n        fractionOf: (wrapped, type=\"total\", formatter=usFmtPct) -> (x...) -> (data, rowKey, colKey) ->\n            selector: {total:[[],[]],row:[rowKey,[]],col:[[],colKey]}[type]\n            inner: wrapped(x...)(data, rowKey, colKey)\n            push: (record) -> @inner.push record\n            format: formatter\n            value: -> @inner.value() / data.getAggregator(@selector...).inner.value()\n            numInputs: wrapped(x...)().numInputs\n\n    aggregatorTemplates.countUnique = (f) -> aggregatorTemplates.uniques(((x) -> x.length), f)\n    aggregatorTemplates.listUnique =  (s) -> aggregatorTemplates.uniques(((x) -> x.sort(naturalSort).join(s)), ((x)->x))\n    aggregatorTemplates.max =         (f) -> aggregatorTemplates.extremes('max', f)\n    aggregatorTemplates.min =         (f) -> aggregatorTemplates.extremes('min', f)\n    aggregatorTemplates.first =       (f) -> aggregatorTemplates.extremes('first', f)\n    aggregatorTemplates.last =        (f) -> aggregatorTemplates.extremes('last', f)\n    aggregatorTemplates.median =      (f) -> aggregatorTemplates.quantile(0.5, f)\n    aggregatorTemplates.average =     (f) -> aggregatorTemplates.runningStat(\"mean\", 1, f)\n    aggregatorTemplates.var =         (ddof, f) -> aggregatorTemplates.runningStat(\"var\", ddof, f)\n    aggregatorTemplates.stdev =       (ddof, f) -> aggregatorTemplates.runningStat(\"stdev\", ddof, f)\n\n    #default aggregators & renderers use US naming and number formatting\n    aggregators = do (tpl = aggregatorTemplates) ->\n        \"Count\":                tpl.count(usFmtInt)\n        \"Count Unique Values\":  tpl.countUnique(usFmtInt)\n        \"List Unique Values\":   tpl.listUnique(\", \")\n        \"Sum\":                  tpl.sum(usFmt)\n        \"Integer Sum\":          tpl.sum(usFmtInt)\n        \"Average\":              tpl.average(usFmt)\n        \"Median\":               tpl.median(usFmt)\n        \"Sample Variance\":      tpl.var(1, usFmt)\n        \"Sample Standard Deviation\": tpl.stdev(1, usFmt)\n        \"Minimum\":              tpl.min(usFmt)\n        \"Maximum\":              tpl.max(usFmt)\n        \"First\":                tpl.first(usFmt)\n        \"Last\":                 tpl.last(usFmt)\n        \"Sum over Sum\":         tpl.sumOverSum(usFmt)\n        \"80% Upper Bound\":      tpl.sumOverSumBound80(true, usFmt)\n        \"80% Lower Bound\":      tpl.sumOverSumBound80(false, usFmt)\n        \"Sum as Fraction of Total\":     tpl.fractionOf(tpl.sum(),   \"total\", usFmtPct)\n        \"Sum as Fraction of Rows\":      tpl.fractionOf(tpl.sum(),   \"row\",   usFmtPct)\n        \"Sum as Fraction of Columns\":   tpl.fractionOf(tpl.sum(),   \"col\",   usFmtPct)\n        \"Count as Fraction of Total\":   tpl.fractionOf(tpl.count(), \"total\", usFmtPct)\n        \"Count as Fraction of Rows\":    tpl.fractionOf(tpl.count(), \"row\",   usFmtPct)\n        \"Count as Fraction of Columns\": tpl.fractionOf(tpl.count(), \"col\",   usFmtPct)\n\n    renderers =\n        \"Table\":          (data, opts) ->   pivotTableRenderer(data, opts)\n        \"Table Barchart\": (data, opts) -> $(pivotTableRenderer(data, opts)).barchart()\n        \"Heatmap\":        (data, opts) -> $(pivotTableRenderer(data, opts)).heatmap(\"heatmap\",    opts)\n        \"Row Heatmap\":    (data, opts) -> $(pivotTableRenderer(data, opts)).heatmap(\"rowheatmap\", opts)\n        \"Col Heatmap\":    (data, opts) -> $(pivotTableRenderer(data, opts)).heatmap(\"colheatmap\", opts)\n\n    locales =\n        en:\n            aggregators: aggregators\n            renderers: renderers\n            localeStrings:\n                renderError: \"An error occurred rendering the PivotTable results.\"\n                computeError: \"An error occurred computing the PivotTable results.\"\n                uiRenderError: \"An error occurred rendering the PivotTable UI.\"\n                selectAll: \"Select All\"\n                selectNone: \"Select None\"\n                tooMany: \"(too many to list)\"\n                filterResults: \"Filter values\"\n                apply: \"Apply\"\n                cancel: \"Cancel\"\n                totals: \"Totals\" #for table renderer\n                vs: \"vs\" #for gchart renderer\n                by: \"by\" #for gchart renderer\n\n    #dateFormat deriver l10n requires month and day names to be passed in directly\n    mthNamesEn = [\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"]\n    dayNamesEn = [\"Sun\",\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\"]\n    zeroPad = (number) -> (\"0\"+number).substr(-2,2)\n\n    derivers =\n        bin: (col, binWidth) -> (record) -> record[col] - record[col] % binWidth\n        dateFormat: (col, formatString, utcOutput=false, mthNames=mthNamesEn, dayNames=dayNamesEn) ->\n            utc = if utcOutput then \"UTC\" else \"\"\n            (record) -> #thanks http://stackoverflow.com/a/12213072/112871\n                date = new Date(Date.parse(record[col]))\n                if isNaN(date) then return \"\"\n                formatString.replace /%(.)/g, (m, p) ->\n                    switch p\n                        when \"y\" then date[\"get#{utc}FullYear\"]()\n                        when \"m\" then zeroPad(date[\"get#{utc}Month\"]()+1)\n                        when \"n\" then mthNames[date[\"get#{utc}Month\"]()]\n                        when \"d\" then zeroPad(date[\"get#{utc}Date\"]())\n                        when \"w\" then dayNames[date[\"get#{utc}Day\"]()]\n                        when \"x\" then date[\"get#{utc}Day\"]()\n                        when \"H\" then zeroPad(date[\"get#{utc}Hours\"]())\n                        when \"M\" then zeroPad(date[\"get#{utc}Minutes\"]())\n                        when \"S\" then zeroPad(date[\"get#{utc}Seconds\"]())\n                        else \"%\" + p\n\n    rx = /(\\d+)|(\\D+)/g\n    rd = /\\d/\n    rz = /^0/\n    naturalSort = (as, bs) =>\n        #nulls first\n        return -1 if bs? and not as?\n        return  1 if as? and not bs?\n\n        #then raw NaNs\n        return -1 if typeof as == \"number\" and isNaN(as)\n        return  1 if typeof bs == \"number\" and isNaN(bs)\n\n        #numbers and numbery strings group together\n        nas = +as\n        nbs = +bs\n        return -1 if nas < nbs\n        return  1 if nas > nbs\n\n        #within that, true numbers before numbery strings\n        return -1 if typeof as == \"number\" and typeof bs != \"number\"\n        return  1 if typeof bs == \"number\" and typeof as != \"number\"\n        return  0 if typeof as == \"number\" and typeof bs == \"number\"\n\n        # 'Infinity' is a textual number, so less than 'A'\n        return -1 if isNaN(nbs) and not isNaN(nas)\n        return  1 if isNaN(nas) and not isNaN(nbs)\n\n        #finally, \"smart\" string sorting per http://stackoverflow.com/a/4373421/112871\n        a = String(as)\n        b = String(bs)\n        return 0 if a == b\n        return (if a > b then 1 else -1) unless rd.test(a) and rd.test(b)\n\n        #special treatment for strings containing digits\n        a = a.match(rx) #create digits vs non-digit chunks and iterate through\n        b = b.match(rx)\n        while a.length and b.length\n            a1 = a.shift()\n            b1 = b.shift()\n            if a1 != b1\n                if rd.test(a1) and rd.test(b1) #both are digit chunks\n                    numDiff = a1.replace(rz, \".0\") - b1.replace(rz, \".0\")\n                    return if numDiff != 0 then numDiff else a1.length - b1.length\n                else\n                    return (if a1 > b1 then 1 else -1)\n        return a.length - b.length\n\n    sortAs = (order) ->\n        mapping = {}\n        l_mapping = {} # sort lowercased keys similarly\n        for i, x of order\n            mapping[x] = i\n            l_mapping[x.toLowerCase()] = i if typeof x == \"string\"\n        (a, b) ->\n            if mapping[a]? and mapping[b]? then mapping[a] - mapping[b]\n            else if mapping[a]? then -1\n            else if mapping[b]? then 1\n            else if l_mapping[a]? and l_mapping[b]? then l_mapping[a] - l_mapping[b]\n            else if l_mapping[a]? then -1\n            else if l_mapping[b]? then 1\n            else naturalSort(a,b)\n\n    getSort = (sorters, attr) ->\n        if sorters?\n            if $.isFunction(sorters)\n                sort = sorters(attr)\n                return sort if $.isFunction(sort)\n            else if sorters[attr]?\n                return sorters[attr]\n        return naturalSort\n\n    ###\n    Data Model class\n    ###\n\n    class PivotData\n        constructor: (input, opts = {}) ->\n            @input = input\n            @aggregator = opts.aggregator ? aggregatorTemplates.count()()\n            @aggregatorName = opts.aggregatorName ? \"Count\"\n            @colAttrs = opts.cols ? []\n            @rowAttrs = opts.rows ? []\n            @valAttrs = opts.vals ? []\n            @sorters = opts.sorters ? {}\n            @rowOrder = opts.rowOrder ? \"key_a_to_z\"\n            @colOrder = opts.colOrder ? \"key_a_to_z\"\n            @derivedAttributes = opts.derivedAttributes ? {}\n            @filter = opts.filter ? (-> true)\n            @tree = {}\n            @rowKeys = []\n            @colKeys = []\n            @rowTotals = {}\n            @colTotals = {}\n            @allTotal = @aggregator(this, [], [])\n            @sorted = false\n\n            # iterate through input, accumulating data for cells\n            PivotData.forEachRecord @input, @derivedAttributes, (record) =>\n                @processRecord(record) if @filter(record)\n\n        #can handle arrays or jQuery selections of tables\n        @forEachRecord = (input, derivedAttributes, f) ->\n            if $.isEmptyObject derivedAttributes\n                addRecord = f\n            else\n                addRecord = (record) ->\n                    record[k] = v(record) ? record[k] for k, v of derivedAttributes\n                    f(record)\n\n            #if it's a function, have it call us back\n            if $.isFunction(input)\n                input(addRecord)\n            else if $.isArray(input)\n                if $.isArray(input[0]) #array of arrays\n                    for own i, compactRecord of input when i > 0\n                        record = {}\n                        record[k] = compactRecord[j] for own j, k of input[0]\n                        addRecord(record)\n                else #array of objects\n                    addRecord(record) for record in input\n            else if input instanceof $\n                tblCols = []\n                $(\"thead > tr > th\", input).each (i) -> tblCols.push $(this).text()\n                $(\"tbody > tr\", input).each (i) ->\n                    record = {}\n                    $(\"td\", this).each (j) -> record[tblCols[j]] = $(this).text()\n                    addRecord(record)\n            else\n                throw new Error(\"unknown input format\")\n\n        forEachMatchingRecord: (criteria, callback) ->\n            PivotData.forEachRecord @input, @derivedAttributes, (record) =>\n                return if not @filter(record)\n                for k, v of criteria\n                    return if v != (record[k] ? \"null\")\n                callback(record)\n\n        arrSort: (attrs) =>\n            sortersArr = (getSort(@sorters, a) for a in attrs)\n            (a,b) ->\n                for own i, sorter of sortersArr\n                    comparison = sorter(a[i], b[i])\n                    return comparison if comparison != 0\n                return 0\n\n        sortKeys: () =>\n            if not @sorted\n                @sorted = true\n                v = (r,c) => @getAggregator(r,c).value()\n                switch @rowOrder\n                    when \"value_a_to_z\"  then @rowKeys.sort (a,b) =>  naturalSort v(a,[]), v(b,[])\n                    when \"value_z_to_a\" then @rowKeys.sort (a,b) => -naturalSort v(a,[]), v(b,[])\n                    else             @rowKeys.sort @arrSort(@rowAttrs)\n                switch @colOrder\n                    when \"value_a_to_z\"  then @colKeys.sort (a,b) =>  naturalSort v([],a), v([],b)\n                    when \"value_z_to_a\" then @colKeys.sort (a,b) => -naturalSort v([],a), v([],b)\n                    else             @colKeys.sort @arrSort(@colAttrs)\n\n        getColKeys: () =>\n            @sortKeys()\n            return @colKeys\n\n        getRowKeys: () =>\n            @sortKeys()\n            return @rowKeys\n\n        processRecord: (record) -> #this code is called in a tight loop\n            colKey = []\n            rowKey = []\n            colKey.push record[x] ? \"null\" for x in @colAttrs\n            rowKey.push record[x] ? \"null\" for x in @rowAttrs\n            flatRowKey = rowKey.join(String.fromCharCode(0))\n            flatColKey = colKey.join(String.fromCharCode(0))\n\n            @allTotal.push record\n\n            if rowKey.length != 0\n                if not @rowTotals[flatRowKey]\n                    @rowKeys.push rowKey\n                    @rowTotals[flatRowKey] = @aggregator(this, rowKey, [])\n                @rowTotals[flatRowKey].push record\n\n            if colKey.length != 0\n                if not @colTotals[flatColKey]\n                    @colKeys.push colKey\n                    @colTotals[flatColKey] = @aggregator(this, [], colKey)\n                @colTotals[flatColKey].push record\n\n            if colKey.length != 0 and rowKey.length != 0\n                if not @tree[flatRowKey]\n                    @tree[flatRowKey] = {}\n                if not @tree[flatRowKey][flatColKey]\n                    @tree[flatRowKey][flatColKey] = @aggregator(this, rowKey, colKey)\n                @tree[flatRowKey][flatColKey].push record\n\n        getAggregator: (rowKey, colKey) =>\n            flatRowKey = rowKey.join(String.fromCharCode(0))\n            flatColKey = colKey.join(String.fromCharCode(0))\n            if rowKey.length == 0 and colKey.length == 0\n                agg = @allTotal\n            else if rowKey.length == 0\n                agg = @colTotals[flatColKey]\n            else if colKey.length == 0\n                agg = @rowTotals[flatRowKey]\n            else\n                agg = @tree[flatRowKey][flatColKey]\n            return agg ? {value: (-> null), format: -> \"\"}\n\n    #expose these to the outside world\n    $.pivotUtilities = {aggregatorTemplates, aggregators, renderers, derivers, locales,\n        naturalSort, numberFormat, sortAs, PivotData}\n\n    ###\n    Default Renderer for hierarchical table layout\n    ###\n\n    pivotTableRenderer = (pivotData, opts) ->\n\n        defaults =\n            table:\n                clickCallback: null\n                rowTotals: true\n                colTotals: true\n            localeStrings: totals: \"Totals\"\n\n        opts = $.extend(true, {}, defaults, opts)\n\n        colAttrs = pivotData.colAttrs\n        rowAttrs = pivotData.rowAttrs\n        rowKeys = pivotData.getRowKeys()\n        colKeys = pivotData.getColKeys()\n\n        if opts.table.clickCallback\n            getClickHandler = (value, rowValues, colValues) ->\n                filters = {}\n                filters[attr] = colValues[i] for own i, attr of colAttrs when colValues[i]?\n                filters[attr] = rowValues[i] for own i, attr of rowAttrs when rowValues[i]?\n                return (e) -> opts.table.clickCallback(e, value, filters, pivotData)\n\n        #now actually build the output\n        result = document.createElement(\"table\")\n        result.className = \"pvtTable\"\n\n        #helper function for setting row/col-span in pivotTableRenderer\n        spanSize = (arr, i, j) ->\n            if i != 0\n                noDraw = true\n                for x in [0..j]\n                    if arr[i-1][x] != arr[i][x]\n                        noDraw = false\n                if noDraw\n                  return -1 #do not draw cell\n            len = 0\n            while i+len < arr.length\n                stop = false\n                for x in [0..j]\n                    stop = true if arr[i][x] != arr[i+len][x]\n                break if stop\n                len++\n            return len\n\n        #the first few rows are for col headers\n        thead = document.createElement(\"thead\")\n        for own j, c of colAttrs\n            tr = document.createElement(\"tr\")\n            if parseInt(j) == 0 and rowAttrs.length != 0\n                th = document.createElement(\"th\")\n                th.setAttribute(\"colspan\", rowAttrs.length)\n                th.setAttribute(\"rowspan\", colAttrs.length)\n                tr.appendChild th\n            th = document.createElement(\"th\")\n            th.className = \"pvtAxisLabel\"\n            th.textContent = c\n            tr.appendChild th\n            for own i, colKey of colKeys\n                x = spanSize(colKeys, parseInt(i), parseInt(j))\n                if x != -1\n                    th = document.createElement(\"th\")\n                    th.className = \"pvtColLabel\"\n                    th.textContent = colKey[j]\n                    th.setAttribute(\"colspan\", x)\n                    if parseInt(j) == colAttrs.length-1 and rowAttrs.length != 0\n                        th.setAttribute(\"rowspan\", 2)\n                    tr.appendChild th\n            if parseInt(j) == 0 && opts.table.rowTotals\n                th = document.createElement(\"th\")\n                th.className = \"pvtTotalLabel pvtRowTotalLabel\"\n                th.innerHTML = opts.localeStrings.totals\n                th.setAttribute(\"rowspan\", colAttrs.length + (if rowAttrs.length ==0 then 0 else 1))\n                tr.appendChild th\n            thead.appendChild tr\n\n        #then a row for row header headers\n        if rowAttrs.length !=0\n            tr = document.createElement(\"tr\")\n            for own i, r of rowAttrs\n                th = document.createElement(\"th\")\n                th.className = \"pvtAxisLabel\"\n                th.textContent = r\n                tr.appendChild th\n            th = document.createElement(\"th\")\n            if colAttrs.length ==0\n                th.className = \"pvtTotalLabel pvtRowTotalLabel\"\n                th.innerHTML = opts.localeStrings.totals\n            tr.appendChild th\n            thead.appendChild tr\n        result.appendChild thead\n\n        #now the actual data rows, with their row headers and totals\n        tbody = document.createElement(\"tbody\")\n        for own i, rowKey of rowKeys\n            tr = document.createElement(\"tr\")\n            for own j, txt of rowKey\n                x = spanSize(rowKeys, parseInt(i), parseInt(j))\n                if x != -1\n                    th = document.createElement(\"th\")\n                    th.className = \"pvtRowLabel\"\n                    th.textContent = txt\n                    th.setAttribute(\"rowspan\", x)\n                    if parseInt(j) == rowAttrs.length-1 and colAttrs.length !=0\n                        th.setAttribute(\"colspan\",2)\n                    tr.appendChild th\n            for own j, colKey of colKeys #this is the tight loop\n                aggregator = pivotData.getAggregator(rowKey, colKey)\n                val = aggregator.value()\n                td = document.createElement(\"td\")\n                td.className = \"pvtVal row#{i} col#{j}\"\n                td.textContent = aggregator.format(val)\n                td.setAttribute(\"data-value\", val)\n                if getClickHandler?\n                    td.onclick = getClickHandler(val, rowKey, colKey)\n                tr.appendChild td\n\n            if opts.table.rowTotals || colAttrs.length == 0\n                totalAggregator = pivotData.getAggregator(rowKey, [])\n                val = totalAggregator.value()\n                td = document.createElement(\"td\")\n                td.className = \"pvtTotal rowTotal\"\n                td.textContent = totalAggregator.format(val)\n                td.setAttribute(\"data-value\", val)\n                if getClickHandler?\n                    td.onclick = getClickHandler(val, rowKey, [])\n                td.setAttribute(\"data-for\", \"row\"+i)\n                tr.appendChild td\n            tbody.appendChild tr\n\n        #finally, the row for col totals, and a grand total\n        if opts.table.colTotals || rowAttrs.length == 0\n            tr = document.createElement(\"tr\")\n            if opts.table.colTotals || rowAttrs.length == 0\n                th = document.createElement(\"th\")\n                th.className = \"pvtTotalLabel pvtColTotalLabel\"\n                th.innerHTML = opts.localeStrings.totals\n                th.setAttribute(\"colspan\", rowAttrs.length + (if colAttrs.length == 0 then 0 else 1))\n                tr.appendChild th\n            for own j, colKey of colKeys\n                totalAggregator = pivotData.getAggregator([], colKey)\n                val = totalAggregator.value()\n                td = document.createElement(\"td\")\n                td.className = \"pvtTotal colTotal\"\n                td.textContent = totalAggregator.format(val)\n                td.setAttribute(\"data-value\", val)\n                if getClickHandler?\n                    td.onclick = getClickHandler(val, [], colKey)\n                td.setAttribute(\"data-for\", \"col\"+j)\n                tr.appendChild td\n            if opts.table.rowTotals || colAttrs.length == 0\n                totalAggregator = pivotData.getAggregator([], [])\n                val = totalAggregator.value()\n                td = document.createElement(\"td\")\n                td.className = \"pvtGrandTotal\"\n                td.textContent = totalAggregator.format(val)\n                td.setAttribute(\"data-value\", val)\n                if getClickHandler?\n                    td.onclick = getClickHandler(val, [], [])\n                tr.appendChild td\n            tbody.appendChild tr\n        result.appendChild tbody\n\n        #squirrel this away for later\n        result.setAttribute(\"data-numrows\", rowKeys.length)\n        result.setAttribute(\"data-numcols\", colKeys.length)\n\n        return result\n\n    ###\n    Pivot Table core: create PivotData object and call Renderer on it\n    ###\n\n    $.fn.pivot = (input, inputOpts, locale=\"en\") ->\n        locale = \"en\" if not locales[locale]?\n        defaults =\n            cols : [], rows: [], vals: []\n            rowOrder: \"key_a_to_z\", colOrder: \"key_a_to_z\"\n            dataClass: PivotData\n            filter: -> true\n            aggregator: aggregatorTemplates.count()()\n            aggregatorName: \"Count\"\n            sorters: {}\n            derivedAttributes: {}\n            renderer: pivotTableRenderer\n\n        localeStrings = $.extend(true, {}, locales.en.localeStrings, locales[locale].localeStrings)\n        localeDefaults =\n            rendererOptions: {localeStrings}\n            localeStrings: localeStrings\n\n        opts = $.extend(true, {}, localeDefaults, $.extend({}, defaults, inputOpts))\n\n        result = null\n        try\n            pivotData = new opts.dataClass(input, opts)\n            try\n                result = opts.renderer(pivotData, opts.rendererOptions)\n            catch e\n                console.error(e.stack) if console?\n                result = $(\"<span>\").html opts.localeStrings.renderError\n        catch e\n            console.error(e.stack) if console?\n            result = $(\"<span>\").html opts.localeStrings.computeError\n\n        x = this[0]\n        x.removeChild(x.lastChild) while x.hasChildNodes()\n        return @append result\n\n\n    ###\n    Pivot Table UI: calls Pivot Table core above with options set by user\n    ###\n\n    $.fn.pivotUI = (input, inputOpts, overwrite = false, locale=\"en\") ->\n        locale = \"en\" if not locales[locale]?\n        defaults =\n            derivedAttributes: {}\n            aggregators: locales[locale].aggregators\n            renderers: locales[locale].renderers\n            hiddenAttributes: []\n            hiddenFromAggregators: []\n            hiddenFromDragDrop: []\n            menuLimit: 500\n            cols: [], rows: [], vals: []\n            rowOrder: \"key_a_to_z\", colOrder: \"key_a_to_z\"\n            dataClass: PivotData\n            exclusions: {}\n            inclusions: {}\n            unusedAttrsVertical: 85\n            autoSortUnusedAttrs: false\n            onRefresh: null\n            showUI: true\n            filter: -> true\n            sorters: {}\n\n        localeStrings = $.extend(true, {}, locales.en.localeStrings, locales[locale].localeStrings)\n        localeDefaults =\n            rendererOptions: {localeStrings}\n            localeStrings: localeStrings\n\n        existingOpts = @data \"pivotUIOptions\"\n        if not existingOpts? or overwrite\n            opts = $.extend(true, {}, localeDefaults, $.extend({}, defaults, inputOpts))\n        else\n            opts = existingOpts\n\n        try\n            # do a first pass on the data to cache a materialized copy of any\n            # function-valued inputs and to compute dimension cardinalities\n            attrValues = {}\n            materializedInput = []\n            recordsProcessed = 0\n            PivotData.forEachRecord input, opts.derivedAttributes, (record) ->\n                return unless opts.filter(record)\n                materializedInput.push(record)\n                for own attr of record\n                    if not attrValues[attr]?\n                        attrValues[attr] = {}\n                        if recordsProcessed > 0\n                            attrValues[attr][\"null\"] = recordsProcessed\n                for attr of attrValues\n                    value = record[attr] ? \"null\"\n                    attrValues[attr][value] ?= 0\n                    attrValues[attr][value]++\n                recordsProcessed++\n\n            #start building the output\n            uiTable = $(\"<table>\", \"class\": \"pvtUi\").attr(\"cellpadding\", 5)\n\n            #renderer control\n            rendererControl = $(\"<td>\").addClass(\"pvtUiCell\")\n\n            renderer = $(\"<select>\")\n                .addClass('pvtRenderer')\n                .appendTo(rendererControl)\n                .bind \"change\", -> refresh() #capture reference\n            for own x of opts.renderers\n                $(\"<option>\").val(x).html(x).appendTo(renderer)\n\n\n            #axis list, including the double-click menu\n            unused = $(\"<td>\").addClass('pvtAxisContainer pvtUnused pvtUiCell')\n            shownAttributes = (a for a of attrValues when a not in opts.hiddenAttributes)\n            shownInAggregators = (c for c in shownAttributes when c not in opts.hiddenFromAggregators)\n            shownInDragDrop = (c for c in shownAttributes when c not in opts.hiddenFromDragDrop)\n\n\n            unusedAttrsVerticalAutoOverride = false\n            if opts.unusedAttrsVertical == \"auto\"\n                unusedAttrsVerticalAutoCutoff = 120 # legacy support\n            else\n                unusedAttrsVerticalAutoCutoff = parseInt opts.unusedAttrsVertical\n\n            if not isNaN(unusedAttrsVerticalAutoCutoff)\n                attrLength = 0\n                attrLength += a.length for a in shownInDragDrop\n                unusedAttrsVerticalAutoOverride = attrLength > unusedAttrsVerticalAutoCutoff\n\n            if opts.unusedAttrsVertical == true or unusedAttrsVerticalAutoOverride\n                unused.addClass('pvtVertList')\n            else\n                unused.addClass('pvtHorizList')\n\n            for own i, attr of shownInDragDrop\n                do (attr) ->\n                    values = (v for v of attrValues[attr])\n                    hasExcludedItem = false\n                    valueList = $(\"<div>\").addClass('pvtFilterBox').hide()\n\n                    valueList.append $(\"<h4>\").append(\n                        $(\"<span>\").text(attr),\n                        $(\"<span>\").addClass(\"count\").text(\"(#{values.length})\"),\n                        )\n                    if values.length > opts.menuLimit\n                        valueList.append $(\"<p>\").html(opts.localeStrings.tooMany)\n                    else\n                        if values.length > 5\n                            controls = $(\"<p>\").appendTo(valueList)\n                            sorter = getSort(opts.sorters, attr)\n                            placeholder = opts.localeStrings.filterResults\n                            $(\"<input>\", {type: \"text\"}).appendTo(controls)\n                                .attr({placeholder: placeholder, class: \"pvtSearch\"})\n                                .bind \"keyup\", ->\n                                    filter = $(this).val().toLowerCase().trim()\n                                    accept_gen = (prefix, accepted) -> (v) ->\n                                        real_filter = filter.substring(prefix.length).trim()\n                                        return true if real_filter.length == 0\n                                        return Math.sign(sorter(v.toLowerCase(), real_filter)) in accepted\n                                    accept =\n                                        if      filter.indexOf(\">=\") == 0 then accept_gen(\">=\", [1,0])\n                                        else if filter.indexOf(\"<=\") == 0 then accept_gen(\"<=\", [-1,0])\n                                        else if filter.indexOf(\">\") == 0  then accept_gen(\">\",  [1])\n                                        else if filter.indexOf(\"<\") == 0  then accept_gen(\"<\",  [-1])\n                                        else if filter.indexOf(\"~\") == 0  then (v) ->\n                                                return true if filter.substring(1).trim().length == 0\n                                                v.toLowerCase().match(filter.substring(1))\n                                        else (v) -> v.toLowerCase().indexOf(filter) != -1\n\n                                    valueList.find('.pvtCheckContainer p label span.value').each ->\n                                        if accept($(this).text())\n                                            $(this).parent().parent().show()\n                                        else\n                                            $(this).parent().parent().hide()\n                            controls.append $(\"<br>\")\n                            $(\"<button>\", {type:\"button\"}).appendTo(controls)\n                                .html(opts.localeStrings.selectAll)\n                                .bind \"click\", ->\n                                    valueList.find(\"input:visible:not(:checked)\")\n                                        .prop(\"checked\", true).toggleClass(\"changed\")\n                                    return false\n                            $(\"<button>\", {type:\"button\"}).appendTo(controls)\n                                .html(opts.localeStrings.selectNone)\n                                .bind \"click\", ->\n                                    valueList.find(\"input:visible:checked\")\n                                        .prop(\"checked\", false).toggleClass(\"changed\")\n                                    return false\n\n                        checkContainer = $(\"<div>\").addClass(\"pvtCheckContainer\").appendTo(valueList)\n\n                        for value in values.sort(getSort(opts.sorters, attr))\n                             valueCount = attrValues[attr][value]\n                             filterItem = $(\"<label>\")\n                             filterItemExcluded = false\n                             if opts.inclusions[attr]\n                                filterItemExcluded = (value not in opts.inclusions[attr])\n                             else if opts.exclusions[attr]\n                                filterItemExcluded = (value in opts.exclusions[attr])\n                             hasExcludedItem ||= filterItemExcluded\n                             $(\"<input>\")\n                                .attr(\"type\", \"checkbox\").addClass('pvtFilter')\n                                .attr(\"checked\", !filterItemExcluded).data(\"filter\", [attr,value])\n                                .appendTo(filterItem)\n                                .bind \"change\", -> $(this).toggleClass(\"changed\")\n                             filterItem.append $(\"<span>\").addClass(\"value\").text(value)\n                             filterItem.append $(\"<span>\").addClass(\"count\").text(\"(\"+valueCount+\")\")\n                             checkContainer.append $(\"<p>\").append(filterItem)\n\n                    closeFilterBox = ->\n                        if valueList.find(\"[type='checkbox']\").length >\n                               valueList.find(\"[type='checkbox']:checked\").length\n                                attrElem.addClass \"pvtFilteredAttribute\"\n                            else\n                                attrElem.removeClass \"pvtFilteredAttribute\"\n\n                            valueList.find('.pvtSearch').val('')\n                            valueList.find('.pvtCheckContainer p').show()\n                            valueList.hide()\n\n                    finalButtons = $(\"<p>\").appendTo(valueList)\n\n                    if values.length <= opts.menuLimit\n                        $(\"<button>\", {type: \"button\"}).text(opts.localeStrings.apply)\n                            .appendTo(finalButtons).bind \"click\", ->\n                                if valueList.find(\".changed\").removeClass(\"changed\").length\n                                    refresh()\n                                closeFilterBox()\n\n                    $(\"<button>\", {type: \"button\"}).text(opts.localeStrings.cancel)\n                        .appendTo(finalButtons).bind \"click\", ->\n                            valueList.find(\".changed:checked\")\n                                .removeClass(\"changed\").prop(\"checked\", false)\n                            valueList.find(\".changed:not(:checked)\")\n                                .removeClass(\"changed\").prop(\"checked\", true)\n                            closeFilterBox()\n\n                    triangleLink = $(\"<span>\").addClass('pvtTriangle')\n                        .html(\" &#x25BE;\").bind \"click\", (e) ->\n                            {left, top} = $(e.currentTarget).position()\n                            valueList.css(left: left+10, top: top+10).show()\n\n                    attrElem = $(\"<li>\").addClass(\"axis_#{i}\")\n                        .append $(\"<span>\").addClass('pvtAttr').text(attr).data(\"attrName\", attr).append(triangleLink)\n\n                    attrElem.addClass('pvtFilteredAttribute') if hasExcludedItem\n                    unused.append(attrElem).append(valueList)\n\n            tr1 = $(\"<tr>\").appendTo(uiTable)\n\n            #aggregator menu and value area\n\n            aggregator = $(\"<select>\").addClass('pvtAggregator')\n                .bind \"change\", -> refresh() #capture reference\n            for own x of opts.aggregators\n                aggregator.append $(\"<option>\").val(x).html(x)\n\n            ordering =\n                key_a_to_z:   {rowSymbol: \"&varr;\", colSymbol: \"&harr;\", next: \"value_a_to_z\"}\n                value_a_to_z: {rowSymbol: \"&darr;\", colSymbol: \"&rarr;\", next: \"value_z_to_a\"}\n                value_z_to_a: {rowSymbol: \"&uarr;\", colSymbol: \"&larr;\", next: \"key_a_to_z\"}\n\n            rowOrderArrow = $(\"<a>\", role: \"button\").addClass(\"pvtRowOrder\")\n                .data(\"order\", opts.rowOrder).html(ordering[opts.rowOrder].rowSymbol)\n                .bind \"click\", ->\n                    $(this).data(\"order\", ordering[$(this).data(\"order\")].next)\n                    $(this).html(ordering[$(this).data(\"order\")].rowSymbol)\n                    refresh()\n\n            colOrderArrow = $(\"<a>\", role: \"button\").addClass(\"pvtColOrder\")\n                .data(\"order\", opts.colOrder).html(ordering[opts.colOrder].colSymbol)\n                .bind \"click\", ->\n                    $(this).data(\"order\", ordering[$(this).data(\"order\")].next)\n                    $(this).html(ordering[$(this).data(\"order\")].colSymbol)\n                    refresh()\n\n            $(\"<td>\").addClass('pvtVals pvtUiCell')\n              .appendTo(tr1)\n              .append(aggregator)\n              .append(rowOrderArrow)\n              .append(colOrderArrow)\n              .append($(\"<br>\"))\n\n            #column axes\n            $(\"<td>\").addClass('pvtAxisContainer pvtHorizList pvtCols pvtUiCell').appendTo(tr1)\n\n            tr2 = $(\"<tr>\").appendTo(uiTable)\n\n            #row axes\n            tr2.append $(\"<td>\").addClass('pvtAxisContainer pvtRows pvtUiCell').attr(\"valign\", \"top\")\n\n            #the actual pivot table container\n            pivotTable = $(\"<td>\")\n                .attr(\"valign\", \"top\")\n                .addClass('pvtRendererArea')\n                .appendTo(tr2)\n\n            #finally the renderer dropdown and unused attribs are inserted at the requested location\n            if opts.unusedAttrsVertical == true or unusedAttrsVerticalAutoOverride\n                uiTable.find('tr:nth-child(1)').prepend rendererControl\n                uiTable.find('tr:nth-child(2)').prepend unused\n            else\n                uiTable.prepend $(\"<tr>\").append(rendererControl).append(unused)\n\n            #render the UI in its default state\n            @html uiTable\n\n            #set up the UI initial state as requested by moving elements around\n\n            for x in opts.cols\n                @find(\".pvtCols\").append @find(\".axis_#{$.inArray(x, shownInDragDrop)}\")\n            for x in opts.rows\n                @find(\".pvtRows\").append @find(\".axis_#{$.inArray(x, shownInDragDrop)}\")\n            if opts.aggregatorName?\n                @find(\".pvtAggregator\").val opts.aggregatorName\n            if opts.rendererName?\n                @find(\".pvtRenderer\").val opts.rendererName\n\n            @find(\".pvtUiCell\").hide() unless opts.showUI\n\n            initialRender = true\n\n            #set up for refreshing\n            refreshDelayed = =>\n                subopts =\n                    derivedAttributes: opts.derivedAttributes\n                    localeStrings: opts.localeStrings\n                    rendererOptions: opts.rendererOptions\n                    sorters: opts.sorters\n                    cols: [], rows: []\n                    dataClass: opts.dataClass\n\n                numInputsToProcess = opts.aggregators[aggregator.val()]([])().numInputs ? 0\n                vals = []\n                @find(\".pvtRows li span.pvtAttr\").each -> subopts.rows.push $(this).data(\"attrName\")\n                @find(\".pvtCols li span.pvtAttr\").each -> subopts.cols.push $(this).data(\"attrName\")\n                @find(\".pvtVals select.pvtAttrDropdown\").each ->\n                    if numInputsToProcess == 0\n                        $(this).remove()\n                    else\n                        numInputsToProcess--\n                        vals.push $(this).val() if $(this).val() != \"\"\n\n                if numInputsToProcess != 0\n                    pvtVals = @find(\".pvtVals\")\n                    for x in [0...numInputsToProcess]\n                        newDropdown = $(\"<select>\")\n                            .addClass('pvtAttrDropdown')\n                            .append($(\"<option>\"))\n                            .bind \"change\", -> refresh()\n                        for attr in shownInAggregators\n                            newDropdown.append($(\"<option>\").val(attr).text(attr))\n                        pvtVals.append(newDropdown)\n\n                if initialRender\n                    vals = opts.vals\n                    i = 0\n                    @find(\".pvtVals select.pvtAttrDropdown\").each ->\n                        $(this).val vals[i]\n                        i++\n                    initialRender = false\n\n                subopts.aggregatorName = aggregator.val()\n                subopts.vals = vals\n                subopts.aggregator = opts.aggregators[aggregator.val()](vals)\n                subopts.renderer = opts.renderers[renderer.val()]\n                subopts.rowOrder = rowOrderArrow.data(\"order\")\n                subopts.colOrder = colOrderArrow.data(\"order\")\n                #construct filter here\n                exclusions = {}\n                @find('input.pvtFilter').not(':checked').each ->\n                    filter = $(this).data(\"filter\")\n                    if exclusions[filter[0]]?\n                        exclusions[filter[0]].push( filter[1] )\n                    else\n                        exclusions[filter[0]] = [ filter[1] ]\n                #include inclusions when exclusions present\n                inclusions = {}\n                @find('input.pvtFilter:checked').each ->\n                    filter = $(this).data(\"filter\")\n                    if exclusions[filter[0]]?\n                        if inclusions[filter[0]]?\n                            inclusions[filter[0]].push( filter[1] )\n                        else\n                            inclusions[filter[0]] = [ filter[1] ]\n\n                subopts.filter = (record) ->\n                    return false if not opts.filter(record)\n                    for k,excludedItems of exclusions\n                        return false if \"\"+(record[k] ? 'null') in excludedItems\n                    return true\n\n                pivotTable.pivot(materializedInput,subopts)\n                pivotUIOptions = $.extend {}, opts,\n                    cols: subopts.cols\n                    rows: subopts.rows\n                    colOrder: subopts.colOrder\n                    rowOrder: subopts.rowOrder\n                    vals: vals\n                    exclusions: exclusions\n                    inclusions: inclusions\n                    inclusionsInfo: inclusions #duplicated for backwards-compatibility\n                    aggregatorName: aggregator.val()\n                    rendererName: renderer.val()\n\n                @data \"pivotUIOptions\", pivotUIOptions\n\n                # if requested make sure unused columns are in alphabetical order\n                if opts.autoSortUnusedAttrs\n                    unusedAttrsContainer = @find(\"td.pvtUnused.pvtAxisContainer\")\n                    $(unusedAttrsContainer).children(\"li\")\n                        .sort((a, b) => naturalSort($(a).text(), $(b).text()))\n                        .appendTo unusedAttrsContainer\n\n                pivotTable.css(\"opacity\", 1)\n                opts.onRefresh(pivotUIOptions) if opts.onRefresh?\n\n            refresh = =>\n                pivotTable.css(\"opacity\", 0.5)\n                setTimeout refreshDelayed, 10\n\n            #the very first refresh will actually display the table\n            refresh()\n\n            @find(\".pvtAxisContainer\").sortable\n                    update: (e, ui) -> refresh() if not ui.sender?\n                    connectWith: @find(\".pvtAxisContainer\")\n                    items: 'li'\n                    placeholder: 'pvtPlaceholder'\n        catch e\n            console.error(e.stack) if console?\n            @html opts.localeStrings.uiRenderError\n        return this\n\n    ###\n    Heatmap post-processing\n    ###\n\n    $.fn.heatmap = (scope = \"heatmap\", opts) ->\n        numRows = @data \"numrows\"\n        numCols = @data \"numcols\"\n\n        # given a series of values\n        # must return a function to map a given value to a CSS color\n        colorScaleGenerator = opts?.heatmap?.colorScaleGenerator\n        colorScaleGenerator ?= (values) ->\n            min = Math.min(values...)\n            max = Math.max(values...)\n            return (x) ->\n                nonRed = 255 - Math.round 255*(x-min)/(max-min)\n                return \"rgb(255,#{nonRed},#{nonRed})\"\n\n        heatmapper = (scope) =>\n            forEachCell = (f) =>\n                @find(scope).each ->\n                    x = $(this).data(\"value\")\n                    f(x, $(this)) if x? and isFinite(x)\n\n            values = []\n            forEachCell (x) -> values.push x\n            colorScale = colorScaleGenerator(values)\n            forEachCell (x, elem) -> elem.css \"background-color\", colorScale(x)\n\n        switch scope\n            when \"heatmap\"    then heatmapper \".pvtVal\"\n            when \"rowheatmap\" then heatmapper \".pvtVal.row#{i}\" for i in [0...numRows]\n            when \"colheatmap\" then heatmapper \".pvtVal.col#{j}\" for j in [0...numCols]\n\n        heatmapper \".pvtTotal.rowTotal\"\n        heatmapper \".pvtTotal.colTotal\"\n\n        return this\n\n    ###\n    Barchart post-processing\n    ###\n\n    $.fn.barchart = (opts) ->\n        numRows = @data \"numrows\"\n        numCols = @data \"numcols\"\n\n        barcharter = (scope) =>\n            forEachCell = (f) =>\n                @find(scope).each ->\n                    x = $(this).data(\"value\")\n                    f(x, $(this)) if x? and isFinite(x)\n\n            values = []\n            forEachCell (x) -> values.push x\n            max = Math.max(values...)\n            if max < 0\n                max = 0\n            range = max;\n            min = Math.min(values...)\n            if min < 0\n                range = max - min\n            scaler = (x) -> 100*x/(1.4*range)\n            forEachCell (x, elem) ->\n                text = elem.text()\n                wrapper = $(\"<div>\").css\n                    \"position\": \"relative\"\n                    \"height\": \"55px\"\n                bgColor = \"gray\"\n                bBase = 0\n                if min < 0\n                    bBase = scaler(-min)\n                if x < 0\n                    bBase += scaler(x)\n                    bgColor = \"darkred\"\n                    x = -x\n                wrapper.append $(\"<div>\").css\n                    \"position\": \"absolute\"\n                    \"bottom\": bBase + \"%\"\n                    \"left\": 0\n                    \"right\": 0\n                    \"height\": scaler(x) + \"%\"\n                    \"background-color\": bgColor\n                wrapper.append $(\"<div>\").text(text).css\n                    \"position\":\"relative\"\n                    \"padding-left\":\"5px\"\n                    \"padding-right\":\"5px\"\n\n                elem.css(\"padding\": 0,\"padding-top\": \"5px\", \"text-align\": \"center\").html wrapper\n\n        barcharter \".pvtVal.row#{i}\" for i in [0...numRows]\n        barcharter \".pvtTotal.colTotal\"\n\n        return this\n"]}
\ No newline at end of file
diff --git a/dist/pivot.min.js b/dist/pivot.min.js
index b79a65a0..1436865a 100644
--- a/dist/pivot.min.js
+++ b/dist/pivot.min.js
@@ -1,2 +1,2 @@
-(function(){var t,e=[].indexOf||function(t){for(var e=0,n=this.length;e<n;e++)if(e in this&&this[e]===t)return e;return-1},n=[].slice,r=function(t,e){return function(){return t.apply(e,arguments)}},a={}.hasOwnProperty;(t=function(t){return"object"==typeof exports&&"object"==typeof module?t(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)})(function(t){var o,i,l,s,u,c,h,d,p,f,m,g,v,b,C,y,w,A,x,S,N;return i=function(t,e,n){var r,a,o,i;for(t+="",a=t.split("."),o=a[0],i=a.length>1?n+a[1]:"",r=/(\d+)(\d{3})/;r.test(o);)o=o.replace(r,"$1"+e+"$2");return o+i},m=function(e){var n;return n={digitsAfterDecimal:2,scaler:1,thousandsSep:",",decimalSep:".",prefix:"",suffix:""},e=t.extend({},n,e),function(t){var n;return isNaN(t)||!isFinite(t)?"":(n=i((e.scaler*t).toFixed(e.digitsAfterDecimal),e.thousandsSep,e.decimalSep),""+e.prefix+n+e.suffix)}},A=m(),x=m({digitsAfterDecimal:0}),S=m({digitsAfterDecimal:1,scaler:100,suffix:"%"}),l={count:function(t){return null==t&&(t=x),function(){return function(e,n,r){return{count:0,push:function(){return this.count++},value:function(){return this.count},format:t}}}},uniques:function(t,n){return null==n&&(n=x),function(r){var a;return a=r[0],function(r,o,i){return{uniq:[],push:function(t){var n;if(n=t[a],e.call(this.uniq,n)<0)return this.uniq.push(t[a])},value:function(){return t(this.uniq)},format:n,numInputs:null!=a?0:1}}}},sum:function(t){return null==t&&(t=A),function(e){var n;return n=e[0],function(e,r,a){return{sum:0,push:function(t){if(!isNaN(parseFloat(t[n])))return this.sum+=parseFloat(t[n])},value:function(){return this.sum},format:t,numInputs:null!=n?0:1}}}},extremes:function(t,e){return null==e&&(e=A),function(n){var r;return r=n[0],function(n,a,o){return{val:null,sorter:h(null!=n?n.sorters:void 0,r),push:function(e){var n,a,o,i;if(i=e[r],"min"!==t&&"max"!==t||(i=parseFloat(i),isNaN(i)||(this.val=Math[t](i,null!=(n=this.val)?n:i))),"first"===t&&this.sorter(i,null!=(a=this.val)?a:i)<=0&&(this.val=i),"last"===t&&this.sorter(i,null!=(o=this.val)?o:i)>=0)return this.val=i},value:function(){return this.val},format:function(t){return isNaN(t)?t:e(t)},numInputs:null!=r?0:1}}}},quantile:function(t,e){return null==e&&(e=A),function(n){var r;return r=n[0],function(n,a,o){return{vals:[],push:function(t){var e;if(e=parseFloat(t[r]),!isNaN(e))return this.vals.push(e)},value:function(){var e;return 0===this.vals.length?null:(this.vals.sort(function(t,e){return t-e}),e=(this.vals.length-1)*t,(this.vals[Math.floor(e)]+this.vals[Math.ceil(e)])/2)},format:e,numInputs:null!=r?0:1}}}},runningStat:function(t,e,n){return null==t&&(t="mean"),null==e&&(e=1),null==n&&(n=A),function(r){var a;return a=r[0],function(r,o,i){return{n:0,m:0,s:0,push:function(t){var e,n;if(n=parseFloat(t[a]),!isNaN(n))return this.n+=1,1===this.n?this.m=n:(e=this.m+(n-this.m)/this.n,this.s=this.s+(n-this.m)*(n-e),this.m=e)},value:function(){if("mean"===t)return 0===this.n?NaN:this.m;if(this.n<=e)return 0;switch(t){case"var":return this.s/(this.n-e);case"stdev":return Math.sqrt(this.s/(this.n-e))}},format:n,numInputs:null!=a?0:1}}}},sumOverSum:function(t){return null==t&&(t=A),function(e){var n,r;return r=e[0],n=e[1],function(e,a,o){return{sumNum:0,sumDenom:0,push:function(t){if(isNaN(parseFloat(t[r]))||(this.sumNum+=parseFloat(t[r])),!isNaN(parseFloat(t[n])))return this.sumDenom+=parseFloat(t[n])},value:function(){return this.sumNum/this.sumDenom},format:t,numInputs:null!=r&&null!=n?0:2}}}},sumOverSumBound80:function(t,e){return null==t&&(t=!0),null==e&&(e=A),function(n){var r,a;return a=n[0],r=n[1],function(n,o,i){return{sumNum:0,sumDenom:0,push:function(t){if(isNaN(parseFloat(t[a]))||(this.sumNum+=parseFloat(t[a])),!isNaN(parseFloat(t[r])))return this.sumDenom+=parseFloat(t[r])},value:function(){var e;return e=t?1:-1,(.821187207574908/this.sumDenom+this.sumNum/this.sumDenom+1.2815515655446004*e*Math.sqrt(.410593603787454/(this.sumDenom*this.sumDenom)+this.sumNum*(1-this.sumNum/this.sumDenom)/(this.sumDenom*this.sumDenom)))/(1+1.642374415149816/this.sumDenom)},format:e,numInputs:null!=a&&null!=r?0:2}}}},fractionOf:function(t,e,r){return null==e&&(e="total"),null==r&&(r=S),function(){var a;return a=1<=arguments.length?n.call(arguments,0):[],function(n,o,i){return{selector:{total:[[],[]],row:[o,[]],col:[[],i]}[e],inner:t.apply(null,a)(n,o,i),push:function(t){return this.inner.push(t)},format:r,value:function(){return this.inner.value()/n.getAggregator.apply(n,this.selector).inner.value()},numInputs:t.apply(null,a)().numInputs}}}}},l.countUnique=function(t){return l.uniques(function(t){return t.length},t)},l.listUnique=function(t){return l.uniques(function(e){return e.sort(f).join(t)},function(t){return t})},l.max=function(t){return l.extremes("max",t)},l.min=function(t){return l.extremes("min",t)},l.first=function(t){return l.extremes("first",t)},l.last=function(t){return l.extremes("last",t)},l.median=function(t){return l.quantile(.5,t)},l.average=function(t){return l.runningStat("mean",1,t)},l["var"]=function(t,e){return l.runningStat("var",t,e)},l.stdev=function(t,e){return l.runningStat("stdev",t,e)},s=function(t){return{Count:t.count(x),"Count Unique Values":t.countUnique(x),"List Unique Values":t.listUnique(", "),Sum:t.sum(A),"Integer Sum":t.sum(x),Average:t.average(A),Median:t.median(A),"Sample Variance":t["var"](1,A),"Sample Standard Deviation":t.stdev(1,A),Minimum:t.min(A),Maximum:t.max(A),First:t.first(A),Last:t.last(A),"Sum over Sum":t.sumOverSum(A),"80% Upper Bound":t.sumOverSumBound80(!0,A),"80% Lower Bound":t.sumOverSumBound80(!1,A),"Sum as Fraction of Total":t.fractionOf(t.sum(),"total",S),"Sum as Fraction of Rows":t.fractionOf(t.sum(),"row",S),"Sum as Fraction of Columns":t.fractionOf(t.sum(),"col",S),"Count as Fraction of Total":t.fractionOf(t.count(),"total",S),"Count as Fraction of Rows":t.fractionOf(t.count(),"row",S),"Count as Fraction of Columns":t.fractionOf(t.count(),"col",S)}}(l),b={Table:function(t,e){return g(t,e)},"Table Barchart":function(e,n){return t(g(e,n)).barchart()},Heatmap:function(e,n){return t(g(e,n)).heatmap("heatmap",n)},"Row Heatmap":function(e,n){return t(g(e,n)).heatmap("rowheatmap",n)},"Col Heatmap":function(e,n){return t(g(e,n)).heatmap("colheatmap",n)}},d={en:{aggregators:s,renderers:b,localeStrings:{renderError:"An error occurred rendering the PivotTable results.",computeError:"An error occurred computing the PivotTable results.",uiRenderError:"An error occurred rendering the PivotTable UI.",selectAll:"Select All",selectNone:"Select None",tooMany:"(too many to list)",filterResults:"Filter values",apply:"Apply",cancel:"Cancel",totals:"Totals",vs:"vs",by:"by"}}},p=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],u=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],N=function(t){return("0"+t).substr(-2,2)},c={bin:function(t,e){return function(n){return n[t]-n[t]%e}},dateFormat:function(t,e,n,r,a){var o;return null==n&&(n=!1),null==r&&(r=p),null==a&&(a=u),o=n?"UTC":"",function(n){var i;return i=new Date(Date.parse(n[t])),isNaN(i)?"":e.replace(/%(.)/g,function(t,e){switch(e){case"y":return i["get"+o+"FullYear"]();case"m":return N(i["get"+o+"Month"]()+1);case"n":return r[i["get"+o+"Month"]()];case"d":return N(i["get"+o+"Date"]());case"w":return a[i["get"+o+"Day"]()];case"x":return i["get"+o+"Day"]();case"H":return N(i["get"+o+"Hours"]());case"M":return N(i["get"+o+"Minutes"]());case"S":return N(i["get"+o+"Seconds"]());default:return"%"+e}})}}},C=/(\d+)|(\D+)/g,v=/\d/,y=/^0/,f=function(t){return function(t,e){var n,r,a,o,i,l;if(null!=e&&null==t)return-1;if(null!=t&&null==e)return 1;if("number"==typeof t&&isNaN(t))return-1;if("number"==typeof e&&isNaN(e))return 1;if(i=+t,l=+e,i<l)return-1;if(i>l)return 1;if("number"==typeof t&&"number"!=typeof e)return-1;if("number"==typeof e&&"number"!=typeof t)return 1;if("number"==typeof t&&"number"==typeof e)return 0;if(isNaN(l)&&!isNaN(i))return-1;if(isNaN(i)&&!isNaN(l))return 1;if(n=String(t),a=String(e),n===a)return 0;if(!v.test(n)||!v.test(a))return n>a?1:-1;for(n=n.match(C),a=a.match(C);n.length&&a.length;)if(r=n.shift(),o=a.shift(),r!==o)return v.test(r)&&v.test(o)?r.replace(y,".0")-o.replace(y,".0"):r>o?1:-1;return n.length-a.length}}(this),w=function(t){var e,n,r,a;r={},n={};for(e in t)a=t[e],r[a]=e,"string"==typeof a&&(n[a.toLowerCase()]=e);return function(t,e){return null!=r[t]&&null!=r[e]?r[t]-r[e]:null!=r[t]?-1:null!=r[e]?1:null!=n[t]&&null!=n[e]?n[t]-n[e]:null!=n[t]?-1:null!=n[e]?1:f(t,e)}},h=function(e,n){var r;if(null!=e)if(t.isFunction(e)){if(r=e(n),t.isFunction(r))return r}else if(null!=e[n])return e[n];return f},o=function(){function e(t,n){var a,o,i,s,u,c,h,d,p,f;null==n&&(n={}),this.getAggregator=r(this.getAggregator,this),this.getRowKeys=r(this.getRowKeys,this),this.getColKeys=r(this.getColKeys,this),this.sortKeys=r(this.sortKeys,this),this.arrSort=r(this.arrSort,this),this.input=t,this.aggregator=null!=(a=n.aggregator)?a:l.count()(),this.aggregatorName=null!=(o=n.aggregatorName)?o:"Count",this.colAttrs=null!=(i=n.cols)?i:[],this.rowAttrs=null!=(s=n.rows)?s:[],this.valAttrs=null!=(u=n.vals)?u:[],this.sorters=null!=(c=n.sorters)?c:{},this.rowOrder=null!=(h=n.rowOrder)?h:"key_a_to_z",this.colOrder=null!=(d=n.colOrder)?d:"key_a_to_z",this.derivedAttributes=null!=(p=n.derivedAttributes)?p:{},this.filter=null!=(f=n.filter)?f:function(){return!0},this.tree={},this.rowKeys=[],this.colKeys=[],this.rowTotals={},this.colTotals={},this.allTotal=this.aggregator(this,[],[]),this.sorted=!1,e.forEachRecord(this.input,this.derivedAttributes,function(t){return function(e){if(t.filter(e))return t.processRecord(e)}}(this))}return e.forEachRecord=function(e,n,r){var o,i,l,s,u,c,h,d,p,f,m,g;if(o=t.isEmptyObject(n)?r:function(t){var e,a,o;for(e in n)o=n[e],t[e]=null!=(a=o(t))?a:t[e];return r(t)},t.isFunction(e))return e(o);if(t.isArray(e)){if(t.isArray(e[0])){f=[];for(l in e)if(a.call(e,l)&&(i=e[l],l>0)){d={},p=e[0];for(s in p)a.call(p,s)&&(u=p[s],d[u]=i[s]);f.push(o(d))}return f}for(m=[],c=0,h=e.length;c<h;c++)d=e[c],m.push(o(d));return m}if(e instanceof t)return g=[],t("thead > tr > th",e).each(function(e){return g.push(t(this).text())}),t("tbody > tr",e).each(function(e){return d={},t("td",this).each(function(e){return d[g[e]]=t(this).text()}),o(d)});throw new Error("unknown input format")},e.prototype.forEachMatchingRecord=function(t,n){return e.forEachRecord(this.input,this.derivedAttributes,function(e){return function(r){var a,o,i;if(e.filter(r)){for(a in t)if(i=t[a],i!==(null!=(o=r[a])?o:"null"))return;return n(r)}}}(this))},e.prototype.arrSort=function(t){var e,n;return n=function(){var n,r,a;for(a=[],n=0,r=t.length;n<r;n++)e=t[n],a.push(h(this.sorters,e));return a}.call(this),function(t,e){var r,o,i;for(o in n)if(a.call(n,o)&&(i=n[o],r=i(t[o],e[o]),0!==r))return r;return 0}},e.prototype.sortKeys=function(){var t;if(!this.sorted){switch(this.sorted=!0,t=function(t){return function(e,n){return t.getAggregator(e,n).value()}}(this),this.rowOrder){case"value_a_to_z":this.rowKeys.sort(function(e){return function(e,n){return f(t(e,[]),t(n,[]))}}(this));break;case"value_z_to_a":this.rowKeys.sort(function(e){return function(e,n){return-f(t(e,[]),t(n,[]))}}(this));break;default:this.rowKeys.sort(this.arrSort(this.rowAttrs))}switch(this.colOrder){case"value_a_to_z":return this.colKeys.sort(function(e){return function(e,n){return f(t([],e),t([],n))}}(this));case"value_z_to_a":return this.colKeys.sort(function(e){return function(e,n){return-f(t([],e),t([],n))}}(this));default:return this.colKeys.sort(this.arrSort(this.colAttrs))}}},e.prototype.getColKeys=function(){return this.sortKeys(),this.colKeys},e.prototype.getRowKeys=function(){return this.sortKeys(),this.rowKeys},e.prototype.processRecord=function(t){var e,n,r,a,o,i,l,s,u,c,h,d,p;for(e=[],d=[],s=this.colAttrs,a=0,o=s.length;a<o;a++)p=s[a],e.push(null!=(u=t[p])?u:"null");for(c=this.rowAttrs,l=0,i=c.length;l<i;l++)p=c[l],d.push(null!=(h=t[p])?h:"null");if(r=d.join(String.fromCharCode(0)),n=e.join(String.fromCharCode(0)),this.allTotal.push(t),0!==d.length&&(this.rowTotals[r]||(this.rowKeys.push(d),this.rowTotals[r]=this.aggregator(this,d,[])),this.rowTotals[r].push(t)),0!==e.length&&(this.colTotals[n]||(this.colKeys.push(e),this.colTotals[n]=this.aggregator(this,[],e)),this.colTotals[n].push(t)),0!==e.length&&0!==d.length)return this.tree[r]||(this.tree[r]={}),this.tree[r][n]||(this.tree[r][n]=this.aggregator(this,d,e)),this.tree[r][n].push(t)},e.prototype.getAggregator=function(t,e){var n,r,a;return a=t.join(String.fromCharCode(0)),r=e.join(String.fromCharCode(0)),n=0===t.length&&0===e.length?this.allTotal:0===t.length?this.colTotals[r]:0===e.length?this.rowTotals[a]:this.tree[a][r],null!=n?n:{value:function(){return null},format:function(){return""}}},e}(),t.pivotUtilities={aggregatorTemplates:l,aggregators:s,renderers:b,derivers:c,locales:d,naturalSort:f,numberFormat:m,sortAs:w,PivotData:o},g=function(e,n){var r,o,i,l,s,u,c,h,d,p,f,m,g,v,b,C,y,w,A,x,S,N,T,k;u={table:{clickCallback:null,rowTotals:!0,colTotals:!0},localeStrings:{totals:"Totals"}},n=t.extend(!0,{},u,n),i=e.colAttrs,m=e.rowAttrs,v=e.getRowKeys(),s=e.getColKeys(),n.table.clickCallback&&(c=function(t,r,o){var l,s,u;s={};for(u in i)a.call(i,u)&&(l=i[u],null!=o[u]&&(s[l]=o[u]));for(u in m)a.call(m,u)&&(l=m[u],null!=r[u]&&(s[l]=r[u]));return function(r){return n.table.clickCallback(r,t,s,e)}}),f=document.createElement("table"),f.className="pvtTable",b=function(t,e,n){var r,a,o,i,l,s,u,c;if(0!==e){for(i=!0,c=r=0,l=n;0<=l?r<=l:r>=l;c=0<=l?++r:--r)t[e-1][c]!==t[e][c]&&(i=!1);if(i)return-1}for(a=0;e+a<t.length;){for(u=!1,c=o=0,s=n;0<=s?o<=s:o>=s;c=0<=s?++o:--o)t[e][c]!==t[e+a][c]&&(u=!0);if(u)break;a++}return a},A=document.createElement("thead");for(d in i)if(a.call(i,d)){o=i[d],S=document.createElement("tr"),0===parseInt(d)&&0!==m.length&&(w=document.createElement("th"),w.setAttribute("colspan",m.length),w.setAttribute("rowspan",i.length),S.appendChild(w)),w=document.createElement("th"),w.className="pvtAxisLabel",w.textContent=o,S.appendChild(w);for(h in s)a.call(s,h)&&(l=s[h],k=b(s,parseInt(h),parseInt(d)),k!==-1&&(w=document.createElement("th"),w.className="pvtColLabel",w.textContent=l[d],w.setAttribute("colspan",k),parseInt(d)===i.length-1&&0!==m.length&&w.setAttribute("rowspan",2),S.appendChild(w)));0===parseInt(d)&&n.table.rowTotals&&(w=document.createElement("th"),w.className="pvtTotalLabel pvtRowTotalLabel",w.innerHTML=n.localeStrings.totals,w.setAttribute("rowspan",i.length+(0===m.length?0:1)),S.appendChild(w)),A.appendChild(S)}if(0!==m.length){S=document.createElement("tr");for(h in m)a.call(m,h)&&(p=m[h],w=document.createElement("th"),w.className="pvtAxisLabel",w.textContent=p,S.appendChild(w));w=document.createElement("th"),0===i.length&&(w.className="pvtTotalLabel pvtRowTotalLabel",w.innerHTML=n.localeStrings.totals),S.appendChild(w),A.appendChild(S)}f.appendChild(A),C=document.createElement("tbody");for(h in v)if(a.call(v,h)){g=v[h],S=document.createElement("tr");for(d in g)a.call(g,d)&&(N=g[d],k=b(v,parseInt(h),parseInt(d)),k!==-1&&(w=document.createElement("th"),w.className="pvtRowLabel",w.textContent=N,w.setAttribute("rowspan",k),parseInt(d)===m.length-1&&0!==i.length&&w.setAttribute("colspan",2),S.appendChild(w)));for(d in s)a.call(s,d)&&(l=s[d],r=e.getAggregator(g,l),T=r.value(),y=document.createElement("td"),y.className="pvtVal row"+h+" col"+d,y.textContent=r.format(T),y.setAttribute("data-value",T),null!=c&&(y.onclick=c(T,g,l)),S.appendChild(y));(n.table.rowTotals||0===i.length)&&(x=e.getAggregator(g,[]),T=x.value(),y=document.createElement("td"),y.className="pvtTotal rowTotal",y.textContent=x.format(T),y.setAttribute("data-value",T),null!=c&&(y.onclick=c(T,g,[])),y.setAttribute("data-for","row"+h),S.appendChild(y)),C.appendChild(S)}if(n.table.colTotals||0===m.length){S=document.createElement("tr"),(n.table.colTotals||0===m.length)&&(w=document.createElement("th"),w.className="pvtTotalLabel pvtColTotalLabel",w.innerHTML=n.localeStrings.totals,w.setAttribute("colspan",m.length+(0===i.length?0:1)),S.appendChild(w));for(d in s)a.call(s,d)&&(l=s[d],x=e.getAggregator([],l),T=x.value(),y=document.createElement("td"),y.className="pvtTotal colTotal",y.textContent=x.format(T),y.setAttribute("data-value",T),null!=c&&(y.onclick=c(T,[],l)),y.setAttribute("data-for","col"+d),S.appendChild(y));(n.table.rowTotals||0===i.length)&&(x=e.getAggregator([],[]),T=x.value(),y=document.createElement("td"),y.className="pvtGrandTotal",y.textContent=x.format(T),y.setAttribute("data-value",T),null!=c&&(y.onclick=c(T,[],[])),S.appendChild(y)),C.appendChild(S)}return f.appendChild(C),f.setAttribute("data-numrows",v.length),f.setAttribute("data-numcols",s.length),f},t.fn.pivot=function(e,n,r){var a,i,s,u,c,h,p,f;null==r&&(r="en"),null==d[r]&&(r="en"),a={cols:[],rows:[],vals:[],rowOrder:"key_a_to_z",colOrder:"key_a_to_z",dataClass:o,filter:function(){return!0},aggregator:l.count()(),aggregatorName:"Count",sorters:{},derivedAttributes:{},renderer:g},u=t.extend(!0,{},d.en.localeStrings,d[r].localeStrings),s={rendererOptions:{localeStrings:u},localeStrings:u},c=t.extend(!0,{},s,t.extend({},a,n)),p=null;try{h=new c.dataClass(e,c);try{p=c.renderer(h,c.rendererOptions)}catch(m){i=m,"undefined"!=typeof console&&null!==console&&console.error(i.stack),p=t("<span>").html(c.localeStrings.renderError)}}catch(m){i=m,"undefined"!=typeof console&&null!==console&&console.error(i.stack),p=t("<span>").html(c.localeStrings.computeError)}for(f=this[0];f.hasChildNodes();)f.removeChild(f.lastChild);return this.append(p)},t.fn.pivotUI=function(n,r,i,l){var s,u,c,p,m,g,v,b,C,y,w,A,x,S,N,T,k,O,_,F,D,E,M,R,I,L,U,K,q,z,V,j,H,B,P,J,G,W,$,Q,Y,X,Z,tt,et;null==i&&(i=!1),null==l&&(l="en"),null==d[l]&&(l="en"),b={derivedAttributes:{},aggregators:d[l].aggregators,renderers:d[l].renderers,hiddenAttributes:[],hiddenFromAggregators:[],hiddenFromDragDrop:[],menuLimit:500,cols:[],rows:[],vals:[],rowOrder:"key_a_to_z",colOrder:"key_a_to_z",dataClass:o,exclusions:{},inclusions:{},unusedAttrsVertical:85,autoSortUnusedAttrs:!1,onRefresh:null,showUI:!0,filter:function(){return!0},sorters:{}},_=t.extend(!0,{},d.en.localeStrings,d[l].localeStrings),O={rendererOptions:{localeStrings:_},localeStrings:_},y=this.data("pivotUIOptions"),M=null==y||i?t.extend(!0,{},O,t.extend({},b,r)):y;try{m={},F=[],L=0,o.forEachRecord(n,M.derivedAttributes,function(t){var e,n,r,o;if(M.filter(t)){F.push(t);for(e in t)a.call(t,e)&&null==m[e]&&(m[e]={},L>0&&(m[e]["null"]=L));for(e in m)o=null!=(r=t[e])?r:"null",null==(n=m[e])[o]&&(n[o]=0),m[e][o]++;return L++}}),Y=t("<table>",{"class":"pvtUi"}).attr("cellpadding",5),B=t("<td>").addClass("pvtUiCell"),H=t("<select>").addClass("pvtRenderer").appendTo(B).bind("change",function(){return V()}),U=M.renderers;for(et in U)a.call(U,et)&&t("<option>").val(et).html(et).appendTo(H);if(X=t("<td>").addClass("pvtAxisContainer pvtUnused pvtUiCell"),J=function(){var t;t=[];for(s in m)e.call(M.hiddenAttributes,s)<0&&t.push(s);return t}(),G=function(){var t,n,r;for(r=[],t=0,n=J.length;t<n;t++)g=J[t],e.call(M.hiddenFromAggregators,g)<0&&r.push(g);return r}(),W=function(){var t,n,r;for(r=[],t=0,n=J.length;t<n;t++)g=J[t],e.call(M.hiddenFromDragDrop,g)<0&&r.push(g);return r}(),tt=!1,Z="auto"===M.unusedAttrsVertical?120:parseInt(M.unusedAttrsVertical),!isNaN(Z)){for(p=0,S=0,N=W.length;S<N;S++)s=W[S],p+=s.length;tt=p>Z}M.unusedAttrsVertical===!0||tt?X.addClass("pvtVertList"):X.addClass("pvtHorizList"),w=function(n){var r,a,o,i,l,s,u,c,d,p,f,g,v,b,C,y,w,x,S;if(S=function(){var t;t=[];for(C in m[n])t.push(C);return t}(),c=!1,x=t("<div>").addClass("pvtFilterBox").hide(),x.append(t("<h4>").append(t("<span>").text(n),t("<span>").addClass("count").text("("+S.length+")"))),S.length>M.menuLimit)x.append(t("<p>").html(M.localeStrings.tooMany));else for(S.length>5&&(i=t("<p>").appendTo(x),v=h(M.sorters,n),f=M.localeStrings.filterResults,t("<input>",{type:"text"}).appendTo(i).attr({placeholder:f,"class":"pvtSearch"}).bind("keyup",function(){var n,r,a;return a=t(this).val().toLowerCase().trim(),r=function(t,n){return function(r){var o,i;return o=a.substring(t.length).trim(),0===o.length||(i=Math.sign(v(r.toLowerCase(),o)),e.call(n,i)>=0)}},n=0===a.indexOf(">=")?r(">=",[1,0]):0===a.indexOf("<=")?r("<=",[-1,0]):0===a.indexOf(">")?r(">",[1]):0===a.indexOf("<")?r("<",[-1]):0===a.indexOf("~")?function(t){return 0===a.substring(1).trim().length||t.toLowerCase().match(a.substring(1))}:function(t){return t.toLowerCase().indexOf(a)!==-1},x.find(".pvtCheckContainer p label span.value").each(function(){return n(t(this).text())?t(this).parent().parent().show():t(this).parent().parent().hide()})}),i.append(t("<br>")),t("<button>",{type:"button"}).appendTo(i).html(M.localeStrings.selectAll).bind("click",function(){return x.find("input:visible:not(:checked)").prop("checked",!0).toggleClass("changed"),!1}),t("<button>",{type:"button"}).appendTo(i).html(M.localeStrings.selectNone).bind("click",function(){return x.find("input:visible:checked").prop("checked",!1).toggleClass("changed"),!1})),a=t("<div>").addClass("pvtCheckContainer").appendTo(x),g=S.sort(h(M.sorters,n)),p=0,d=g.length;p<d;p++)y=g[p],w=m[n][y],l=t("<label>"),s=!1,M.inclusions[n]?s=e.call(M.inclusions[n],y)<0:M.exclusions[n]&&(s=e.call(M.exclusions[n],y)>=0),c||(c=s),t("<input>").attr("type","checkbox").addClass("pvtFilter").attr("checked",!s).data("filter",[n,y]).appendTo(l).bind("change",function(){return t(this).toggleClass("changed")}),l.append(t("<span>").addClass("value").text(y)),l.append(t("<span>").addClass("count").text("("+w+")")),a.append(t("<p>").append(l));return o=function(){return x.find("[type='checkbox']").length>x.find("[type='checkbox']:checked").length?r.addClass("pvtFilteredAttribute"):r.removeClass("pvtFilteredAttribute"),x.find(".pvtSearch").val(""),x.find(".pvtCheckContainer p").show(),x.hide()},u=t("<p>").appendTo(x),S.length<=M.menuLimit&&t("<button>",{type:"button"}).text(M.localeStrings.apply).appendTo(u).bind("click",function(){return x.find(".changed").removeClass("changed").length&&V(),o()}),t("<button>",{type:"button"}).text(M.localeStrings.cancel).appendTo(u).bind("click",function(){return x.find(".changed:checked").removeClass("changed").prop("checked",!1),x.find(".changed:not(:checked)").removeClass("changed").prop("checked",!0),o()}),b=t("<span>").addClass("pvtTriangle").html(" &#x25BE;").bind("click",function(e){var n,r,a;return r=t(e.currentTarget).position(),n=r.left,a=r.top,x.css({left:n+10,top:a+10}).show()}),r=t("<li>").addClass("axis_"+A).append(t("<span>").addClass("pvtAttr").text(n).data("attrName",n).append(b)),c&&r.addClass("pvtFilteredAttribute"),X.append(r).append(x)};for(A in W)a.call(W,A)&&(c=W[A],w(c));$=t("<tr>").appendTo(Y),u=t("<select>").addClass("pvtAggregator").bind("change",function(){return V()}),K=M.aggregators;for(et in K)a.call(K,et)&&u.append(t("<option>").val(et).html(et));for(R={key_a_to_z:{rowSymbol:"&varr;",colSymbol:"&harr;",next:"value_a_to_z"},value_a_to_z:{rowSymbol:"&darr;",colSymbol:"&rarr;",next:"value_z_to_a"},value_z_to_a:{rowSymbol:"&uarr;",colSymbol:"&larr;",next:"key_a_to_z"}},P=t("<a>",{role:"button"}).addClass("pvtRowOrder").data("order",M.rowOrder).html(R[M.rowOrder].rowSymbol).bind("click",function(){return t(this).data("order",R[t(this).data("order")].next),t(this).html(R[t(this).data("order")].rowSymbol),V()}),v=t("<a>",{role:"button"}).addClass("pvtColOrder").data("order",M.colOrder).html(R[M.colOrder].colSymbol).bind("click",function(){return t(this).data("order",R[t(this).data("order")].next),t(this).html(R[t(this).data("order")].colSymbol),V()}),t("<td>").addClass("pvtVals pvtUiCell").appendTo($).append(u).append(P).append(v).append(t("<br>")),t("<td>").addClass("pvtAxisContainer pvtHorizList pvtCols pvtUiCell").appendTo($),Q=t("<tr>").appendTo(Y),Q.append(t("<td>").addClass("pvtAxisContainer pvtRows pvtUiCell").attr("valign","top")),I=t("<td>").attr("valign","top").addClass("pvtRendererArea").appendTo(Q),M.unusedAttrsVertical===!0||tt?(Y.find("tr:nth-child(1)").prepend(B),Y.find("tr:nth-child(2)").prepend(X)):Y.prepend(t("<tr>").append(B).append(X)),this.html(Y),q=M.cols,D=0,T=q.length;D<T;D++)et=q[D],this.find(".pvtCols").append(this.find(".axis_"+t.inArray(et,W)));for(z=M.rows,E=0,k=z.length;E<k;E++)et=z[E],this.find(".pvtRows").append(this.find(".axis_"+t.inArray(et,W)));null!=M.aggregatorName&&this.find(".pvtAggregator").val(M.aggregatorName),null!=M.rendererName&&this.find(".pvtRenderer").val(M.rendererName),M.showUI||this.find(".pvtUiCell").hide(),x=!0,j=function(n){return function(){var r,a,o,i,l,s,h,d,p,m,g,b,C,y;if(m={derivedAttributes:M.derivedAttributes,localeStrings:M.localeStrings,rendererOptions:M.rendererOptions,sorters:M.sorters,cols:[],rows:[],dataClass:M.dataClass},l=null!=(d=M.aggregators[u.val()]([])().numInputs)?d:0,y=[],n.find(".pvtRows li span.pvtAttr").each(function(){return m.rows.push(t(this).data("attrName"))}),n.find(".pvtCols li span.pvtAttr").each(function(){return m.cols.push(t(this).data("attrName"))}),n.find(".pvtVals select.pvtAttrDropdown").each(function(){return 0===l?t(this).remove():(l--,""!==t(this).val()?y.push(t(this).val()):void 0)}),0!==l)for(h=n.find(".pvtVals"),et=g=0,p=l;0<=p?g<p:g>p;et=0<=p?++g:--g){for(i=t("<select>").addClass("pvtAttrDropdown").append(t("<option>")).bind("change",function(){return V()}),b=0,o=G.length;b<o;b++)c=G[b],i.append(t("<option>").val(c).text(c));h.append(i)}if(x&&(y=M.vals,A=0,n.find(".pvtVals select.pvtAttrDropdown").each(function(){return t(this).val(y[A]),A++}),x=!1),m.aggregatorName=u.val(),m.vals=y,m.aggregator=M.aggregators[u.val()](y),m.renderer=M.renderers[H.val()],m.rowOrder=P.data("order"),m.colOrder=v.data("order"),r={},n.find("input.pvtFilter").not(":checked").each(function(){var e;return e=t(this).data("filter"),null!=r[e[0]]?r[e[0]].push(e[1]):r[e[0]]=[e[1]]}),a={},n.find("input.pvtFilter:checked").each(function(){var e;if(e=t(this).data("filter"),null!=r[e[0]])return null!=a[e[0]]?a[e[0]].push(e[1]):a[e[0]]=[e[1]]}),m.filter=function(t){var n,a,o,i;if(!M.filter(t))return!1;for(a in r)if(n=r[a],o=""+(null!=(i=t[a])?i:"null"),e.call(n,o)>=0)return!1;return!0},I.pivot(F,m),s=t.extend({},M,{cols:m.cols,rows:m.rows,colOrder:m.colOrder,rowOrder:m.rowOrder,vals:y,exclusions:r,inclusions:a,inclusionsInfo:a,aggregatorName:u.val(),rendererName:H.val()}),n.data("pivotUIOptions",s),M.autoSortUnusedAttrs&&(C=n.find("td.pvtUnused.pvtAxisContainer"),t(C).children("li").sort(function(e,n){return f(t(e).text(),t(n).text())}).appendTo(C)),I.css("opacity",1),null!=M.onRefresh)return M.onRefresh(s)}}(this),V=function(t){return function(){return I.css("opacity",.5),setTimeout(j,10)}}(this),V(),this.find(".pvtAxisContainer").sortable({update:function(t,e){if(null==e.sender)return V()},connectWith:this.find(".pvtAxisContainer"),items:"li",placeholder:"pvtPlaceholder"})}catch(nt){C=nt,"undefined"!=typeof console&&null!==console&&console.error(C.stack),this.html(M.localeStrings.uiRenderError)}return this},t.fn.heatmap=function(e,n){var r,a,o,i,l,s,u,c,h,d,p;switch(null==e&&(e="heatmap"),c=this.data("numrows"),u=this.data("numcols"),r=null!=n&&null!=(h=n.heatmap)?h.colorScaleGenerator:void 0,null==r&&(r=function(t){var e,n;return n=Math.min.apply(Math,t),e=Math.max.apply(Math,t),function(t){var r;return r=255-Math.round(255*(t-n)/(e-n)),"rgb(255,"+r+","+r+")"}}),a=function(e){return function(n){var a,o,i;return o=function(r){return e.find(n).each(function(){var e;if(e=t(this).data("value"),null!=e&&isFinite(e))return r(e,t(this))})},i=[],o(function(t){return i.push(t)}),a=r(i),o(function(t,e){return e.css("background-color",a(t))})}}(this),e){case"heatmap":a(".pvtVal");break;case"rowheatmap":for(o=l=0,d=c;0<=d?l<d:l>d;o=0<=d?++l:--l)a(".pvtVal.row"+o);break;case"colheatmap":for(i=s=0,p=u;0<=p?s<p:s>p;i=0<=p?++s:--s)a(".pvtVal.col"+i)}return a(".pvtTotal.rowTotal"),a(".pvtTotal.colTotal"),this},t.fn.barchart=function(e){var n,r,a,o,i,l;for(i=this.data("numrows"),o=this.data("numcols"),n=function(e){return function(n){var r,a,o,i,l,s;return r=function(r){return e.find(n).each(function(){var e;if(e=t(this).data("value"),null!=e&&isFinite(e))return r(e,t(this))})},s=[],r(function(t){return s.push(t)}),a=Math.max.apply(Math,s),a<0&&(a=0),i=a,o=Math.min.apply(Math,s),o<0&&(i=a-o),l=function(t){return 100*t/(1.4*i)},r(function(e,n){var r,a,i,s;return i=n.text(),s=t("<div>").css({position:"relative",height:"55px"}),a="gray",r=0,o<0&&(r=l(-o)),e<0&&(r+=l(e),a="darkred",e=-e),s.append(t("<div>").css({position:"absolute",bottom:r+"%",left:0,right:0,height:l(e)+"%","background-color":a})),s.append(t("<div>").text(i).css({position:"relative","padding-left":"5px","padding-right":"5px"})),n.css({padding:0,"padding-top":"5px","text-align":"center"}).html(s)})}}(this),r=a=0,l=i;0<=l?a<l:a>l;r=0<=l?++a:--a)n(".pvtVal.row"+r);return n(".pvtTotal.colTotal"),this}})}).call(this);
+(function(){var t,e=[].indexOf||function(t){for(var e=0,n=this.length;e<n;e++)if(e in this&&this[e]===t)return e;return-1},n=[].slice,r=function(t,e){return function(){return t.apply(e,arguments)}},a={}.hasOwnProperty;(t=function(t){return"object"==typeof exports&&"object"==typeof module?t(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)})(function(t){var o,i,l,s,u,c,h,d,p,f,m,g,v,b,C,y,w,A,x,S,N;return i=function(t,e,n){var r,a,o,i;for(t+="",a=t.split("."),o=a[0],i=a.length>1?n+a[1]:"",r=/(\d+)(\d{3})/;r.test(o);)o=o.replace(r,"$1"+e+"$2");return o+i},m=function(e){var n;return n={digitsAfterDecimal:2,scaler:1,thousandsSep:",",decimalSep:".",prefix:"",suffix:""},e=t.extend({},n,e),function(t){var n;return isNaN(t)||!isFinite(t)?"":(n=i((e.scaler*t).toFixed(e.digitsAfterDecimal),e.thousandsSep,e.decimalSep),""+e.prefix+n+e.suffix)}},A=m(),x=m({digitsAfterDecimal:0}),S=m({digitsAfterDecimal:1,scaler:100,suffix:"%"}),l={count:function(t){return null==t&&(t=x),function(){return function(e,n,r){return{count:0,push:function(){return this.count++},value:function(){return this.count},format:t}}}},uniques:function(t,n){return null==n&&(n=x),function(r){var a;return a=r[0],function(r,o,i){return{uniq:[],push:function(t){var n;if(n=t[a],e.call(this.uniq,n)<0)return this.uniq.push(t[a])},value:function(){return t(this.uniq)},format:n,numInputs:null!=a?0:1}}}},sum:function(t){return null==t&&(t=A),function(e){var n;return n=e[0],function(e,r,a){return{sum:0,push:function(t){if(!isNaN(parseFloat(t[n])))return this.sum+=parseFloat(t[n])},value:function(){return this.sum},format:t,numInputs:null!=n?0:1}}}},extremes:function(t,e){return null==e&&(e=A),function(n){var r;return r=n[0],function(n,a,o){return{val:null,sorter:h(null!=n?n.sorters:void 0,r),push:function(e){var n,a,o,i;if(i=e[r],"min"!==t&&"max"!==t||(i=parseFloat(i),isNaN(i)||(this.val=Math[t](i,null!=(n=this.val)?n:i))),"first"===t&&this.sorter(i,null!=(a=this.val)?a:i)<=0&&(this.val=i),"last"===t&&this.sorter(i,null!=(o=this.val)?o:i)>=0)return this.val=i},value:function(){return this.val},format:function(t){return isNaN(t)?t:e(t)},numInputs:null!=r?0:1}}}},quantile:function(t,e){return null==e&&(e=A),function(n){var r;return r=n[0],function(n,a,o){return{vals:[],push:function(t){var e;if(e=parseFloat(t[r]),!isNaN(e))return this.vals.push(e)},value:function(){var e;return 0===this.vals.length?null:(this.vals.sort(function(t,e){return t-e}),e=(this.vals.length-1)*t,(this.vals[Math.floor(e)]+this.vals[Math.ceil(e)])/2)},format:e,numInputs:null!=r?0:1}}}},runningStat:function(t,e,n){return null==t&&(t="mean"),null==e&&(e=1),null==n&&(n=A),function(r){var a;return a=r[0],function(r,o,i){return{n:0,m:0,s:0,push:function(t){var e,n;if(n=parseFloat(t[a]),!isNaN(n))return this.n+=1,1===this.n?this.m=n:(e=this.m+(n-this.m)/this.n,this.s=this.s+(n-this.m)*(n-e),this.m=e)},value:function(){if("mean"===t)return 0===this.n?NaN:this.m;if(this.n<=e)return 0;switch(t){case"var":return this.s/(this.n-e);case"stdev":return Math.sqrt(this.s/(this.n-e))}},format:n,numInputs:null!=a?0:1}}}},sumOverSum:function(t){return null==t&&(t=A),function(e){var n,r;return r=e[0],n=e[1],function(e,a,o){return{sumNum:0,sumDenom:0,push:function(t){if(isNaN(parseFloat(t[r]))||(this.sumNum+=parseFloat(t[r])),!isNaN(parseFloat(t[n])))return this.sumDenom+=parseFloat(t[n])},value:function(){return this.sumNum/this.sumDenom},format:t,numInputs:null!=r&&null!=n?0:2}}}},sumOverSumBound80:function(t,e){return null==t&&(t=!0),null==e&&(e=A),function(n){var r,a;return a=n[0],r=n[1],function(n,o,i){return{sumNum:0,sumDenom:0,push:function(t){if(isNaN(parseFloat(t[a]))||(this.sumNum+=parseFloat(t[a])),!isNaN(parseFloat(t[r])))return this.sumDenom+=parseFloat(t[r])},value:function(){var e;return e=t?1:-1,(.821187207574908/this.sumDenom+this.sumNum/this.sumDenom+1.2815515655446004*e*Math.sqrt(.410593603787454/(this.sumDenom*this.sumDenom)+this.sumNum*(1-this.sumNum/this.sumDenom)/(this.sumDenom*this.sumDenom)))/(1+1.642374415149816/this.sumDenom)},format:e,numInputs:null!=a&&null!=r?0:2}}}},fractionOf:function(t,e,r){return null==e&&(e="total"),null==r&&(r=S),function(){var a;return a=1<=arguments.length?n.call(arguments,0):[],function(n,o,i){return{selector:{total:[[],[]],row:[o,[]],col:[[],i]}[e],inner:t.apply(null,a)(n,o,i),push:function(t){return this.inner.push(t)},format:r,value:function(){return this.inner.value()/n.getAggregator.apply(n,this.selector).inner.value()},numInputs:t.apply(null,a)().numInputs}}}}},l.countUnique=function(t){return l.uniques(function(t){return t.length},t)},l.listUnique=function(t){return l.uniques(function(e){return e.sort(f).join(t)},function(t){return t})},l.max=function(t){return l.extremes("max",t)},l.min=function(t){return l.extremes("min",t)},l.first=function(t){return l.extremes("first",t)},l.last=function(t){return l.extremes("last",t)},l.median=function(t){return l.quantile(.5,t)},l.average=function(t){return l.runningStat("mean",1,t)},l["var"]=function(t,e){return l.runningStat("var",t,e)},l.stdev=function(t,e){return l.runningStat("stdev",t,e)},s=function(t){return{Count:t.count(x),"Count Unique Values":t.countUnique(x),"List Unique Values":t.listUnique(", "),Sum:t.sum(A),"Integer Sum":t.sum(x),Average:t.average(A),Median:t.median(A),"Sample Variance":t["var"](1,A),"Sample Standard Deviation":t.stdev(1,A),Minimum:t.min(A),Maximum:t.max(A),First:t.first(A),Last:t.last(A),"Sum over Sum":t.sumOverSum(A),"80% Upper Bound":t.sumOverSumBound80(!0,A),"80% Lower Bound":t.sumOverSumBound80(!1,A),"Sum as Fraction of Total":t.fractionOf(t.sum(),"total",S),"Sum as Fraction of Rows":t.fractionOf(t.sum(),"row",S),"Sum as Fraction of Columns":t.fractionOf(t.sum(),"col",S),"Count as Fraction of Total":t.fractionOf(t.count(),"total",S),"Count as Fraction of Rows":t.fractionOf(t.count(),"row",S),"Count as Fraction of Columns":t.fractionOf(t.count(),"col",S)}}(l),b={Table:function(t,e){return g(t,e)},"Table Barchart":function(e,n){return t(g(e,n)).barchart()},Heatmap:function(e,n){return t(g(e,n)).heatmap("heatmap",n)},"Row Heatmap":function(e,n){return t(g(e,n)).heatmap("rowheatmap",n)},"Col Heatmap":function(e,n){return t(g(e,n)).heatmap("colheatmap",n)}},d={en:{aggregators:s,renderers:b,localeStrings:{renderError:"An error occurred rendering the PivotTable results.",computeError:"An error occurred computing the PivotTable results.",uiRenderError:"An error occurred rendering the PivotTable UI.",selectAll:"Select All",selectNone:"Select None",tooMany:"(too many to list)",filterResults:"Filter values",apply:"Apply",cancel:"Cancel",totals:"Totals",vs:"vs",by:"by"}}},p=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],u=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],N=function(t){return("0"+t).substr(-2,2)},c={bin:function(t,e){return function(n){return n[t]-n[t]%e}},dateFormat:function(t,e,n,r,a){var o;return null==n&&(n=!1),null==r&&(r=p),null==a&&(a=u),o=n?"UTC":"",function(n){var i;return i=new Date(Date.parse(n[t])),isNaN(i)?"":e.replace(/%(.)/g,function(t,e){switch(e){case"y":return i["get"+o+"FullYear"]();case"m":return N(i["get"+o+"Month"]()+1);case"n":return r[i["get"+o+"Month"]()];case"d":return N(i["get"+o+"Date"]());case"w":return a[i["get"+o+"Day"]()];case"x":return i["get"+o+"Day"]();case"H":return N(i["get"+o+"Hours"]());case"M":return N(i["get"+o+"Minutes"]());case"S":return N(i["get"+o+"Seconds"]());default:return"%"+e}})}}},C=/(\d+)|(\D+)/g,v=/\d/,y=/^0/,f=function(t){return function(t,e){var n,r,a,o,i,l,s;if(null!=e&&null==t)return-1;if(null!=t&&null==e)return 1;if("number"==typeof t&&isNaN(t))return-1;if("number"==typeof e&&isNaN(e))return 1;if(i=+t,l=+e,i<l)return-1;if(i>l)return 1;if("number"==typeof t&&"number"!=typeof e)return-1;if("number"==typeof e&&"number"!=typeof t)return 1;if("number"==typeof t&&"number"==typeof e)return 0;if(isNaN(l)&&!isNaN(i))return-1;if(isNaN(i)&&!isNaN(l))return 1;if(n=String(t),a=String(e),n===a)return 0;if(!v.test(n)||!v.test(a))return n>a?1:-1;for(n=n.match(C),a=a.match(C);n.length&&a.length;)if(r=n.shift(),o=a.shift(),r!==o)return v.test(r)&&v.test(o)?(s=r.replace(y,".0")-o.replace(y,".0"),0!==s?s:r.length-o.length):r>o?1:-1;return n.length-a.length}}(this),w=function(t){var e,n,r,a;r={},n={};for(e in t)a=t[e],r[a]=e,"string"==typeof a&&(n[a.toLowerCase()]=e);return function(t,e){return null!=r[t]&&null!=r[e]?r[t]-r[e]:null!=r[t]?-1:null!=r[e]?1:null!=n[t]&&null!=n[e]?n[t]-n[e]:null!=n[t]?-1:null!=n[e]?1:f(t,e)}},h=function(e,n){var r;if(null!=e)if(t.isFunction(e)){if(r=e(n),t.isFunction(r))return r}else if(null!=e[n])return e[n];return f},o=function(){function e(t,n){var a,o,i,s,u,c,h,d,p,f;null==n&&(n={}),this.getAggregator=r(this.getAggregator,this),this.getRowKeys=r(this.getRowKeys,this),this.getColKeys=r(this.getColKeys,this),this.sortKeys=r(this.sortKeys,this),this.arrSort=r(this.arrSort,this),this.input=t,this.aggregator=null!=(a=n.aggregator)?a:l.count()(),this.aggregatorName=null!=(o=n.aggregatorName)?o:"Count",this.colAttrs=null!=(i=n.cols)?i:[],this.rowAttrs=null!=(s=n.rows)?s:[],this.valAttrs=null!=(u=n.vals)?u:[],this.sorters=null!=(c=n.sorters)?c:{},this.rowOrder=null!=(h=n.rowOrder)?h:"key_a_to_z",this.colOrder=null!=(d=n.colOrder)?d:"key_a_to_z",this.derivedAttributes=null!=(p=n.derivedAttributes)?p:{},this.filter=null!=(f=n.filter)?f:function(){return!0},this.tree={},this.rowKeys=[],this.colKeys=[],this.rowTotals={},this.colTotals={},this.allTotal=this.aggregator(this,[],[]),this.sorted=!1,e.forEachRecord(this.input,this.derivedAttributes,function(t){return function(e){if(t.filter(e))return t.processRecord(e)}}(this))}return e.forEachRecord=function(e,n,r){var o,i,l,s,u,c,h,d,p,f,m,g;if(o=t.isEmptyObject(n)?r:function(t){var e,a,o;for(e in n)o=n[e],t[e]=null!=(a=o(t))?a:t[e];return r(t)},t.isFunction(e))return e(o);if(t.isArray(e)){if(t.isArray(e[0])){f=[];for(l in e)if(a.call(e,l)&&(i=e[l],l>0)){d={},p=e[0];for(s in p)a.call(p,s)&&(u=p[s],d[u]=i[s]);f.push(o(d))}return f}for(m=[],c=0,h=e.length;c<h;c++)d=e[c],m.push(o(d));return m}if(e instanceof t)return g=[],t("thead > tr > th",e).each(function(e){return g.push(t(this).text())}),t("tbody > tr",e).each(function(e){return d={},t("td",this).each(function(e){return d[g[e]]=t(this).text()}),o(d)});throw new Error("unknown input format")},e.prototype.forEachMatchingRecord=function(t,n){return e.forEachRecord(this.input,this.derivedAttributes,function(e){return function(r){var a,o,i;if(e.filter(r)){for(a in t)if(i=t[a],i!==(null!=(o=r[a])?o:"null"))return;return n(r)}}}(this))},e.prototype.arrSort=function(t){var e,n;return n=function(){var n,r,a;for(a=[],n=0,r=t.length;n<r;n++)e=t[n],a.push(h(this.sorters,e));return a}.call(this),function(t,e){var r,o,i;for(o in n)if(a.call(n,o)&&(i=n[o],r=i(t[o],e[o]),0!==r))return r;return 0}},e.prototype.sortKeys=function(){var t;if(!this.sorted){switch(this.sorted=!0,t=function(t){return function(e,n){return t.getAggregator(e,n).value()}}(this),this.rowOrder){case"value_a_to_z":this.rowKeys.sort(function(e){return function(e,n){return f(t(e,[]),t(n,[]))}}(this));break;case"value_z_to_a":this.rowKeys.sort(function(e){return function(e,n){return-f(t(e,[]),t(n,[]))}}(this));break;default:this.rowKeys.sort(this.arrSort(this.rowAttrs))}switch(this.colOrder){case"value_a_to_z":return this.colKeys.sort(function(e){return function(e,n){return f(t([],e),t([],n))}}(this));case"value_z_to_a":return this.colKeys.sort(function(e){return function(e,n){return-f(t([],e),t([],n))}}(this));default:return this.colKeys.sort(this.arrSort(this.colAttrs))}}},e.prototype.getColKeys=function(){return this.sortKeys(),this.colKeys},e.prototype.getRowKeys=function(){return this.sortKeys(),this.rowKeys},e.prototype.processRecord=function(t){var e,n,r,a,o,i,l,s,u,c,h,d,p;for(e=[],d=[],s=this.colAttrs,a=0,o=s.length;a<o;a++)p=s[a],e.push(null!=(u=t[p])?u:"null");for(c=this.rowAttrs,l=0,i=c.length;l<i;l++)p=c[l],d.push(null!=(h=t[p])?h:"null");if(r=d.join(String.fromCharCode(0)),n=e.join(String.fromCharCode(0)),this.allTotal.push(t),0!==d.length&&(this.rowTotals[r]||(this.rowKeys.push(d),this.rowTotals[r]=this.aggregator(this,d,[])),this.rowTotals[r].push(t)),0!==e.length&&(this.colTotals[n]||(this.colKeys.push(e),this.colTotals[n]=this.aggregator(this,[],e)),this.colTotals[n].push(t)),0!==e.length&&0!==d.length)return this.tree[r]||(this.tree[r]={}),this.tree[r][n]||(this.tree[r][n]=this.aggregator(this,d,e)),this.tree[r][n].push(t)},e.prototype.getAggregator=function(t,e){var n,r,a;return a=t.join(String.fromCharCode(0)),r=e.join(String.fromCharCode(0)),n=0===t.length&&0===e.length?this.allTotal:0===t.length?this.colTotals[r]:0===e.length?this.rowTotals[a]:this.tree[a][r],null!=n?n:{value:function(){return null},format:function(){return""}}},e}(),t.pivotUtilities={aggregatorTemplates:l,aggregators:s,renderers:b,derivers:c,locales:d,naturalSort:f,numberFormat:m,sortAs:w,PivotData:o},g=function(e,n){var r,o,i,l,s,u,c,h,d,p,f,m,g,v,b,C,y,w,A,x,S,N,T,k;u={table:{clickCallback:null,rowTotals:!0,colTotals:!0},localeStrings:{totals:"Totals"}},n=t.extend(!0,{},u,n),i=e.colAttrs,m=e.rowAttrs,v=e.getRowKeys(),s=e.getColKeys(),n.table.clickCallback&&(c=function(t,r,o){var l,s,u;s={};for(u in i)a.call(i,u)&&(l=i[u],null!=o[u]&&(s[l]=o[u]));for(u in m)a.call(m,u)&&(l=m[u],null!=r[u]&&(s[l]=r[u]));return function(r){return n.table.clickCallback(r,t,s,e)}}),f=document.createElement("table"),f.className="pvtTable",b=function(t,e,n){var r,a,o,i,l,s,u,c;if(0!==e){for(i=!0,c=r=0,l=n;0<=l?r<=l:r>=l;c=0<=l?++r:--r)t[e-1][c]!==t[e][c]&&(i=!1);if(i)return-1}for(a=0;e+a<t.length;){for(u=!1,c=o=0,s=n;0<=s?o<=s:o>=s;c=0<=s?++o:--o)t[e][c]!==t[e+a][c]&&(u=!0);if(u)break;a++}return a},A=document.createElement("thead");for(d in i)if(a.call(i,d)){o=i[d],S=document.createElement("tr"),0===parseInt(d)&&0!==m.length&&(w=document.createElement("th"),w.setAttribute("colspan",m.length),w.setAttribute("rowspan",i.length),S.appendChild(w)),w=document.createElement("th"),w.className="pvtAxisLabel",w.textContent=o,S.appendChild(w);for(h in s)a.call(s,h)&&(l=s[h],k=b(s,parseInt(h),parseInt(d)),k!==-1&&(w=document.createElement("th"),w.className="pvtColLabel",w.textContent=l[d],w.setAttribute("colspan",k),parseInt(d)===i.length-1&&0!==m.length&&w.setAttribute("rowspan",2),S.appendChild(w)));0===parseInt(d)&&n.table.rowTotals&&(w=document.createElement("th"),w.className="pvtTotalLabel pvtRowTotalLabel",w.innerHTML=n.localeStrings.totals,w.setAttribute("rowspan",i.length+(0===m.length?0:1)),S.appendChild(w)),A.appendChild(S)}if(0!==m.length){S=document.createElement("tr");for(h in m)a.call(m,h)&&(p=m[h],w=document.createElement("th"),w.className="pvtAxisLabel",w.textContent=p,S.appendChild(w));w=document.createElement("th"),0===i.length&&(w.className="pvtTotalLabel pvtRowTotalLabel",w.innerHTML=n.localeStrings.totals),S.appendChild(w),A.appendChild(S)}f.appendChild(A),C=document.createElement("tbody");for(h in v)if(a.call(v,h)){g=v[h],S=document.createElement("tr");for(d in g)a.call(g,d)&&(N=g[d],k=b(v,parseInt(h),parseInt(d)),k!==-1&&(w=document.createElement("th"),w.className="pvtRowLabel",w.textContent=N,w.setAttribute("rowspan",k),parseInt(d)===m.length-1&&0!==i.length&&w.setAttribute("colspan",2),S.appendChild(w)));for(d in s)a.call(s,d)&&(l=s[d],r=e.getAggregator(g,l),T=r.value(),y=document.createElement("td"),y.className="pvtVal row"+h+" col"+d,y.textContent=r.format(T),y.setAttribute("data-value",T),null!=c&&(y.onclick=c(T,g,l)),S.appendChild(y));(n.table.rowTotals||0===i.length)&&(x=e.getAggregator(g,[]),T=x.value(),y=document.createElement("td"),y.className="pvtTotal rowTotal",y.textContent=x.format(T),y.setAttribute("data-value",T),null!=c&&(y.onclick=c(T,g,[])),y.setAttribute("data-for","row"+h),S.appendChild(y)),C.appendChild(S)}if(n.table.colTotals||0===m.length){S=document.createElement("tr"),(n.table.colTotals||0===m.length)&&(w=document.createElement("th"),w.className="pvtTotalLabel pvtColTotalLabel",w.innerHTML=n.localeStrings.totals,w.setAttribute("colspan",m.length+(0===i.length?0:1)),S.appendChild(w));for(d in s)a.call(s,d)&&(l=s[d],x=e.getAggregator([],l),T=x.value(),y=document.createElement("td"),y.className="pvtTotal colTotal",y.textContent=x.format(T),y.setAttribute("data-value",T),null!=c&&(y.onclick=c(T,[],l)),y.setAttribute("data-for","col"+d),S.appendChild(y));(n.table.rowTotals||0===i.length)&&(x=e.getAggregator([],[]),T=x.value(),y=document.createElement("td"),y.className="pvtGrandTotal",y.textContent=x.format(T),y.setAttribute("data-value",T),null!=c&&(y.onclick=c(T,[],[])),S.appendChild(y)),C.appendChild(S)}return f.appendChild(C),f.setAttribute("data-numrows",v.length),f.setAttribute("data-numcols",s.length),f},t.fn.pivot=function(e,n,r){var a,i,s,u,c,h,p,f;null==r&&(r="en"),null==d[r]&&(r="en"),a={cols:[],rows:[],vals:[],rowOrder:"key_a_to_z",colOrder:"key_a_to_z",dataClass:o,filter:function(){return!0},aggregator:l.count()(),aggregatorName:"Count",sorters:{},derivedAttributes:{},renderer:g},u=t.extend(!0,{},d.en.localeStrings,d[r].localeStrings),s={rendererOptions:{localeStrings:u},localeStrings:u},c=t.extend(!0,{},s,t.extend({},a,n)),p=null;try{h=new c.dataClass(e,c);try{p=c.renderer(h,c.rendererOptions)}catch(m){i=m,"undefined"!=typeof console&&null!==console&&console.error(i.stack),p=t("<span>").html(c.localeStrings.renderError)}}catch(m){i=m,"undefined"!=typeof console&&null!==console&&console.error(i.stack),p=t("<span>").html(c.localeStrings.computeError)}for(f=this[0];f.hasChildNodes();)f.removeChild(f.lastChild);return this.append(p)},t.fn.pivotUI=function(n,r,i,l){var s,u,c,p,m,g,v,b,C,y,w,A,x,S,N,T,k,O,_,F,D,E,M,R,I,L,U,K,q,z,V,j,H,B,P,J,G,W,$,Q,Y,X,Z,tt,et;null==i&&(i=!1),null==l&&(l="en"),null==d[l]&&(l="en"),b={derivedAttributes:{},aggregators:d[l].aggregators,renderers:d[l].renderers,hiddenAttributes:[],hiddenFromAggregators:[],hiddenFromDragDrop:[],menuLimit:500,cols:[],rows:[],vals:[],rowOrder:"key_a_to_z",colOrder:"key_a_to_z",dataClass:o,exclusions:{},inclusions:{},unusedAttrsVertical:85,autoSortUnusedAttrs:!1,onRefresh:null,showUI:!0,filter:function(){return!0},sorters:{}},_=t.extend(!0,{},d.en.localeStrings,d[l].localeStrings),O={rendererOptions:{localeStrings:_},localeStrings:_},y=this.data("pivotUIOptions"),M=null==y||i?t.extend(!0,{},O,t.extend({},b,r)):y;try{m={},F=[],L=0,o.forEachRecord(n,M.derivedAttributes,function(t){var e,n,r,o;if(M.filter(t)){F.push(t);for(e in t)a.call(t,e)&&null==m[e]&&(m[e]={},L>0&&(m[e]["null"]=L));for(e in m)o=null!=(r=t[e])?r:"null",null==(n=m[e])[o]&&(n[o]=0),m[e][o]++;return L++}}),Y=t("<table>",{"class":"pvtUi"}).attr("cellpadding",5),B=t("<td>").addClass("pvtUiCell"),H=t("<select>").addClass("pvtRenderer").appendTo(B).bind("change",function(){return V()}),U=M.renderers;for(et in U)a.call(U,et)&&t("<option>").val(et).html(et).appendTo(H);if(X=t("<td>").addClass("pvtAxisContainer pvtUnused pvtUiCell"),J=function(){var t;t=[];for(s in m)e.call(M.hiddenAttributes,s)<0&&t.push(s);return t}(),G=function(){var t,n,r;for(r=[],t=0,n=J.length;t<n;t++)g=J[t],e.call(M.hiddenFromAggregators,g)<0&&r.push(g);return r}(),W=function(){var t,n,r;for(r=[],t=0,n=J.length;t<n;t++)g=J[t],e.call(M.hiddenFromDragDrop,g)<0&&r.push(g);return r}(),tt=!1,Z="auto"===M.unusedAttrsVertical?120:parseInt(M.unusedAttrsVertical),!isNaN(Z)){for(p=0,S=0,N=W.length;S<N;S++)s=W[S],p+=s.length;tt=p>Z}M.unusedAttrsVertical===!0||tt?X.addClass("pvtVertList"):X.addClass("pvtHorizList"),w=function(n){var r,a,o,i,l,s,u,c,d,p,f,g,v,b,C,y,w,x,S;if(S=function(){var t;t=[];for(C in m[n])t.push(C);return t}(),c=!1,x=t("<div>").addClass("pvtFilterBox").hide(),x.append(t("<h4>").append(t("<span>").text(n),t("<span>").addClass("count").text("("+S.length+")"))),S.length>M.menuLimit)x.append(t("<p>").html(M.localeStrings.tooMany));else for(S.length>5&&(i=t("<p>").appendTo(x),v=h(M.sorters,n),f=M.localeStrings.filterResults,t("<input>",{type:"text"}).appendTo(i).attr({placeholder:f,"class":"pvtSearch"}).bind("keyup",function(){var n,r,a;return a=t(this).val().toLowerCase().trim(),r=function(t,n){return function(r){var o,i;return o=a.substring(t.length).trim(),0===o.length||(i=Math.sign(v(r.toLowerCase(),o)),e.call(n,i)>=0)}},n=0===a.indexOf(">=")?r(">=",[1,0]):0===a.indexOf("<=")?r("<=",[-1,0]):0===a.indexOf(">")?r(">",[1]):0===a.indexOf("<")?r("<",[-1]):0===a.indexOf("~")?function(t){return 0===a.substring(1).trim().length||t.toLowerCase().match(a.substring(1))}:function(t){return t.toLowerCase().indexOf(a)!==-1},x.find(".pvtCheckContainer p label span.value").each(function(){return n(t(this).text())?t(this).parent().parent().show():t(this).parent().parent().hide()})}),i.append(t("<br>")),t("<button>",{type:"button"}).appendTo(i).html(M.localeStrings.selectAll).bind("click",function(){return x.find("input:visible:not(:checked)").prop("checked",!0).toggleClass("changed"),!1}),t("<button>",{type:"button"}).appendTo(i).html(M.localeStrings.selectNone).bind("click",function(){return x.find("input:visible:checked").prop("checked",!1).toggleClass("changed"),!1})),a=t("<div>").addClass("pvtCheckContainer").appendTo(x),g=S.sort(h(M.sorters,n)),p=0,d=g.length;p<d;p++)y=g[p],w=m[n][y],l=t("<label>"),s=!1,M.inclusions[n]?s=e.call(M.inclusions[n],y)<0:M.exclusions[n]&&(s=e.call(M.exclusions[n],y)>=0),c||(c=s),t("<input>").attr("type","checkbox").addClass("pvtFilter").attr("checked",!s).data("filter",[n,y]).appendTo(l).bind("change",function(){return t(this).toggleClass("changed")}),l.append(t("<span>").addClass("value").text(y)),l.append(t("<span>").addClass("count").text("("+w+")")),a.append(t("<p>").append(l));return o=function(){return x.find("[type='checkbox']").length>x.find("[type='checkbox']:checked").length?r.addClass("pvtFilteredAttribute"):r.removeClass("pvtFilteredAttribute"),x.find(".pvtSearch").val(""),x.find(".pvtCheckContainer p").show(),x.hide()},u=t("<p>").appendTo(x),S.length<=M.menuLimit&&t("<button>",{type:"button"}).text(M.localeStrings.apply).appendTo(u).bind("click",function(){return x.find(".changed").removeClass("changed").length&&V(),o()}),t("<button>",{type:"button"}).text(M.localeStrings.cancel).appendTo(u).bind("click",function(){return x.find(".changed:checked").removeClass("changed").prop("checked",!1),x.find(".changed:not(:checked)").removeClass("changed").prop("checked",!0),o()}),b=t("<span>").addClass("pvtTriangle").html(" &#x25BE;").bind("click",function(e){var n,r,a;return r=t(e.currentTarget).position(),n=r.left,a=r.top,x.css({left:n+10,top:a+10}).show()}),r=t("<li>").addClass("axis_"+A).append(t("<span>").addClass("pvtAttr").text(n).data("attrName",n).append(b)),c&&r.addClass("pvtFilteredAttribute"),X.append(r).append(x)};for(A in W)a.call(W,A)&&(c=W[A],w(c));$=t("<tr>").appendTo(Y),u=t("<select>").addClass("pvtAggregator").bind("change",function(){return V()}),K=M.aggregators;for(et in K)a.call(K,et)&&u.append(t("<option>").val(et).html(et));for(R={key_a_to_z:{rowSymbol:"&varr;",colSymbol:"&harr;",next:"value_a_to_z"},value_a_to_z:{rowSymbol:"&darr;",colSymbol:"&rarr;",next:"value_z_to_a"},value_z_to_a:{rowSymbol:"&uarr;",colSymbol:"&larr;",next:"key_a_to_z"}},P=t("<a>",{role:"button"}).addClass("pvtRowOrder").data("order",M.rowOrder).html(R[M.rowOrder].rowSymbol).bind("click",function(){return t(this).data("order",R[t(this).data("order")].next),t(this).html(R[t(this).data("order")].rowSymbol),V()}),v=t("<a>",{role:"button"}).addClass("pvtColOrder").data("order",M.colOrder).html(R[M.colOrder].colSymbol).bind("click",function(){return t(this).data("order",R[t(this).data("order")].next),t(this).html(R[t(this).data("order")].colSymbol),V()}),t("<td>").addClass("pvtVals pvtUiCell").appendTo($).append(u).append(P).append(v).append(t("<br>")),t("<td>").addClass("pvtAxisContainer pvtHorizList pvtCols pvtUiCell").appendTo($),Q=t("<tr>").appendTo(Y),Q.append(t("<td>").addClass("pvtAxisContainer pvtRows pvtUiCell").attr("valign","top")),I=t("<td>").attr("valign","top").addClass("pvtRendererArea").appendTo(Q),M.unusedAttrsVertical===!0||tt?(Y.find("tr:nth-child(1)").prepend(B),Y.find("tr:nth-child(2)").prepend(X)):Y.prepend(t("<tr>").append(B).append(X)),this.html(Y),q=M.cols,D=0,T=q.length;D<T;D++)et=q[D],this.find(".pvtCols").append(this.find(".axis_"+t.inArray(et,W)));for(z=M.rows,E=0,k=z.length;E<k;E++)et=z[E],this.find(".pvtRows").append(this.find(".axis_"+t.inArray(et,W)));null!=M.aggregatorName&&this.find(".pvtAggregator").val(M.aggregatorName),null!=M.rendererName&&this.find(".pvtRenderer").val(M.rendererName),M.showUI||this.find(".pvtUiCell").hide(),x=!0,j=function(n){return function(){var r,a,o,i,l,s,h,d,p,m,g,b,C,y;if(m={derivedAttributes:M.derivedAttributes,localeStrings:M.localeStrings,rendererOptions:M.rendererOptions,sorters:M.sorters,cols:[],rows:[],dataClass:M.dataClass},l=null!=(d=M.aggregators[u.val()]([])().numInputs)?d:0,y=[],n.find(".pvtRows li span.pvtAttr").each(function(){return m.rows.push(t(this).data("attrName"))}),n.find(".pvtCols li span.pvtAttr").each(function(){return m.cols.push(t(this).data("attrName"))}),n.find(".pvtVals select.pvtAttrDropdown").each(function(){return 0===l?t(this).remove():(l--,""!==t(this).val()?y.push(t(this).val()):void 0)}),0!==l)for(h=n.find(".pvtVals"),et=g=0,p=l;0<=p?g<p:g>p;et=0<=p?++g:--g){for(i=t("<select>").addClass("pvtAttrDropdown").append(t("<option>")).bind("change",function(){return V()}),b=0,o=G.length;b<o;b++)c=G[b],i.append(t("<option>").val(c).text(c));h.append(i)}if(x&&(y=M.vals,A=0,n.find(".pvtVals select.pvtAttrDropdown").each(function(){return t(this).val(y[A]),A++}),x=!1),m.aggregatorName=u.val(),m.vals=y,m.aggregator=M.aggregators[u.val()](y),m.renderer=M.renderers[H.val()],m.rowOrder=P.data("order"),m.colOrder=v.data("order"),r={},n.find("input.pvtFilter").not(":checked").each(function(){var e;return e=t(this).data("filter"),null!=r[e[0]]?r[e[0]].push(e[1]):r[e[0]]=[e[1]]}),a={},n.find("input.pvtFilter:checked").each(function(){var e;if(e=t(this).data("filter"),null!=r[e[0]])return null!=a[e[0]]?a[e[0]].push(e[1]):a[e[0]]=[e[1]]}),m.filter=function(t){var n,a,o,i;if(!M.filter(t))return!1;for(a in r)if(n=r[a],o=""+(null!=(i=t[a])?i:"null"),e.call(n,o)>=0)return!1;return!0},I.pivot(F,m),s=t.extend({},M,{cols:m.cols,rows:m.rows,colOrder:m.colOrder,rowOrder:m.rowOrder,vals:y,exclusions:r,inclusions:a,inclusionsInfo:a,aggregatorName:u.val(),rendererName:H.val()}),n.data("pivotUIOptions",s),M.autoSortUnusedAttrs&&(C=n.find("td.pvtUnused.pvtAxisContainer"),t(C).children("li").sort(function(e,n){return f(t(e).text(),t(n).text())}).appendTo(C)),I.css("opacity",1),null!=M.onRefresh)return M.onRefresh(s)}}(this),V=function(t){return function(){return I.css("opacity",.5),setTimeout(j,10)}}(this),V(),this.find(".pvtAxisContainer").sortable({update:function(t,e){if(null==e.sender)return V()},connectWith:this.find(".pvtAxisContainer"),items:"li",placeholder:"pvtPlaceholder"})}catch(nt){C=nt,"undefined"!=typeof console&&null!==console&&console.error(C.stack),this.html(M.localeStrings.uiRenderError)}return this},t.fn.heatmap=function(e,n){var r,a,o,i,l,s,u,c,h,d,p;switch(null==e&&(e="heatmap"),c=this.data("numrows"),u=this.data("numcols"),r=null!=n&&null!=(h=n.heatmap)?h.colorScaleGenerator:void 0,null==r&&(r=function(t){var e,n;return n=Math.min.apply(Math,t),e=Math.max.apply(Math,t),function(t){var r;return r=255-Math.round(255*(t-n)/(e-n)),"rgb(255,"+r+","+r+")"}}),a=function(e){return function(n){var a,o,i;return o=function(r){return e.find(n).each(function(){var e;if(e=t(this).data("value"),null!=e&&isFinite(e))return r(e,t(this))})},i=[],o(function(t){return i.push(t)}),a=r(i),o(function(t,e){return e.css("background-color",a(t))})}}(this),e){case"heatmap":a(".pvtVal");break;case"rowheatmap":for(o=l=0,d=c;0<=d?l<d:l>d;o=0<=d?++l:--l)a(".pvtVal.row"+o);break;case"colheatmap":for(i=s=0,p=u;0<=p?s<p:s>p;i=0<=p?++s:--s)a(".pvtVal.col"+i)}return a(".pvtTotal.rowTotal"),a(".pvtTotal.colTotal"),this},t.fn.barchart=function(e){var n,r,a,o,i,l;for(i=this.data("numrows"),o=this.data("numcols"),n=function(e){return function(n){var r,a,o,i,l,s;return r=function(r){return e.find(n).each(function(){var e;if(e=t(this).data("value"),null!=e&&isFinite(e))return r(e,t(this))})},s=[],r(function(t){return s.push(t)}),a=Math.max.apply(Math,s),a<0&&(a=0),i=a,o=Math.min.apply(Math,s),o<0&&(i=a-o),l=function(t){return 100*t/(1.4*i)},r(function(e,n){var r,a,i,s;return i=n.text(),s=t("<div>").css({position:"relative",height:"55px"}),a="gray",r=0,o<0&&(r=l(-o)),e<0&&(r+=l(e),a="darkred",e=-e),s.append(t("<div>").css({position:"absolute",bottom:r+"%",left:0,right:0,height:l(e)+"%","background-color":a})),s.append(t("<div>").text(i).css({position:"relative","padding-left":"5px","padding-right":"5px"})),n.css({padding:0,"padding-top":"5px","text-align":"center"}).html(s)})}}(this),r=a=0,l=i;0<=l?a<l:a>l;r=0<=l?++a:--a)n(".pvtVal.row"+r);return n(".pvtTotal.colTotal"),this}})}).call(this);
 //# sourceMappingURL=pivot.min.js.map
diff --git a/dist/pivot.min.js.map b/dist/pivot.min.js.map
index acf39572..153907ab 100644
--- a/dist/pivot.min.js.map
+++ b/dist/pivot.min.js.map
@@ -1 +1 @@
-{"version":3,"sources":["pivot.coffee","pivot.min.js"],"names":["callWithJQuery","indexOf","item","i","l","this","length","slice","bind","fn","me","apply","arguments","hasProp","hasOwnProperty","pivotModule","exports","module","require","define","amd","jQuery","$","PivotData","addSeparators","aggregatorTemplates","aggregators","dayNamesEn","derivers","getSort","locales","mthNamesEn","naturalSort","numberFormat","pivotTableRenderer","rd","renderers","rx","rz","sortAs","usFmt","usFmtInt","usFmtPct","zeroPad","nStr","thousandsSep","decimalSep","rgx","x","x1","x2","split","test","replace","opts","defaults","digitsAfterDecimal","scaler","prefix","suffix","extend","result","isNaN","isFinite","toFixed","count","formatter","data","rowKey","colKey","push","value","format","uniques","arg","attr","uniq","record","ref","call","numInputs","sum","parseFloat","extremes","mode","val","sorter","sorters","ref1","ref2","Math","quantile","q","vals","sort","a","b","floor","ceil","runningStat","ddof","n","m","s","m_new","sqrt","sumOverSum","denom","num","sumNum","sumDenom","sumOverSumBound80","upper","sign","fractionOf","wrapped","type","selector","total","row","col","inner","getAggregator","countUnique","f","listUnique","join","max","min","first","last","median","average","stdev","tpl","Count","Count Unique Values","List Unique Values","Sum","Integer Sum","Average","Median","Sample Variance","Sample Standard Deviation","Minimum","Maximum","First","Last","Sum over Sum","80% Upper Bound","80% Lower Bound","Sum as Fraction of Total","Sum as Fraction of Rows","Sum as Fraction of Columns","Count as Fraction of Total","Count as Fraction of Rows","Count as Fraction of Columns","Table","Table Barchart","barchart","Heatmap","heatmap","Row Heatmap","Col Heatmap","en","localeStrings","renderError","computeError","uiRenderError","selectAll","selectNone","tooMany","filterResults","cancel","totals","vs","by","number","substr","bin","binWidth","dateFormat","formatString","utcOutput","mthNames","dayNames","utc","date","Date","parse","p","_this","as","bs","a1","b1","nas","nbs","String","match","shift","order","l_mapping","mapping","toLowerCase","isFunction","input","ref3","ref4","ref5","ref6","ref7","ref8","ref9","getRowKeys","getColKeys","sortKeys","arrSort","aggregator","aggregatorName","colAttrs","cols","rowAttrs","rows","valAttrs","rowOrder","colOrder","derivedAttributes","filter","tree","rowKeys","colKeys","rowTotals","colTotals","allTotal","sorted","forEachRecord","processRecord","addRecord","compactRecord","j","k","len1","results","results1","tblCols","isEmptyObject","v","isArray","each","text","Error","prototype","forEachMatchingRecord","criteria","callback","attrs","sortersArr","comparison","r","c","flatColKey","flatRowKey","len2","fromCharCode","agg","pivotUtilities","pivotData","getClickHandler","spanSize","tbody","td","th","thead","totalAggregator","tr","txt","table","clickCallback","rowValues","colValues","filters","e","document","createElement","className","arr","len","noDraw","stop","parseInt","setAttribute","appendChild","textContent","innerHTML","onclick","pivot","inputOpts","locale","localeDefaults","dataClass","renderer","rendererOptions","error","console","stack","html","hasChildNodes","removeChild","lastChild","append","pivotUI","overwrite","attrLength","attrValues","colOrderArrow","existingOpts","fn1","initialRender","len3","materializedInput","o","ordering","pivotTable","recordsProcessed","refresh","refreshDelayed","rendererControl","rowOrderArrow","shownAttributes","shownInAggregators","shownInDragDrop","tr1","tr2","uiTable","unused","unusedAttrsVerticalAutoCutoff","unusedAttrsVerticalAutoOverride","hiddenAttributes","hiddenFromAggregators","hiddenFromDragDrop","menuLimit","exclusions","inclusions","unusedAttrsVertical","autoSortUnusedAttrs","onRefresh","showUI","base","class","addClass","appendTo","attrElem","checkContainer","closeFilterBox","controls","filterItem","filterItemExcluded","finalButtons","hasExcludedItem","placeholder","triangleLink","valueCount","valueList","values","hide","accept","accept_gen","trim","accepted","real_filter","substring","find","parent","show","prop","toggleClass","removeClass","left","top","currentTarget","position","css","key_a_to_z","rowSymbol","colSymbol","next","value_a_to_z","value_z_to_a","role","prepend","inArray","rendererName","len4","newDropdown","numInputsToProcess","pivotUIOptions","pvtVals","subopts","t","u","unusedAttrsContainer","remove","not","excludedItems","inclusionsInfo","children","setTimeout","sortable","update","ui","sender","connectWith","items","scope","colorScaleGenerator","heatmapper","numCols","numRows","nonRed","round","colorScale","forEachCell","elem","barcharter","range","bBase","bgColor","wrapper","height","bottom","right","background-color","padding-left","padding-right","padding","padding-top","text-align"],"mappings":"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","file":"pivot.min.js","sourcesContent":["callWithJQuery = (pivotModule) ->\n    if typeof exports is \"object\" and typeof module is \"object\" # CommonJS\n        pivotModule require(\"jquery\")\n    else if typeof define is \"function\" and define.amd # AMD\n        define [\"jquery\"], pivotModule\n    # Plain browser env\n    else\n        pivotModule jQuery\n\ncallWithJQuery ($) ->\n\n    ###\n    Utilities\n    ###\n\n    addSeparators = (nStr, thousandsSep, decimalSep) ->\n        nStr += ''\n        x = nStr.split('.')\n        x1 = x[0]\n        x2 = if x.length > 1 then  decimalSep + x[1] else ''\n        rgx = /(\\d+)(\\d{3})/\n        x1 = x1.replace(rgx, '$1' + thousandsSep + '$2') while rgx.test(x1)\n        return x1 + x2\n\n    numberFormat = (opts) ->\n        defaults =\n            digitsAfterDecimal: 2, scaler: 1,\n            thousandsSep: \",\", decimalSep: \".\"\n            prefix: \"\", suffix: \"\"\n        opts = $.extend({}, defaults, opts)\n        (x) ->\n            return \"\" if isNaN(x) or not isFinite(x)\n            result = addSeparators (opts.scaler*x).toFixed(opts.digitsAfterDecimal), opts.thousandsSep, opts.decimalSep\n            return \"\"+opts.prefix+result+opts.suffix\n\n    #aggregator templates default to US number formatting but this is overrideable\n    usFmt = numberFormat()\n    usFmtInt = numberFormat(digitsAfterDecimal: 0)\n    usFmtPct = numberFormat(digitsAfterDecimal:1, scaler: 100, suffix: \"%\")\n\n    aggregatorTemplates =\n        count: (formatter=usFmtInt) -> () -> (data, rowKey, colKey) ->\n            count: 0\n            push:  -> @count++\n            value: -> @count\n            format: formatter\n\n        uniques: (fn, formatter=usFmtInt) -> ([attr]) -> (data, rowKey, colKey) ->\n            uniq: []\n            push: (record) -> @uniq.push(record[attr]) if record[attr] not in @uniq\n            value: -> fn(@uniq)\n            format: formatter\n            numInputs: if attr? then 0 else 1\n\n        sum: (formatter=usFmt) -> ([attr]) -> (data, rowKey, colKey) ->\n            sum: 0\n            push: (record) -> @sum += parseFloat(record[attr]) if not isNaN parseFloat(record[attr])\n            value: -> @sum\n            format: formatter\n            numInputs: if attr? then 0 else 1\n\n        extremes: (mode, formatter=usFmt) -> ([attr]) -> (data, rowKey, colKey) ->\n            val: null\n            sorter: getSort(data?.sorters, attr)\n            push: (record) ->\n                x = record[attr]\n                if mode in [\"min\", \"max\"]\n                    x = parseFloat(x)\n                    if not isNaN x then @val = Math[mode](x, @val ? x)\n                if mode == \"first\" then @val = x if @sorter(x, @val ? x) <= 0\n                if mode == \"last\"  then @val = x if @sorter(x, @val ? x) >= 0\n            value: -> @val\n            format: (x) -> if isNaN(x) then x else formatter(x)\n            numInputs: if attr? then 0 else 1\n\n        quantile: (q, formatter=usFmt) -> ([attr]) -> (data, rowKey, colKey) ->\n            vals: []\n            push: (record) ->\n                x = parseFloat(record[attr])\n                @vals.push(x) if not isNaN(x)\n            value: ->\n                return null if @vals.length == 0\n                @vals.sort((a,b) -> a-b)\n                i = (@vals.length-1)*q\n                return (@vals[Math.floor(i)] + @vals[Math.ceil(i)])/2.0\n            format: formatter\n            numInputs: if attr? then 0 else 1\n\n        runningStat: (mode=\"mean\", ddof=1, formatter=usFmt) -> ([attr]) -> (data, rowKey, colKey) ->\n            n: 0.0, m: 0.0, s: 0.0\n            push: (record) ->\n                x = parseFloat(record[attr])\n                return if isNaN(x)\n                @n += 1.0\n                if @n == 1.0\n                    @m = x\n                else\n                    m_new = @m + (x - @m)/@n\n                    @s = @s + (x - @m)*(x - m_new)\n                    @m = m_new\n            value: ->\n                if mode == \"mean\"\n                    return if @n == 0 then 0/0 else @m\n                return 0 if @n <= ddof\n                switch mode\n                    when \"var\"   then @s/(@n-ddof)\n                    when \"stdev\" then Math.sqrt(@s/(@n-ddof))\n            format: formatter\n            numInputs: if attr? then 0 else 1\n\n        sumOverSum: (formatter=usFmt) -> ([num, denom]) -> (data, rowKey, colKey) ->\n            sumNum: 0\n            sumDenom: 0\n            push: (record) ->\n                @sumNum   += parseFloat(record[num])   if not isNaN parseFloat(record[num])\n                @sumDenom += parseFloat(record[denom]) if not isNaN parseFloat(record[denom])\n            value: -> @sumNum/@sumDenom\n            format: formatter\n            numInputs: if num? and denom? then 0 else 2\n\n        sumOverSumBound80: (upper=true, formatter=usFmt) -> ([num, denom]) -> (data, rowKey, colKey) ->\n            sumNum: 0\n            sumDenom: 0\n            push: (record) ->\n                @sumNum   += parseFloat(record[num])   if not isNaN parseFloat(record[num])\n                @sumDenom += parseFloat(record[denom]) if not isNaN parseFloat(record[denom])\n            value: ->\n                sign = if upper then 1 else -1\n                (0.821187207574908/@sumDenom + @sumNum/@sumDenom + 1.2815515655446004*sign*\n                    Math.sqrt(0.410593603787454/ (@sumDenom*@sumDenom) + (@sumNum*(1 - @sumNum/ @sumDenom))/ (@sumDenom*@sumDenom)))/\n                    (1 + 1.642374415149816/@sumDenom)\n            format: formatter\n            numInputs: if num? and denom? then 0 else 2\n\n        fractionOf: (wrapped, type=\"total\", formatter=usFmtPct) -> (x...) -> (data, rowKey, colKey) ->\n            selector: {total:[[],[]],row:[rowKey,[]],col:[[],colKey]}[type]\n            inner: wrapped(x...)(data, rowKey, colKey)\n            push: (record) -> @inner.push record\n            format: formatter\n            value: -> @inner.value() / data.getAggregator(@selector...).inner.value()\n            numInputs: wrapped(x...)().numInputs\n\n    aggregatorTemplates.countUnique = (f) -> aggregatorTemplates.uniques(((x) -> x.length), f)\n    aggregatorTemplates.listUnique =  (s) -> aggregatorTemplates.uniques(((x) -> x.sort(naturalSort).join(s)), ((x)->x))\n    aggregatorTemplates.max =         (f) -> aggregatorTemplates.extremes('max', f)\n    aggregatorTemplates.min =         (f) -> aggregatorTemplates.extremes('min', f)\n    aggregatorTemplates.first =       (f) -> aggregatorTemplates.extremes('first', f)\n    aggregatorTemplates.last =        (f) -> aggregatorTemplates.extremes('last', f)\n    aggregatorTemplates.median =      (f) -> aggregatorTemplates.quantile(0.5, f)\n    aggregatorTemplates.average =     (f) -> aggregatorTemplates.runningStat(\"mean\", 1, f)\n    aggregatorTemplates.var =         (ddof, f) -> aggregatorTemplates.runningStat(\"var\", ddof, f)\n    aggregatorTemplates.stdev =       (ddof, f) -> aggregatorTemplates.runningStat(\"stdev\", ddof, f)\n\n    #default aggregators & renderers use US naming and number formatting\n    aggregators = do (tpl = aggregatorTemplates) ->\n        \"Count\":                tpl.count(usFmtInt)\n        \"Count Unique Values\":  tpl.countUnique(usFmtInt)\n        \"List Unique Values\":   tpl.listUnique(\", \")\n        \"Sum\":                  tpl.sum(usFmt)\n        \"Integer Sum\":          tpl.sum(usFmtInt)\n        \"Average\":              tpl.average(usFmt)\n        \"Median\":               tpl.median(usFmt)\n        \"Sample Variance\":      tpl.var(1, usFmt)\n        \"Sample Standard Deviation\": tpl.stdev(1, usFmt)\n        \"Minimum\":              tpl.min(usFmt)\n        \"Maximum\":              tpl.max(usFmt)\n        \"First\":                tpl.first(usFmt)\n        \"Last\":                 tpl.last(usFmt)\n        \"Sum over Sum\":         tpl.sumOverSum(usFmt)\n        \"80% Upper Bound\":      tpl.sumOverSumBound80(true, usFmt)\n        \"80% Lower Bound\":      tpl.sumOverSumBound80(false, usFmt)\n        \"Sum as Fraction of Total\":     tpl.fractionOf(tpl.sum(),   \"total\", usFmtPct)\n        \"Sum as Fraction of Rows\":      tpl.fractionOf(tpl.sum(),   \"row\",   usFmtPct)\n        \"Sum as Fraction of Columns\":   tpl.fractionOf(tpl.sum(),   \"col\",   usFmtPct)\n        \"Count as Fraction of Total\":   tpl.fractionOf(tpl.count(), \"total\", usFmtPct)\n        \"Count as Fraction of Rows\":    tpl.fractionOf(tpl.count(), \"row\",   usFmtPct)\n        \"Count as Fraction of Columns\": tpl.fractionOf(tpl.count(), \"col\",   usFmtPct)\n\n    renderers =\n        \"Table\":          (data, opts) ->   pivotTableRenderer(data, opts)\n        \"Table Barchart\": (data, opts) -> $(pivotTableRenderer(data, opts)).barchart()\n        \"Heatmap\":        (data, opts) -> $(pivotTableRenderer(data, opts)).heatmap(\"heatmap\",    opts)\n        \"Row Heatmap\":    (data, opts) -> $(pivotTableRenderer(data, opts)).heatmap(\"rowheatmap\", opts)\n        \"Col Heatmap\":    (data, opts) -> $(pivotTableRenderer(data, opts)).heatmap(\"colheatmap\", opts)\n\n    locales =\n        en:\n            aggregators: aggregators\n            renderers: renderers\n            localeStrings:\n                renderError: \"An error occurred rendering the PivotTable results.\"\n                computeError: \"An error occurred computing the PivotTable results.\"\n                uiRenderError: \"An error occurred rendering the PivotTable UI.\"\n                selectAll: \"Select All\"\n                selectNone: \"Select None\"\n                tooMany: \"(too many to list)\"\n                filterResults: \"Filter values\"\n                apply: \"Apply\"\n                cancel: \"Cancel\"\n                totals: \"Totals\" #for table renderer\n                vs: \"vs\" #for gchart renderer\n                by: \"by\" #for gchart renderer\n\n    #dateFormat deriver l10n requires month and day names to be passed in directly\n    mthNamesEn = [\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"]\n    dayNamesEn = [\"Sun\",\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\"]\n    zeroPad = (number) -> (\"0\"+number).substr(-2,2)\n\n    derivers =\n        bin: (col, binWidth) -> (record) -> record[col] - record[col] % binWidth\n        dateFormat: (col, formatString, utcOutput=false, mthNames=mthNamesEn, dayNames=dayNamesEn) ->\n            utc = if utcOutput then \"UTC\" else \"\"\n            (record) -> #thanks http://stackoverflow.com/a/12213072/112871\n                date = new Date(Date.parse(record[col]))\n                if isNaN(date) then return \"\"\n                formatString.replace /%(.)/g, (m, p) ->\n                    switch p\n                        when \"y\" then date[\"get#{utc}FullYear\"]()\n                        when \"m\" then zeroPad(date[\"get#{utc}Month\"]()+1)\n                        when \"n\" then mthNames[date[\"get#{utc}Month\"]()]\n                        when \"d\" then zeroPad(date[\"get#{utc}Date\"]())\n                        when \"w\" then dayNames[date[\"get#{utc}Day\"]()]\n                        when \"x\" then date[\"get#{utc}Day\"]()\n                        when \"H\" then zeroPad(date[\"get#{utc}Hours\"]())\n                        when \"M\" then zeroPad(date[\"get#{utc}Minutes\"]())\n                        when \"S\" then zeroPad(date[\"get#{utc}Seconds\"]())\n                        else \"%\" + p\n\n    rx = /(\\d+)|(\\D+)/g\n    rd = /\\d/\n    rz = /^0/\n    naturalSort = (as, bs) =>\n        #nulls first\n        return -1 if bs? and not as?\n        return  1 if as? and not bs?\n\n        #then raw NaNs\n        return -1 if typeof as == \"number\" and isNaN(as)\n        return  1 if typeof bs == \"number\" and isNaN(bs)\n\n        #numbers and numbery strings group together\n        nas = +as\n        nbs = +bs\n        return -1 if nas < nbs\n        return  1 if nas > nbs\n\n        #within that, true numbers before numbery strings\n        return -1 if typeof as == \"number\" and typeof bs != \"number\"\n        return  1 if typeof bs == \"number\" and typeof as != \"number\"\n        return  0 if typeof as == \"number\" and typeof bs == \"number\"\n\n        # 'Infinity' is a textual number, so less than 'A'\n        return -1 if isNaN(nbs) and not isNaN(nas)\n        return  1 if isNaN(nas) and not isNaN(nbs)\n\n        #finally, \"smart\" string sorting per http://stackoverflow.com/a/4373421/112871\n        a = String(as)\n        b = String(bs)\n        return 0 if a == b\n        return (if a > b then 1 else -1) unless rd.test(a) and rd.test(b)\n\n        #special treatment for strings containing digits\n        a = a.match(rx) #create digits vs non-digit chunks and iterate through\n        b = b.match(rx)\n        while a.length and b.length\n            a1 = a.shift()\n            b1 = b.shift()\n            if a1 != b1\n                if rd.test(a1) and rd.test(b1) #both are digit chunks\n                    return a1.replace(rz, \".0\") - b1.replace(rz, \".0\")\n                else\n                    return (if a1 > b1 then 1 else -1)\n        return a.length - b.length\n\n    sortAs = (order) ->\n        mapping = {}\n        l_mapping = {} # sort lowercased keys similarly\n        for i, x of order\n            mapping[x] = i\n            l_mapping[x.toLowerCase()] = i if typeof x == \"string\"\n        (a, b) ->\n            if mapping[a]? and mapping[b]? then mapping[a] - mapping[b]\n            else if mapping[a]? then -1\n            else if mapping[b]? then 1\n            else if l_mapping[a]? and l_mapping[b]? then l_mapping[a] - l_mapping[b]\n            else if l_mapping[a]? then -1\n            else if l_mapping[b]? then 1\n            else naturalSort(a,b)\n\n    getSort = (sorters, attr) ->\n        if sorters?\n            if $.isFunction(sorters)\n                sort = sorters(attr)\n                return sort if $.isFunction(sort)\n            else if sorters[attr]?\n                return sorters[attr]\n        return naturalSort\n\n    ###\n    Data Model class\n    ###\n\n    class PivotData\n        constructor: (input, opts = {}) ->\n            @input = input\n            @aggregator = opts.aggregator ? aggregatorTemplates.count()()\n            @aggregatorName = opts.aggregatorName ? \"Count\"\n            @colAttrs = opts.cols ? []\n            @rowAttrs = opts.rows ? []\n            @valAttrs = opts.vals ? []\n            @sorters = opts.sorters ? {}\n            @rowOrder = opts.rowOrder ? \"key_a_to_z\"\n            @colOrder = opts.colOrder ? \"key_a_to_z\"\n            @derivedAttributes = opts.derivedAttributes ? {}\n            @filter = opts.filter ? (-> true)\n            @tree = {}\n            @rowKeys = []\n            @colKeys = []\n            @rowTotals = {}\n            @colTotals = {}\n            @allTotal = @aggregator(this, [], [])\n            @sorted = false\n\n            # iterate through input, accumulating data for cells\n            PivotData.forEachRecord @input, @derivedAttributes, (record) =>\n                @processRecord(record) if @filter(record)\n\n        #can handle arrays or jQuery selections of tables\n        @forEachRecord = (input, derivedAttributes, f) ->\n            if $.isEmptyObject derivedAttributes\n                addRecord = f\n            else\n                addRecord = (record) ->\n                    record[k] = v(record) ? record[k] for k, v of derivedAttributes\n                    f(record)\n\n            #if it's a function, have it call us back\n            if $.isFunction(input)\n                input(addRecord)\n            else if $.isArray(input)\n                if $.isArray(input[0]) #array of arrays\n                    for own i, compactRecord of input when i > 0\n                        record = {}\n                        record[k] = compactRecord[j] for own j, k of input[0]\n                        addRecord(record)\n                else #array of objects\n                    addRecord(record) for record in input\n            else if input instanceof $\n                tblCols = []\n                $(\"thead > tr > th\", input).each (i) -> tblCols.push $(this).text()\n                $(\"tbody > tr\", input).each (i) ->\n                    record = {}\n                    $(\"td\", this).each (j) -> record[tblCols[j]] = $(this).text()\n                    addRecord(record)\n            else\n                throw new Error(\"unknown input format\")\n\n        forEachMatchingRecord: (criteria, callback) ->\n            PivotData.forEachRecord @input, @derivedAttributes, (record) =>\n                return if not @filter(record)\n                for k, v of criteria\n                    return if v != (record[k] ? \"null\")\n                callback(record)\n\n        arrSort: (attrs) =>\n            sortersArr = (getSort(@sorters, a) for a in attrs)\n            (a,b) ->\n                for own i, sorter of sortersArr\n                    comparison = sorter(a[i], b[i])\n                    return comparison if comparison != 0\n                return 0\n\n        sortKeys: () =>\n            if not @sorted\n                @sorted = true\n                v = (r,c) => @getAggregator(r,c).value()\n                switch @rowOrder\n                    when \"value_a_to_z\"  then @rowKeys.sort (a,b) =>  naturalSort v(a,[]), v(b,[])\n                    when \"value_z_to_a\" then @rowKeys.sort (a,b) => -naturalSort v(a,[]), v(b,[])\n                    else             @rowKeys.sort @arrSort(@rowAttrs)\n                switch @colOrder\n                    when \"value_a_to_z\"  then @colKeys.sort (a,b) =>  naturalSort v([],a), v([],b)\n                    when \"value_z_to_a\" then @colKeys.sort (a,b) => -naturalSort v([],a), v([],b)\n                    else             @colKeys.sort @arrSort(@colAttrs)\n\n        getColKeys: () =>\n            @sortKeys()\n            return @colKeys\n\n        getRowKeys: () =>\n            @sortKeys()\n            return @rowKeys\n\n        processRecord: (record) -> #this code is called in a tight loop\n            colKey = []\n            rowKey = []\n            colKey.push record[x] ? \"null\" for x in @colAttrs\n            rowKey.push record[x] ? \"null\" for x in @rowAttrs\n            flatRowKey = rowKey.join(String.fromCharCode(0))\n            flatColKey = colKey.join(String.fromCharCode(0))\n\n            @allTotal.push record\n\n            if rowKey.length != 0\n                if not @rowTotals[flatRowKey]\n                    @rowKeys.push rowKey\n                    @rowTotals[flatRowKey] = @aggregator(this, rowKey, [])\n                @rowTotals[flatRowKey].push record\n\n            if colKey.length != 0\n                if not @colTotals[flatColKey]\n                    @colKeys.push colKey\n                    @colTotals[flatColKey] = @aggregator(this, [], colKey)\n                @colTotals[flatColKey].push record\n\n            if colKey.length != 0 and rowKey.length != 0\n                if not @tree[flatRowKey]\n                    @tree[flatRowKey] = {}\n                if not @tree[flatRowKey][flatColKey]\n                    @tree[flatRowKey][flatColKey] = @aggregator(this, rowKey, colKey)\n                @tree[flatRowKey][flatColKey].push record\n\n        getAggregator: (rowKey, colKey) =>\n            flatRowKey = rowKey.join(String.fromCharCode(0))\n            flatColKey = colKey.join(String.fromCharCode(0))\n            if rowKey.length == 0 and colKey.length == 0\n                agg = @allTotal\n            else if rowKey.length == 0\n                agg = @colTotals[flatColKey]\n            else if colKey.length == 0\n                agg = @rowTotals[flatRowKey]\n            else\n                agg = @tree[flatRowKey][flatColKey]\n            return agg ? {value: (-> null), format: -> \"\"}\n\n    #expose these to the outside world\n    $.pivotUtilities = {aggregatorTemplates, aggregators, renderers, derivers, locales,\n        naturalSort, numberFormat, sortAs, PivotData}\n\n    ###\n    Default Renderer for hierarchical table layout\n    ###\n\n    pivotTableRenderer = (pivotData, opts) ->\n\n        defaults =\n            table:\n                clickCallback: null\n                rowTotals: true\n                colTotals: true\n            localeStrings: totals: \"Totals\"\n\n        opts = $.extend(true, {}, defaults, opts)\n\n        colAttrs = pivotData.colAttrs\n        rowAttrs = pivotData.rowAttrs\n        rowKeys = pivotData.getRowKeys()\n        colKeys = pivotData.getColKeys()\n\n        if opts.table.clickCallback\n            getClickHandler = (value, rowValues, colValues) ->\n                filters = {}\n                filters[attr] = colValues[i] for own i, attr of colAttrs when colValues[i]?\n                filters[attr] = rowValues[i] for own i, attr of rowAttrs when rowValues[i]?\n                return (e) -> opts.table.clickCallback(e, value, filters, pivotData)\n\n        #now actually build the output\n        result = document.createElement(\"table\")\n        result.className = \"pvtTable\"\n\n        #helper function for setting row/col-span in pivotTableRenderer\n        spanSize = (arr, i, j) ->\n            if i != 0\n                noDraw = true\n                for x in [0..j]\n                    if arr[i-1][x] != arr[i][x]\n                        noDraw = false\n                if noDraw\n                  return -1 #do not draw cell\n            len = 0\n            while i+len < arr.length\n                stop = false\n                for x in [0..j]\n                    stop = true if arr[i][x] != arr[i+len][x]\n                break if stop\n                len++\n            return len\n\n        #the first few rows are for col headers\n        thead = document.createElement(\"thead\")\n        for own j, c of colAttrs\n            tr = document.createElement(\"tr\")\n            if parseInt(j) == 0 and rowAttrs.length != 0\n                th = document.createElement(\"th\")\n                th.setAttribute(\"colspan\", rowAttrs.length)\n                th.setAttribute(\"rowspan\", colAttrs.length)\n                tr.appendChild th\n            th = document.createElement(\"th\")\n            th.className = \"pvtAxisLabel\"\n            th.textContent = c\n            tr.appendChild th\n            for own i, colKey of colKeys\n                x = spanSize(colKeys, parseInt(i), parseInt(j))\n                if x != -1\n                    th = document.createElement(\"th\")\n                    th.className = \"pvtColLabel\"\n                    th.textContent = colKey[j]\n                    th.setAttribute(\"colspan\", x)\n                    if parseInt(j) == colAttrs.length-1 and rowAttrs.length != 0\n                        th.setAttribute(\"rowspan\", 2)\n                    tr.appendChild th\n            if parseInt(j) == 0 && opts.table.rowTotals\n                th = document.createElement(\"th\")\n                th.className = \"pvtTotalLabel pvtRowTotalLabel\"\n                th.innerHTML = opts.localeStrings.totals\n                th.setAttribute(\"rowspan\", colAttrs.length + (if rowAttrs.length ==0 then 0 else 1))\n                tr.appendChild th\n            thead.appendChild tr\n\n        #then a row for row header headers\n        if rowAttrs.length !=0\n            tr = document.createElement(\"tr\")\n            for own i, r of rowAttrs\n                th = document.createElement(\"th\")\n                th.className = \"pvtAxisLabel\"\n                th.textContent = r\n                tr.appendChild th\n            th = document.createElement(\"th\")\n            if colAttrs.length ==0\n                th.className = \"pvtTotalLabel pvtRowTotalLabel\"\n                th.innerHTML = opts.localeStrings.totals\n            tr.appendChild th\n            thead.appendChild tr\n        result.appendChild thead\n\n        #now the actual data rows, with their row headers and totals\n        tbody = document.createElement(\"tbody\")\n        for own i, rowKey of rowKeys\n            tr = document.createElement(\"tr\")\n            for own j, txt of rowKey\n                x = spanSize(rowKeys, parseInt(i), parseInt(j))\n                if x != -1\n                    th = document.createElement(\"th\")\n                    th.className = \"pvtRowLabel\"\n                    th.textContent = txt\n                    th.setAttribute(\"rowspan\", x)\n                    if parseInt(j) == rowAttrs.length-1 and colAttrs.length !=0\n                        th.setAttribute(\"colspan\",2)\n                    tr.appendChild th\n            for own j, colKey of colKeys #this is the tight loop\n                aggregator = pivotData.getAggregator(rowKey, colKey)\n                val = aggregator.value()\n                td = document.createElement(\"td\")\n                td.className = \"pvtVal row#{i} col#{j}\"\n                td.textContent = aggregator.format(val)\n                td.setAttribute(\"data-value\", val)\n                if getClickHandler?\n                    td.onclick = getClickHandler(val, rowKey, colKey)\n                tr.appendChild td\n\n            if opts.table.rowTotals || colAttrs.length == 0\n                totalAggregator = pivotData.getAggregator(rowKey, [])\n                val = totalAggregator.value()\n                td = document.createElement(\"td\")\n                td.className = \"pvtTotal rowTotal\"\n                td.textContent = totalAggregator.format(val)\n                td.setAttribute(\"data-value\", val)\n                if getClickHandler?\n                    td.onclick = getClickHandler(val, rowKey, [])\n                td.setAttribute(\"data-for\", \"row\"+i)\n                tr.appendChild td\n            tbody.appendChild tr\n\n        #finally, the row for col totals, and a grand total\n        if opts.table.colTotals || rowAttrs.length == 0\n            tr = document.createElement(\"tr\")\n            if opts.table.colTotals || rowAttrs.length == 0\n                th = document.createElement(\"th\")\n                th.className = \"pvtTotalLabel pvtColTotalLabel\"\n                th.innerHTML = opts.localeStrings.totals\n                th.setAttribute(\"colspan\", rowAttrs.length + (if colAttrs.length == 0 then 0 else 1))\n                tr.appendChild th\n            for own j, colKey of colKeys\n                totalAggregator = pivotData.getAggregator([], colKey)\n                val = totalAggregator.value()\n                td = document.createElement(\"td\")\n                td.className = \"pvtTotal colTotal\"\n                td.textContent = totalAggregator.format(val)\n                td.setAttribute(\"data-value\", val)\n                if getClickHandler?\n                    td.onclick = getClickHandler(val, [], colKey)\n                td.setAttribute(\"data-for\", \"col\"+j)\n                tr.appendChild td\n            if opts.table.rowTotals || colAttrs.length == 0\n                totalAggregator = pivotData.getAggregator([], [])\n                val = totalAggregator.value()\n                td = document.createElement(\"td\")\n                td.className = \"pvtGrandTotal\"\n                td.textContent = totalAggregator.format(val)\n                td.setAttribute(\"data-value\", val)\n                if getClickHandler?\n                    td.onclick = getClickHandler(val, [], [])\n                tr.appendChild td\n            tbody.appendChild tr\n        result.appendChild tbody\n\n        #squirrel this away for later\n        result.setAttribute(\"data-numrows\", rowKeys.length)\n        result.setAttribute(\"data-numcols\", colKeys.length)\n\n        return result\n\n    ###\n    Pivot Table core: create PivotData object and call Renderer on it\n    ###\n\n    $.fn.pivot = (input, inputOpts, locale=\"en\") ->\n        locale = \"en\" if not locales[locale]?\n        defaults =\n            cols : [], rows: [], vals: []\n            rowOrder: \"key_a_to_z\", colOrder: \"key_a_to_z\"\n            dataClass: PivotData\n            filter: -> true\n            aggregator: aggregatorTemplates.count()()\n            aggregatorName: \"Count\"\n            sorters: {}\n            derivedAttributes: {}\n            renderer: pivotTableRenderer\n\n        localeStrings = $.extend(true, {}, locales.en.localeStrings, locales[locale].localeStrings)\n        localeDefaults =\n            rendererOptions: {localeStrings}\n            localeStrings: localeStrings\n\n        opts = $.extend(true, {}, localeDefaults, $.extend({}, defaults, inputOpts))\n\n        result = null\n        try\n            pivotData = new opts.dataClass(input, opts)\n            try\n                result = opts.renderer(pivotData, opts.rendererOptions)\n            catch e\n                console.error(e.stack) if console?\n                result = $(\"<span>\").html opts.localeStrings.renderError\n        catch e\n            console.error(e.stack) if console?\n            result = $(\"<span>\").html opts.localeStrings.computeError\n\n        x = this[0]\n        x.removeChild(x.lastChild) while x.hasChildNodes()\n        return @append result\n\n\n    ###\n    Pivot Table UI: calls Pivot Table core above with options set by user\n    ###\n\n    $.fn.pivotUI = (input, inputOpts, overwrite = false, locale=\"en\") ->\n        locale = \"en\" if not locales[locale]?\n        defaults =\n            derivedAttributes: {}\n            aggregators: locales[locale].aggregators\n            renderers: locales[locale].renderers\n            hiddenAttributes: []\n            hiddenFromAggregators: []\n            hiddenFromDragDrop: []\n            menuLimit: 500\n            cols: [], rows: [], vals: []\n            rowOrder: \"key_a_to_z\", colOrder: \"key_a_to_z\"\n            dataClass: PivotData\n            exclusions: {}\n            inclusions: {}\n            unusedAttrsVertical: 85\n            autoSortUnusedAttrs: false\n            onRefresh: null\n            showUI: true\n            filter: -> true\n            sorters: {}\n\n        localeStrings = $.extend(true, {}, locales.en.localeStrings, locales[locale].localeStrings)\n        localeDefaults =\n            rendererOptions: {localeStrings}\n            localeStrings: localeStrings\n\n        existingOpts = @data \"pivotUIOptions\"\n        if not existingOpts? or overwrite\n            opts = $.extend(true, {}, localeDefaults, $.extend({}, defaults, inputOpts))\n        else\n            opts = existingOpts\n\n        try\n            # do a first pass on the data to cache a materialized copy of any\n            # function-valued inputs and to compute dimension cardinalities\n            attrValues = {}\n            materializedInput = []\n            recordsProcessed = 0\n            PivotData.forEachRecord input, opts.derivedAttributes, (record) ->\n                return unless opts.filter(record)\n                materializedInput.push(record)\n                for own attr of record\n                    if not attrValues[attr]?\n                        attrValues[attr] = {}\n                        if recordsProcessed > 0\n                            attrValues[attr][\"null\"] = recordsProcessed\n                for attr of attrValues\n                    value = record[attr] ? \"null\"\n                    attrValues[attr][value] ?= 0\n                    attrValues[attr][value]++\n                recordsProcessed++\n\n            #start building the output\n            uiTable = $(\"<table>\", \"class\": \"pvtUi\").attr(\"cellpadding\", 5)\n\n            #renderer control\n            rendererControl = $(\"<td>\").addClass(\"pvtUiCell\")\n\n            renderer = $(\"<select>\")\n                .addClass('pvtRenderer')\n                .appendTo(rendererControl)\n                .bind \"change\", -> refresh() #capture reference\n            for own x of opts.renderers\n                $(\"<option>\").val(x).html(x).appendTo(renderer)\n\n\n            #axis list, including the double-click menu\n            unused = $(\"<td>\").addClass('pvtAxisContainer pvtUnused pvtUiCell')\n            shownAttributes = (a for a of attrValues when a not in opts.hiddenAttributes)\n            shownInAggregators = (c for c in shownAttributes when c not in opts.hiddenFromAggregators)\n            shownInDragDrop = (c for c in shownAttributes when c not in opts.hiddenFromDragDrop)\n\n\n            unusedAttrsVerticalAutoOverride = false\n            if opts.unusedAttrsVertical == \"auto\"\n                unusedAttrsVerticalAutoCutoff = 120 # legacy support\n            else\n                unusedAttrsVerticalAutoCutoff = parseInt opts.unusedAttrsVertical\n\n            if not isNaN(unusedAttrsVerticalAutoCutoff)\n                attrLength = 0\n                attrLength += a.length for a in shownInDragDrop\n                unusedAttrsVerticalAutoOverride = attrLength > unusedAttrsVerticalAutoCutoff\n\n            if opts.unusedAttrsVertical == true or unusedAttrsVerticalAutoOverride\n                unused.addClass('pvtVertList')\n            else\n                unused.addClass('pvtHorizList')\n\n            for own i, attr of shownInDragDrop\n                do (attr) ->\n                    values = (v for v of attrValues[attr])\n                    hasExcludedItem = false\n                    valueList = $(\"<div>\").addClass('pvtFilterBox').hide()\n\n                    valueList.append $(\"<h4>\").append(\n                        $(\"<span>\").text(attr),\n                        $(\"<span>\").addClass(\"count\").text(\"(#{values.length})\"),\n                        )\n                    if values.length > opts.menuLimit\n                        valueList.append $(\"<p>\").html(opts.localeStrings.tooMany)\n                    else\n                        if values.length > 5\n                            controls = $(\"<p>\").appendTo(valueList)\n                            sorter = getSort(opts.sorters, attr)\n                            placeholder = opts.localeStrings.filterResults\n                            $(\"<input>\", {type: \"text\"}).appendTo(controls)\n                                .attr({placeholder: placeholder, class: \"pvtSearch\"})\n                                .bind \"keyup\", ->\n                                    filter = $(this).val().toLowerCase().trim()\n                                    accept_gen = (prefix, accepted) -> (v) ->\n                                        real_filter = filter.substring(prefix.length).trim()\n                                        return true if real_filter.length == 0\n                                        return Math.sign(sorter(v.toLowerCase(), real_filter)) in accepted\n                                    accept =\n                                        if      filter.indexOf(\">=\") == 0 then accept_gen(\">=\", [1,0])\n                                        else if filter.indexOf(\"<=\") == 0 then accept_gen(\"<=\", [-1,0])\n                                        else if filter.indexOf(\">\") == 0  then accept_gen(\">\",  [1])\n                                        else if filter.indexOf(\"<\") == 0  then accept_gen(\"<\",  [-1])\n                                        else if filter.indexOf(\"~\") == 0  then (v) ->\n                                                return true if filter.substring(1).trim().length == 0\n                                                v.toLowerCase().match(filter.substring(1))\n                                        else (v) -> v.toLowerCase().indexOf(filter) != -1\n\n                                    valueList.find('.pvtCheckContainer p label span.value').each ->\n                                        if accept($(this).text())\n                                            $(this).parent().parent().show()\n                                        else\n                                            $(this).parent().parent().hide()\n                            controls.append $(\"<br>\")\n                            $(\"<button>\", {type:\"button\"}).appendTo(controls)\n                                .html(opts.localeStrings.selectAll)\n                                .bind \"click\", ->\n                                    valueList.find(\"input:visible:not(:checked)\")\n                                        .prop(\"checked\", true).toggleClass(\"changed\")\n                                    return false\n                            $(\"<button>\", {type:\"button\"}).appendTo(controls)\n                                .html(opts.localeStrings.selectNone)\n                                .bind \"click\", ->\n                                    valueList.find(\"input:visible:checked\")\n                                        .prop(\"checked\", false).toggleClass(\"changed\")\n                                    return false\n\n                        checkContainer = $(\"<div>\").addClass(\"pvtCheckContainer\").appendTo(valueList)\n\n                        for value in values.sort(getSort(opts.sorters, attr))\n                             valueCount = attrValues[attr][value]\n                             filterItem = $(\"<label>\")\n                             filterItemExcluded = false\n                             if opts.inclusions[attr]\n                                filterItemExcluded = (value not in opts.inclusions[attr])\n                             else if opts.exclusions[attr]\n                                filterItemExcluded = (value in opts.exclusions[attr])\n                             hasExcludedItem ||= filterItemExcluded\n                             $(\"<input>\")\n                                .attr(\"type\", \"checkbox\").addClass('pvtFilter')\n                                .attr(\"checked\", !filterItemExcluded).data(\"filter\", [attr,value])\n                                .appendTo(filterItem)\n                                .bind \"change\", -> $(this).toggleClass(\"changed\")\n                             filterItem.append $(\"<span>\").addClass(\"value\").text(value)\n                             filterItem.append $(\"<span>\").addClass(\"count\").text(\"(\"+valueCount+\")\")\n                             checkContainer.append $(\"<p>\").append(filterItem)\n\n                    closeFilterBox = ->\n                        if valueList.find(\"[type='checkbox']\").length >\n                               valueList.find(\"[type='checkbox']:checked\").length\n                                attrElem.addClass \"pvtFilteredAttribute\"\n                            else\n                                attrElem.removeClass \"pvtFilteredAttribute\"\n\n                            valueList.find('.pvtSearch').val('')\n                            valueList.find('.pvtCheckContainer p').show()\n                            valueList.hide()\n\n                    finalButtons = $(\"<p>\").appendTo(valueList)\n\n                    if values.length <= opts.menuLimit\n                        $(\"<button>\", {type: \"button\"}).text(opts.localeStrings.apply)\n                            .appendTo(finalButtons).bind \"click\", ->\n                                if valueList.find(\".changed\").removeClass(\"changed\").length\n                                    refresh()\n                                closeFilterBox()\n\n                    $(\"<button>\", {type: \"button\"}).text(opts.localeStrings.cancel)\n                        .appendTo(finalButtons).bind \"click\", ->\n                            valueList.find(\".changed:checked\")\n                                .removeClass(\"changed\").prop(\"checked\", false)\n                            valueList.find(\".changed:not(:checked)\")\n                                .removeClass(\"changed\").prop(\"checked\", true)\n                            closeFilterBox()\n\n                    triangleLink = $(\"<span>\").addClass('pvtTriangle')\n                        .html(\" &#x25BE;\").bind \"click\", (e) ->\n                            {left, top} = $(e.currentTarget).position()\n                            valueList.css(left: left+10, top: top+10).show()\n\n                    attrElem = $(\"<li>\").addClass(\"axis_#{i}\")\n                        .append $(\"<span>\").addClass('pvtAttr').text(attr).data(\"attrName\", attr).append(triangleLink)\n\n                    attrElem.addClass('pvtFilteredAttribute') if hasExcludedItem\n                    unused.append(attrElem).append(valueList)\n\n            tr1 = $(\"<tr>\").appendTo(uiTable)\n\n            #aggregator menu and value area\n\n            aggregator = $(\"<select>\").addClass('pvtAggregator')\n                .bind \"change\", -> refresh() #capture reference\n            for own x of opts.aggregators\n                aggregator.append $(\"<option>\").val(x).html(x)\n\n            ordering =\n                key_a_to_z:   {rowSymbol: \"&varr;\", colSymbol: \"&harr;\", next: \"value_a_to_z\"}\n                value_a_to_z: {rowSymbol: \"&darr;\", colSymbol: \"&rarr;\", next: \"value_z_to_a\"}\n                value_z_to_a: {rowSymbol: \"&uarr;\", colSymbol: \"&larr;\", next: \"key_a_to_z\"}\n\n            rowOrderArrow = $(\"<a>\", role: \"button\").addClass(\"pvtRowOrder\")\n                .data(\"order\", opts.rowOrder).html(ordering[opts.rowOrder].rowSymbol)\n                .bind \"click\", ->\n                    $(this).data(\"order\", ordering[$(this).data(\"order\")].next)\n                    $(this).html(ordering[$(this).data(\"order\")].rowSymbol)\n                    refresh()\n\n            colOrderArrow = $(\"<a>\", role: \"button\").addClass(\"pvtColOrder\")\n                .data(\"order\", opts.colOrder).html(ordering[opts.colOrder].colSymbol)\n                .bind \"click\", ->\n                    $(this).data(\"order\", ordering[$(this).data(\"order\")].next)\n                    $(this).html(ordering[$(this).data(\"order\")].colSymbol)\n                    refresh()\n\n            $(\"<td>\").addClass('pvtVals pvtUiCell')\n              .appendTo(tr1)\n              .append(aggregator)\n              .append(rowOrderArrow)\n              .append(colOrderArrow)\n              .append($(\"<br>\"))\n\n            #column axes\n            $(\"<td>\").addClass('pvtAxisContainer pvtHorizList pvtCols pvtUiCell').appendTo(tr1)\n\n            tr2 = $(\"<tr>\").appendTo(uiTable)\n\n            #row axes\n            tr2.append $(\"<td>\").addClass('pvtAxisContainer pvtRows pvtUiCell').attr(\"valign\", \"top\")\n\n            #the actual pivot table container\n            pivotTable = $(\"<td>\")\n                .attr(\"valign\", \"top\")\n                .addClass('pvtRendererArea')\n                .appendTo(tr2)\n\n            #finally the renderer dropdown and unused attribs are inserted at the requested location\n            if opts.unusedAttrsVertical == true or unusedAttrsVerticalAutoOverride\n                uiTable.find('tr:nth-child(1)').prepend rendererControl\n                uiTable.find('tr:nth-child(2)').prepend unused\n            else\n                uiTable.prepend $(\"<tr>\").append(rendererControl).append(unused)\n\n            #render the UI in its default state\n            @html uiTable\n\n            #set up the UI initial state as requested by moving elements around\n\n            for x in opts.cols\n                @find(\".pvtCols\").append @find(\".axis_#{$.inArray(x, shownInDragDrop)}\")\n            for x in opts.rows\n                @find(\".pvtRows\").append @find(\".axis_#{$.inArray(x, shownInDragDrop)}\")\n            if opts.aggregatorName?\n                @find(\".pvtAggregator\").val opts.aggregatorName\n            if opts.rendererName?\n                @find(\".pvtRenderer\").val opts.rendererName\n\n            @find(\".pvtUiCell\").hide() unless opts.showUI\n\n            initialRender = true\n\n            #set up for refreshing\n            refreshDelayed = =>\n                subopts =\n                    derivedAttributes: opts.derivedAttributes\n                    localeStrings: opts.localeStrings\n                    rendererOptions: opts.rendererOptions\n                    sorters: opts.sorters\n                    cols: [], rows: []\n                    dataClass: opts.dataClass\n\n                numInputsToProcess = opts.aggregators[aggregator.val()]([])().numInputs ? 0\n                vals = []\n                @find(\".pvtRows li span.pvtAttr\").each -> subopts.rows.push $(this).data(\"attrName\")\n                @find(\".pvtCols li span.pvtAttr\").each -> subopts.cols.push $(this).data(\"attrName\")\n                @find(\".pvtVals select.pvtAttrDropdown\").each ->\n                    if numInputsToProcess == 0\n                        $(this).remove()\n                    else\n                        numInputsToProcess--\n                        vals.push $(this).val() if $(this).val() != \"\"\n\n                if numInputsToProcess != 0\n                    pvtVals = @find(\".pvtVals\")\n                    for x in [0...numInputsToProcess]\n                        newDropdown = $(\"<select>\")\n                            .addClass('pvtAttrDropdown')\n                            .append($(\"<option>\"))\n                            .bind \"change\", -> refresh()\n                        for attr in shownInAggregators\n                            newDropdown.append($(\"<option>\").val(attr).text(attr))\n                        pvtVals.append(newDropdown)\n\n                if initialRender\n                    vals = opts.vals\n                    i = 0\n                    @find(\".pvtVals select.pvtAttrDropdown\").each ->\n                        $(this).val vals[i]\n                        i++\n                    initialRender = false\n\n                subopts.aggregatorName = aggregator.val()\n                subopts.vals = vals\n                subopts.aggregator = opts.aggregators[aggregator.val()](vals)\n                subopts.renderer = opts.renderers[renderer.val()]\n                subopts.rowOrder = rowOrderArrow.data(\"order\")\n                subopts.colOrder = colOrderArrow.data(\"order\")\n                #construct filter here\n                exclusions = {}\n                @find('input.pvtFilter').not(':checked').each ->\n                    filter = $(this).data(\"filter\")\n                    if exclusions[filter[0]]?\n                        exclusions[filter[0]].push( filter[1] )\n                    else\n                        exclusions[filter[0]] = [ filter[1] ]\n                #include inclusions when exclusions present\n                inclusions = {}\n                @find('input.pvtFilter:checked').each ->\n                    filter = $(this).data(\"filter\")\n                    if exclusions[filter[0]]?\n                        if inclusions[filter[0]]?\n                            inclusions[filter[0]].push( filter[1] )\n                        else\n                            inclusions[filter[0]] = [ filter[1] ]\n\n                subopts.filter = (record) ->\n                    return false if not opts.filter(record)\n                    for k,excludedItems of exclusions\n                        return false if \"\"+(record[k] ? 'null') in excludedItems\n                    return true\n\n                pivotTable.pivot(materializedInput,subopts)\n                pivotUIOptions = $.extend {}, opts,\n                    cols: subopts.cols\n                    rows: subopts.rows\n                    colOrder: subopts.colOrder\n                    rowOrder: subopts.rowOrder\n                    vals: vals\n                    exclusions: exclusions\n                    inclusions: inclusions\n                    inclusionsInfo: inclusions #duplicated for backwards-compatibility\n                    aggregatorName: aggregator.val()\n                    rendererName: renderer.val()\n\n                @data \"pivotUIOptions\", pivotUIOptions\n\n                # if requested make sure unused columns are in alphabetical order\n                if opts.autoSortUnusedAttrs\n                    unusedAttrsContainer = @find(\"td.pvtUnused.pvtAxisContainer\")\n                    $(unusedAttrsContainer).children(\"li\")\n                        .sort((a, b) => naturalSort($(a).text(), $(b).text()))\n                        .appendTo unusedAttrsContainer\n\n                pivotTable.css(\"opacity\", 1)\n                opts.onRefresh(pivotUIOptions) if opts.onRefresh?\n\n            refresh = =>\n                pivotTable.css(\"opacity\", 0.5)\n                setTimeout refreshDelayed, 10\n\n            #the very first refresh will actually display the table\n            refresh()\n\n            @find(\".pvtAxisContainer\").sortable\n                    update: (e, ui) -> refresh() if not ui.sender?\n                    connectWith: @find(\".pvtAxisContainer\")\n                    items: 'li'\n                    placeholder: 'pvtPlaceholder'\n        catch e\n            console.error(e.stack) if console?\n            @html opts.localeStrings.uiRenderError\n        return this\n\n    ###\n    Heatmap post-processing\n    ###\n\n    $.fn.heatmap = (scope = \"heatmap\", opts) ->\n        numRows = @data \"numrows\"\n        numCols = @data \"numcols\"\n\n        # given a series of values\n        # must return a function to map a given value to a CSS color\n        colorScaleGenerator = opts?.heatmap?.colorScaleGenerator\n        colorScaleGenerator ?= (values) ->\n            min = Math.min(values...)\n            max = Math.max(values...)\n            return (x) ->\n                nonRed = 255 - Math.round 255*(x-min)/(max-min)\n                return \"rgb(255,#{nonRed},#{nonRed})\"\n\n        heatmapper = (scope) =>\n            forEachCell = (f) =>\n                @find(scope).each ->\n                    x = $(this).data(\"value\")\n                    f(x, $(this)) if x? and isFinite(x)\n\n            values = []\n            forEachCell (x) -> values.push x\n            colorScale = colorScaleGenerator(values)\n            forEachCell (x, elem) -> elem.css \"background-color\", colorScale(x)\n\n        switch scope\n            when \"heatmap\"    then heatmapper \".pvtVal\"\n            when \"rowheatmap\" then heatmapper \".pvtVal.row#{i}\" for i in [0...numRows]\n            when \"colheatmap\" then heatmapper \".pvtVal.col#{j}\" for j in [0...numCols]\n\n        heatmapper \".pvtTotal.rowTotal\"\n        heatmapper \".pvtTotal.colTotal\"\n\n        return this\n\n    ###\n    Barchart post-processing\n    ###\n\n    $.fn.barchart = (opts) ->\n        numRows = @data \"numrows\"\n        numCols = @data \"numcols\"\n\n        barcharter = (scope) =>\n            forEachCell = (f) =>\n                @find(scope).each ->\n                    x = $(this).data(\"value\")\n                    f(x, $(this)) if x? and isFinite(x)\n\n            values = []\n            forEachCell (x) -> values.push x\n            max = Math.max(values...)\n            if max < 0\n                max = 0\n            range = max;\n            min = Math.min(values...)\n            if min < 0\n                range = max - min\n            scaler = (x) -> 100*x/(1.4*range)\n            forEachCell (x, elem) ->\n                text = elem.text()\n                wrapper = $(\"<div>\").css\n                    \"position\": \"relative\"\n                    \"height\": \"55px\"\n                bgColor = \"gray\"\n                bBase = 0\n                if min < 0\n                    bBase = scaler(-min)\n                if x < 0\n                    bBase += scaler(x)\n                    bgColor = \"darkred\"\n                    x = -x\n                wrapper.append $(\"<div>\").css\n                    \"position\": \"absolute\"\n                    \"bottom\": bBase + \"%\"\n                    \"left\": 0\n                    \"right\": 0\n                    \"height\": scaler(x) + \"%\"\n                    \"background-color\": bgColor\n                wrapper.append $(\"<div>\").text(text).css\n                    \"position\":\"relative\"\n                    \"padding-left\":\"5px\"\n                    \"padding-right\":\"5px\"\n\n                elem.css(\"padding\": 0,\"padding-top\": \"5px\", \"text-align\": \"center\").html wrapper\n\n        barcharter \".pvtVal.row#{i}\" for i in [0...numRows]\n        barcharter \".pvtTotal.colTotal\"\n\n        return this\n","(function() {\n  var callWithJQuery,\n    indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },\n    slice = [].slice,\n    bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },\n    hasProp = {}.hasOwnProperty;\n\n  callWithJQuery = function(pivotModule) {\n    if (typeof exports === \"object\" && typeof module === \"object\") {\n      return pivotModule(require(\"jquery\"));\n    } else if (typeof define === \"function\" && define.amd) {\n      return define([\"jquery\"], pivotModule);\n    } else {\n      return pivotModule(jQuery);\n    }\n  };\n\n  callWithJQuery(function($) {\n\n    /*\n    Utilities\n     */\n    var PivotData, addSeparators, aggregatorTemplates, aggregators, dayNamesEn, derivers, getSort, locales, mthNamesEn, naturalSort, numberFormat, pivotTableRenderer, rd, renderers, rx, rz, sortAs, usFmt, usFmtInt, usFmtPct, zeroPad;\n    addSeparators = function(nStr, thousandsSep, decimalSep) {\n      var rgx, x, x1, x2;\n      nStr += '';\n      x = nStr.split('.');\n      x1 = x[0];\n      x2 = x.length > 1 ? decimalSep + x[1] : '';\n      rgx = /(\\d+)(\\d{3})/;\n      while (rgx.test(x1)) {\n        x1 = x1.replace(rgx, '$1' + thousandsSep + '$2');\n      }\n      return x1 + x2;\n    };\n    numberFormat = function(opts) {\n      var defaults;\n      defaults = {\n        digitsAfterDecimal: 2,\n        scaler: 1,\n        thousandsSep: \",\",\n        decimalSep: \".\",\n        prefix: \"\",\n        suffix: \"\"\n      };\n      opts = $.extend({}, defaults, opts);\n      return function(x) {\n        var result;\n        if (isNaN(x) || !isFinite(x)) {\n          return \"\";\n        }\n        result = addSeparators((opts.scaler * x).toFixed(opts.digitsAfterDecimal), opts.thousandsSep, opts.decimalSep);\n        return \"\" + opts.prefix + result + opts.suffix;\n      };\n    };\n    usFmt = numberFormat();\n    usFmtInt = numberFormat({\n      digitsAfterDecimal: 0\n    });\n    usFmtPct = numberFormat({\n      digitsAfterDecimal: 1,\n      scaler: 100,\n      suffix: \"%\"\n    });\n    aggregatorTemplates = {\n      count: function(formatter) {\n        if (formatter == null) {\n          formatter = usFmtInt;\n        }\n        return function() {\n          return function(data, rowKey, colKey) {\n            return {\n              count: 0,\n              push: function() {\n                return this.count++;\n              },\n              value: function() {\n                return this.count;\n              },\n              format: formatter\n            };\n          };\n        };\n      },\n      uniques: function(fn, formatter) {\n        if (formatter == null) {\n          formatter = usFmtInt;\n        }\n        return function(arg) {\n          var attr;\n          attr = arg[0];\n          return function(data, rowKey, colKey) {\n            return {\n              uniq: [],\n              push: function(record) {\n                var ref;\n                if (ref = record[attr], indexOf.call(this.uniq, ref) < 0) {\n                  return this.uniq.push(record[attr]);\n                }\n              },\n              value: function() {\n                return fn(this.uniq);\n              },\n              format: formatter,\n              numInputs: attr != null ? 0 : 1\n            };\n          };\n        };\n      },\n      sum: function(formatter) {\n        if (formatter == null) {\n          formatter = usFmt;\n        }\n        return function(arg) {\n          var attr;\n          attr = arg[0];\n          return function(data, rowKey, colKey) {\n            return {\n              sum: 0,\n              push: function(record) {\n                if (!isNaN(parseFloat(record[attr]))) {\n                  return this.sum += parseFloat(record[attr]);\n                }\n              },\n              value: function() {\n                return this.sum;\n              },\n              format: formatter,\n              numInputs: attr != null ? 0 : 1\n            };\n          };\n        };\n      },\n      extremes: function(mode, formatter) {\n        if (formatter == null) {\n          formatter = usFmt;\n        }\n        return function(arg) {\n          var attr;\n          attr = arg[0];\n          return function(data, rowKey, colKey) {\n            return {\n              val: null,\n              sorter: getSort(data != null ? data.sorters : void 0, attr),\n              push: function(record) {\n                var ref, ref1, ref2, x;\n                x = record[attr];\n                if (mode === \"min\" || mode === \"max\") {\n                  x = parseFloat(x);\n                  if (!isNaN(x)) {\n                    this.val = Math[mode](x, (ref = this.val) != null ? ref : x);\n                  }\n                }\n                if (mode === \"first\") {\n                  if (this.sorter(x, (ref1 = this.val) != null ? ref1 : x) <= 0) {\n                    this.val = x;\n                  }\n                }\n                if (mode === \"last\") {\n                  if (this.sorter(x, (ref2 = this.val) != null ? ref2 : x) >= 0) {\n                    return this.val = x;\n                  }\n                }\n              },\n              value: function() {\n                return this.val;\n              },\n              format: function(x) {\n                if (isNaN(x)) {\n                  return x;\n                } else {\n                  return formatter(x);\n                }\n              },\n              numInputs: attr != null ? 0 : 1\n            };\n          };\n        };\n      },\n      quantile: function(q, formatter) {\n        if (formatter == null) {\n          formatter = usFmt;\n        }\n        return function(arg) {\n          var attr;\n          attr = arg[0];\n          return function(data, rowKey, colKey) {\n            return {\n              vals: [],\n              push: function(record) {\n                var x;\n                x = parseFloat(record[attr]);\n                if (!isNaN(x)) {\n                  return this.vals.push(x);\n                }\n              },\n              value: function() {\n                var i;\n                if (this.vals.length === 0) {\n                  return null;\n                }\n                this.vals.sort(function(a, b) {\n                  return a - b;\n                });\n                i = (this.vals.length - 1) * q;\n                return (this.vals[Math.floor(i)] + this.vals[Math.ceil(i)]) / 2.0;\n              },\n              format: formatter,\n              numInputs: attr != null ? 0 : 1\n            };\n          };\n        };\n      },\n      runningStat: function(mode, ddof, formatter) {\n        if (mode == null) {\n          mode = \"mean\";\n        }\n        if (ddof == null) {\n          ddof = 1;\n        }\n        if (formatter == null) {\n          formatter = usFmt;\n        }\n        return function(arg) {\n          var attr;\n          attr = arg[0];\n          return function(data, rowKey, colKey) {\n            return {\n              n: 0.0,\n              m: 0.0,\n              s: 0.0,\n              push: function(record) {\n                var m_new, x;\n                x = parseFloat(record[attr]);\n                if (isNaN(x)) {\n                  return;\n                }\n                this.n += 1.0;\n                if (this.n === 1.0) {\n                  return this.m = x;\n                } else {\n                  m_new = this.m + (x - this.m) / this.n;\n                  this.s = this.s + (x - this.m) * (x - m_new);\n                  return this.m = m_new;\n                }\n              },\n              value: function() {\n                if (mode === \"mean\") {\n                  if (this.n === 0) {\n                    return 0 / 0;\n                  } else {\n                    return this.m;\n                  }\n                }\n                if (this.n <= ddof) {\n                  return 0;\n                }\n                switch (mode) {\n                  case \"var\":\n                    return this.s / (this.n - ddof);\n                  case \"stdev\":\n                    return Math.sqrt(this.s / (this.n - ddof));\n                }\n              },\n              format: formatter,\n              numInputs: attr != null ? 0 : 1\n            };\n          };\n        };\n      },\n      sumOverSum: function(formatter) {\n        if (formatter == null) {\n          formatter = usFmt;\n        }\n        return function(arg) {\n          var denom, num;\n          num = arg[0], denom = arg[1];\n          return function(data, rowKey, colKey) {\n            return {\n              sumNum: 0,\n              sumDenom: 0,\n              push: function(record) {\n                if (!isNaN(parseFloat(record[num]))) {\n                  this.sumNum += parseFloat(record[num]);\n                }\n                if (!isNaN(parseFloat(record[denom]))) {\n                  return this.sumDenom += parseFloat(record[denom]);\n                }\n              },\n              value: function() {\n                return this.sumNum / this.sumDenom;\n              },\n              format: formatter,\n              numInputs: (num != null) && (denom != null) ? 0 : 2\n            };\n          };\n        };\n      },\n      sumOverSumBound80: function(upper, formatter) {\n        if (upper == null) {\n          upper = true;\n        }\n        if (formatter == null) {\n          formatter = usFmt;\n        }\n        return function(arg) {\n          var denom, num;\n          num = arg[0], denom = arg[1];\n          return function(data, rowKey, colKey) {\n            return {\n              sumNum: 0,\n              sumDenom: 0,\n              push: function(record) {\n                if (!isNaN(parseFloat(record[num]))) {\n                  this.sumNum += parseFloat(record[num]);\n                }\n                if (!isNaN(parseFloat(record[denom]))) {\n                  return this.sumDenom += parseFloat(record[denom]);\n                }\n              },\n              value: function() {\n                var sign;\n                sign = upper ? 1 : -1;\n                return (0.821187207574908 / this.sumDenom + this.sumNum / this.sumDenom + 1.2815515655446004 * sign * Math.sqrt(0.410593603787454 / (this.sumDenom * this.sumDenom) + (this.sumNum * (1 - this.sumNum / this.sumDenom)) / (this.sumDenom * this.sumDenom))) / (1 + 1.642374415149816 / this.sumDenom);\n              },\n              format: formatter,\n              numInputs: (num != null) && (denom != null) ? 0 : 2\n            };\n          };\n        };\n      },\n      fractionOf: function(wrapped, type, formatter) {\n        if (type == null) {\n          type = \"total\";\n        }\n        if (formatter == null) {\n          formatter = usFmtPct;\n        }\n        return function() {\n          var x;\n          x = 1 <= arguments.length ? slice.call(arguments, 0) : [];\n          return function(data, rowKey, colKey) {\n            return {\n              selector: {\n                total: [[], []],\n                row: [rowKey, []],\n                col: [[], colKey]\n              }[type],\n              inner: wrapped.apply(null, x)(data, rowKey, colKey),\n              push: function(record) {\n                return this.inner.push(record);\n              },\n              format: formatter,\n              value: function() {\n                return this.inner.value() / data.getAggregator.apply(data, this.selector).inner.value();\n              },\n              numInputs: wrapped.apply(null, x)().numInputs\n            };\n          };\n        };\n      }\n    };\n    aggregatorTemplates.countUnique = function(f) {\n      return aggregatorTemplates.uniques((function(x) {\n        return x.length;\n      }), f);\n    };\n    aggregatorTemplates.listUnique = function(s) {\n      return aggregatorTemplates.uniques((function(x) {\n        return x.sort(naturalSort).join(s);\n      }), (function(x) {\n        return x;\n      }));\n    };\n    aggregatorTemplates.max = function(f) {\n      return aggregatorTemplates.extremes('max', f);\n    };\n    aggregatorTemplates.min = function(f) {\n      return aggregatorTemplates.extremes('min', f);\n    };\n    aggregatorTemplates.first = function(f) {\n      return aggregatorTemplates.extremes('first', f);\n    };\n    aggregatorTemplates.last = function(f) {\n      return aggregatorTemplates.extremes('last', f);\n    };\n    aggregatorTemplates.median = function(f) {\n      return aggregatorTemplates.quantile(0.5, f);\n    };\n    aggregatorTemplates.average = function(f) {\n      return aggregatorTemplates.runningStat(\"mean\", 1, f);\n    };\n    aggregatorTemplates[\"var\"] = function(ddof, f) {\n      return aggregatorTemplates.runningStat(\"var\", ddof, f);\n    };\n    aggregatorTemplates.stdev = function(ddof, f) {\n      return aggregatorTemplates.runningStat(\"stdev\", ddof, f);\n    };\n    aggregators = (function(tpl) {\n      return {\n        \"Count\": tpl.count(usFmtInt),\n        \"Count Unique Values\": tpl.countUnique(usFmtInt),\n        \"List Unique Values\": tpl.listUnique(\", \"),\n        \"Sum\": tpl.sum(usFmt),\n        \"Integer Sum\": tpl.sum(usFmtInt),\n        \"Average\": tpl.average(usFmt),\n        \"Median\": tpl.median(usFmt),\n        \"Sample Variance\": tpl[\"var\"](1, usFmt),\n        \"Sample Standard Deviation\": tpl.stdev(1, usFmt),\n        \"Minimum\": tpl.min(usFmt),\n        \"Maximum\": tpl.max(usFmt),\n        \"First\": tpl.first(usFmt),\n        \"Last\": tpl.last(usFmt),\n        \"Sum over Sum\": tpl.sumOverSum(usFmt),\n        \"80% Upper Bound\": tpl.sumOverSumBound80(true, usFmt),\n        \"80% Lower Bound\": tpl.sumOverSumBound80(false, usFmt),\n        \"Sum as Fraction of Total\": tpl.fractionOf(tpl.sum(), \"total\", usFmtPct),\n        \"Sum as Fraction of Rows\": tpl.fractionOf(tpl.sum(), \"row\", usFmtPct),\n        \"Sum as Fraction of Columns\": tpl.fractionOf(tpl.sum(), \"col\", usFmtPct),\n        \"Count as Fraction of Total\": tpl.fractionOf(tpl.count(), \"total\", usFmtPct),\n        \"Count as Fraction of Rows\": tpl.fractionOf(tpl.count(), \"row\", usFmtPct),\n        \"Count as Fraction of Columns\": tpl.fractionOf(tpl.count(), \"col\", usFmtPct)\n      };\n    })(aggregatorTemplates);\n    renderers = {\n      \"Table\": function(data, opts) {\n        return pivotTableRenderer(data, opts);\n      },\n      \"Table Barchart\": function(data, opts) {\n        return $(pivotTableRenderer(data, opts)).barchart();\n      },\n      \"Heatmap\": function(data, opts) {\n        return $(pivotTableRenderer(data, opts)).heatmap(\"heatmap\", opts);\n      },\n      \"Row Heatmap\": function(data, opts) {\n        return $(pivotTableRenderer(data, opts)).heatmap(\"rowheatmap\", opts);\n      },\n      \"Col Heatmap\": function(data, opts) {\n        return $(pivotTableRenderer(data, opts)).heatmap(\"colheatmap\", opts);\n      }\n    };\n    locales = {\n      en: {\n        aggregators: aggregators,\n        renderers: renderers,\n        localeStrings: {\n          renderError: \"An error occurred rendering the PivotTable results.\",\n          computeError: \"An error occurred computing the PivotTable results.\",\n          uiRenderError: \"An error occurred rendering the PivotTable UI.\",\n          selectAll: \"Select All\",\n          selectNone: \"Select None\",\n          tooMany: \"(too many to list)\",\n          filterResults: \"Filter values\",\n          apply: \"Apply\",\n          cancel: \"Cancel\",\n          totals: \"Totals\",\n          vs: \"vs\",\n          by: \"by\"\n        }\n      }\n    };\n    mthNamesEn = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"];\n    dayNamesEn = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\n    zeroPad = function(number) {\n      return (\"0\" + number).substr(-2, 2);\n    };\n    derivers = {\n      bin: function(col, binWidth) {\n        return function(record) {\n          return record[col] - record[col] % binWidth;\n        };\n      },\n      dateFormat: function(col, formatString, utcOutput, mthNames, dayNames) {\n        var utc;\n        if (utcOutput == null) {\n          utcOutput = false;\n        }\n        if (mthNames == null) {\n          mthNames = mthNamesEn;\n        }\n        if (dayNames == null) {\n          dayNames = dayNamesEn;\n        }\n        utc = utcOutput ? \"UTC\" : \"\";\n        return function(record) {\n          var date;\n          date = new Date(Date.parse(record[col]));\n          if (isNaN(date)) {\n            return \"\";\n          }\n          return formatString.replace(/%(.)/g, function(m, p) {\n            switch (p) {\n              case \"y\":\n                return date[\"get\" + utc + \"FullYear\"]();\n              case \"m\":\n                return zeroPad(date[\"get\" + utc + \"Month\"]() + 1);\n              case \"n\":\n                return mthNames[date[\"get\" + utc + \"Month\"]()];\n              case \"d\":\n                return zeroPad(date[\"get\" + utc + \"Date\"]());\n              case \"w\":\n                return dayNames[date[\"get\" + utc + \"Day\"]()];\n              case \"x\":\n                return date[\"get\" + utc + \"Day\"]();\n              case \"H\":\n                return zeroPad(date[\"get\" + utc + \"Hours\"]());\n              case \"M\":\n                return zeroPad(date[\"get\" + utc + \"Minutes\"]());\n              case \"S\":\n                return zeroPad(date[\"get\" + utc + \"Seconds\"]());\n              default:\n                return \"%\" + p;\n            }\n          });\n        };\n      }\n    };\n    rx = /(\\d+)|(\\D+)/g;\n    rd = /\\d/;\n    rz = /^0/;\n    naturalSort = (function(_this) {\n      return function(as, bs) {\n        var a, a1, b, b1, nas, nbs;\n        if ((bs != null) && (as == null)) {\n          return -1;\n        }\n        if ((as != null) && (bs == null)) {\n          return 1;\n        }\n        if (typeof as === \"number\" && isNaN(as)) {\n          return -1;\n        }\n        if (typeof bs === \"number\" && isNaN(bs)) {\n          return 1;\n        }\n        nas = +as;\n        nbs = +bs;\n        if (nas < nbs) {\n          return -1;\n        }\n        if (nas > nbs) {\n          return 1;\n        }\n        if (typeof as === \"number\" && typeof bs !== \"number\") {\n          return -1;\n        }\n        if (typeof bs === \"number\" && typeof as !== \"number\") {\n          return 1;\n        }\n        if (typeof as === \"number\" && typeof bs === \"number\") {\n          return 0;\n        }\n        if (isNaN(nbs) && !isNaN(nas)) {\n          return -1;\n        }\n        if (isNaN(nas) && !isNaN(nbs)) {\n          return 1;\n        }\n        a = String(as);\n        b = String(bs);\n        if (a === b) {\n          return 0;\n        }\n        if (!(rd.test(a) && rd.test(b))) {\n          return (a > b ? 1 : -1);\n        }\n        a = a.match(rx);\n        b = b.match(rx);\n        while (a.length && b.length) {\n          a1 = a.shift();\n          b1 = b.shift();\n          if (a1 !== b1) {\n            if (rd.test(a1) && rd.test(b1)) {\n              return a1.replace(rz, \".0\") - b1.replace(rz, \".0\");\n            } else {\n              return (a1 > b1 ? 1 : -1);\n            }\n          }\n        }\n        return a.length - b.length;\n      };\n    })(this);\n    sortAs = function(order) {\n      var i, l_mapping, mapping, x;\n      mapping = {};\n      l_mapping = {};\n      for (i in order) {\n        x = order[i];\n        mapping[x] = i;\n        if (typeof x === \"string\") {\n          l_mapping[x.toLowerCase()] = i;\n        }\n      }\n      return function(a, b) {\n        if ((mapping[a] != null) && (mapping[b] != null)) {\n          return mapping[a] - mapping[b];\n        } else if (mapping[a] != null) {\n          return -1;\n        } else if (mapping[b] != null) {\n          return 1;\n        } else if ((l_mapping[a] != null) && (l_mapping[b] != null)) {\n          return l_mapping[a] - l_mapping[b];\n        } else if (l_mapping[a] != null) {\n          return -1;\n        } else if (l_mapping[b] != null) {\n          return 1;\n        } else {\n          return naturalSort(a, b);\n        }\n      };\n    };\n    getSort = function(sorters, attr) {\n      var sort;\n      if (sorters != null) {\n        if ($.isFunction(sorters)) {\n          sort = sorters(attr);\n          if ($.isFunction(sort)) {\n            return sort;\n          }\n        } else if (sorters[attr] != null) {\n          return sorters[attr];\n        }\n      }\n      return naturalSort;\n    };\n\n    /*\n    Data Model class\n     */\n    PivotData = (function() {\n      function PivotData(input, opts) {\n        var ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9;\n        if (opts == null) {\n          opts = {};\n        }\n        this.getAggregator = bind(this.getAggregator, this);\n        this.getRowKeys = bind(this.getRowKeys, this);\n        this.getColKeys = bind(this.getColKeys, this);\n        this.sortKeys = bind(this.sortKeys, this);\n        this.arrSort = bind(this.arrSort, this);\n        this.input = input;\n        this.aggregator = (ref = opts.aggregator) != null ? ref : aggregatorTemplates.count()();\n        this.aggregatorName = (ref1 = opts.aggregatorName) != null ? ref1 : \"Count\";\n        this.colAttrs = (ref2 = opts.cols) != null ? ref2 : [];\n        this.rowAttrs = (ref3 = opts.rows) != null ? ref3 : [];\n        this.valAttrs = (ref4 = opts.vals) != null ? ref4 : [];\n        this.sorters = (ref5 = opts.sorters) != null ? ref5 : {};\n        this.rowOrder = (ref6 = opts.rowOrder) != null ? ref6 : \"key_a_to_z\";\n        this.colOrder = (ref7 = opts.colOrder) != null ? ref7 : \"key_a_to_z\";\n        this.derivedAttributes = (ref8 = opts.derivedAttributes) != null ? ref8 : {};\n        this.filter = (ref9 = opts.filter) != null ? ref9 : (function() {\n          return true;\n        });\n        this.tree = {};\n        this.rowKeys = [];\n        this.colKeys = [];\n        this.rowTotals = {};\n        this.colTotals = {};\n        this.allTotal = this.aggregator(this, [], []);\n        this.sorted = false;\n        PivotData.forEachRecord(this.input, this.derivedAttributes, (function(_this) {\n          return function(record) {\n            if (_this.filter(record)) {\n              return _this.processRecord(record);\n            }\n          };\n        })(this));\n      }\n\n      PivotData.forEachRecord = function(input, derivedAttributes, f) {\n        var addRecord, compactRecord, i, j, k, l, len1, record, ref, results, results1, tblCols;\n        if ($.isEmptyObject(derivedAttributes)) {\n          addRecord = f;\n        } else {\n          addRecord = function(record) {\n            var k, ref, v;\n            for (k in derivedAttributes) {\n              v = derivedAttributes[k];\n              record[k] = (ref = v(record)) != null ? ref : record[k];\n            }\n            return f(record);\n          };\n        }\n        if ($.isFunction(input)) {\n          return input(addRecord);\n        } else if ($.isArray(input)) {\n          if ($.isArray(input[0])) {\n            results = [];\n            for (i in input) {\n              if (!hasProp.call(input, i)) continue;\n              compactRecord = input[i];\n              if (!(i > 0)) {\n                continue;\n              }\n              record = {};\n              ref = input[0];\n              for (j in ref) {\n                if (!hasProp.call(ref, j)) continue;\n                k = ref[j];\n                record[k] = compactRecord[j];\n              }\n              results.push(addRecord(record));\n            }\n            return results;\n          } else {\n            results1 = [];\n            for (l = 0, len1 = input.length; l < len1; l++) {\n              record = input[l];\n              results1.push(addRecord(record));\n            }\n            return results1;\n          }\n        } else if (input instanceof $) {\n          tblCols = [];\n          $(\"thead > tr > th\", input).each(function(i) {\n            return tblCols.push($(this).text());\n          });\n          return $(\"tbody > tr\", input).each(function(i) {\n            record = {};\n            $(\"td\", this).each(function(j) {\n              return record[tblCols[j]] = $(this).text();\n            });\n            return addRecord(record);\n          });\n        } else {\n          throw new Error(\"unknown input format\");\n        }\n      };\n\n      PivotData.prototype.forEachMatchingRecord = function(criteria, callback) {\n        return PivotData.forEachRecord(this.input, this.derivedAttributes, (function(_this) {\n          return function(record) {\n            var k, ref, v;\n            if (!_this.filter(record)) {\n              return;\n            }\n            for (k in criteria) {\n              v = criteria[k];\n              if (v !== ((ref = record[k]) != null ? ref : \"null\")) {\n                return;\n              }\n            }\n            return callback(record);\n          };\n        })(this));\n      };\n\n      PivotData.prototype.arrSort = function(attrs) {\n        var a, sortersArr;\n        sortersArr = (function() {\n          var l, len1, results;\n          results = [];\n          for (l = 0, len1 = attrs.length; l < len1; l++) {\n            a = attrs[l];\n            results.push(getSort(this.sorters, a));\n          }\n          return results;\n        }).call(this);\n        return function(a, b) {\n          var comparison, i, sorter;\n          for (i in sortersArr) {\n            if (!hasProp.call(sortersArr, i)) continue;\n            sorter = sortersArr[i];\n            comparison = sorter(a[i], b[i]);\n            if (comparison !== 0) {\n              return comparison;\n            }\n          }\n          return 0;\n        };\n      };\n\n      PivotData.prototype.sortKeys = function() {\n        var v;\n        if (!this.sorted) {\n          this.sorted = true;\n          v = (function(_this) {\n            return function(r, c) {\n              return _this.getAggregator(r, c).value();\n            };\n          })(this);\n          switch (this.rowOrder) {\n            case \"value_a_to_z\":\n              this.rowKeys.sort((function(_this) {\n                return function(a, b) {\n                  return naturalSort(v(a, []), v(b, []));\n                };\n              })(this));\n              break;\n            case \"value_z_to_a\":\n              this.rowKeys.sort((function(_this) {\n                return function(a, b) {\n                  return -naturalSort(v(a, []), v(b, []));\n                };\n              })(this));\n              break;\n            default:\n              this.rowKeys.sort(this.arrSort(this.rowAttrs));\n          }\n          switch (this.colOrder) {\n            case \"value_a_to_z\":\n              return this.colKeys.sort((function(_this) {\n                return function(a, b) {\n                  return naturalSort(v([], a), v([], b));\n                };\n              })(this));\n            case \"value_z_to_a\":\n              return this.colKeys.sort((function(_this) {\n                return function(a, b) {\n                  return -naturalSort(v([], a), v([], b));\n                };\n              })(this));\n            default:\n              return this.colKeys.sort(this.arrSort(this.colAttrs));\n          }\n        }\n      };\n\n      PivotData.prototype.getColKeys = function() {\n        this.sortKeys();\n        return this.colKeys;\n      };\n\n      PivotData.prototype.getRowKeys = function() {\n        this.sortKeys();\n        return this.rowKeys;\n      };\n\n      PivotData.prototype.processRecord = function(record) {\n        var colKey, flatColKey, flatRowKey, l, len1, len2, n, ref, ref1, ref2, ref3, rowKey, x;\n        colKey = [];\n        rowKey = [];\n        ref = this.colAttrs;\n        for (l = 0, len1 = ref.length; l < len1; l++) {\n          x = ref[l];\n          colKey.push((ref1 = record[x]) != null ? ref1 : \"null\");\n        }\n        ref2 = this.rowAttrs;\n        for (n = 0, len2 = ref2.length; n < len2; n++) {\n          x = ref2[n];\n          rowKey.push((ref3 = record[x]) != null ? ref3 : \"null\");\n        }\n        flatRowKey = rowKey.join(String.fromCharCode(0));\n        flatColKey = colKey.join(String.fromCharCode(0));\n        this.allTotal.push(record);\n        if (rowKey.length !== 0) {\n          if (!this.rowTotals[flatRowKey]) {\n            this.rowKeys.push(rowKey);\n            this.rowTotals[flatRowKey] = this.aggregator(this, rowKey, []);\n          }\n          this.rowTotals[flatRowKey].push(record);\n        }\n        if (colKey.length !== 0) {\n          if (!this.colTotals[flatColKey]) {\n            this.colKeys.push(colKey);\n            this.colTotals[flatColKey] = this.aggregator(this, [], colKey);\n          }\n          this.colTotals[flatColKey].push(record);\n        }\n        if (colKey.length !== 0 && rowKey.length !== 0) {\n          if (!this.tree[flatRowKey]) {\n            this.tree[flatRowKey] = {};\n          }\n          if (!this.tree[flatRowKey][flatColKey]) {\n            this.tree[flatRowKey][flatColKey] = this.aggregator(this, rowKey, colKey);\n          }\n          return this.tree[flatRowKey][flatColKey].push(record);\n        }\n      };\n\n      PivotData.prototype.getAggregator = function(rowKey, colKey) {\n        var agg, flatColKey, flatRowKey;\n        flatRowKey = rowKey.join(String.fromCharCode(0));\n        flatColKey = colKey.join(String.fromCharCode(0));\n        if (rowKey.length === 0 && colKey.length === 0) {\n          agg = this.allTotal;\n        } else if (rowKey.length === 0) {\n          agg = this.colTotals[flatColKey];\n        } else if (colKey.length === 0) {\n          agg = this.rowTotals[flatRowKey];\n        } else {\n          agg = this.tree[flatRowKey][flatColKey];\n        }\n        return agg != null ? agg : {\n          value: (function() {\n            return null;\n          }),\n          format: function() {\n            return \"\";\n          }\n        };\n      };\n\n      return PivotData;\n\n    })();\n    $.pivotUtilities = {\n      aggregatorTemplates: aggregatorTemplates,\n      aggregators: aggregators,\n      renderers: renderers,\n      derivers: derivers,\n      locales: locales,\n      naturalSort: naturalSort,\n      numberFormat: numberFormat,\n      sortAs: sortAs,\n      PivotData: PivotData\n    };\n\n    /*\n    Default Renderer for hierarchical table layout\n     */\n    pivotTableRenderer = function(pivotData, opts) {\n      var aggregator, c, colAttrs, colKey, colKeys, defaults, getClickHandler, i, j, r, result, rowAttrs, rowKey, rowKeys, spanSize, tbody, td, th, thead, totalAggregator, tr, txt, val, x;\n      defaults = {\n        table: {\n          clickCallback: null,\n          rowTotals: true,\n          colTotals: true\n        },\n        localeStrings: {\n          totals: \"Totals\"\n        }\n      };\n      opts = $.extend(true, {}, defaults, opts);\n      colAttrs = pivotData.colAttrs;\n      rowAttrs = pivotData.rowAttrs;\n      rowKeys = pivotData.getRowKeys();\n      colKeys = pivotData.getColKeys();\n      if (opts.table.clickCallback) {\n        getClickHandler = function(value, rowValues, colValues) {\n          var attr, filters, i;\n          filters = {};\n          for (i in colAttrs) {\n            if (!hasProp.call(colAttrs, i)) continue;\n            attr = colAttrs[i];\n            if (colValues[i] != null) {\n              filters[attr] = colValues[i];\n            }\n          }\n          for (i in rowAttrs) {\n            if (!hasProp.call(rowAttrs, i)) continue;\n            attr = rowAttrs[i];\n            if (rowValues[i] != null) {\n              filters[attr] = rowValues[i];\n            }\n          }\n          return function(e) {\n            return opts.table.clickCallback(e, value, filters, pivotData);\n          };\n        };\n      }\n      result = document.createElement(\"table\");\n      result.className = \"pvtTable\";\n      spanSize = function(arr, i, j) {\n        var l, len, n, noDraw, ref, ref1, stop, x;\n        if (i !== 0) {\n          noDraw = true;\n          for (x = l = 0, ref = j; 0 <= ref ? l <= ref : l >= ref; x = 0 <= ref ? ++l : --l) {\n            if (arr[i - 1][x] !== arr[i][x]) {\n              noDraw = false;\n            }\n          }\n          if (noDraw) {\n            return -1;\n          }\n        }\n        len = 0;\n        while (i + len < arr.length) {\n          stop = false;\n          for (x = n = 0, ref1 = j; 0 <= ref1 ? n <= ref1 : n >= ref1; x = 0 <= ref1 ? ++n : --n) {\n            if (arr[i][x] !== arr[i + len][x]) {\n              stop = true;\n            }\n          }\n          if (stop) {\n            break;\n          }\n          len++;\n        }\n        return len;\n      };\n      thead = document.createElement(\"thead\");\n      for (j in colAttrs) {\n        if (!hasProp.call(colAttrs, j)) continue;\n        c = colAttrs[j];\n        tr = document.createElement(\"tr\");\n        if (parseInt(j) === 0 && rowAttrs.length !== 0) {\n          th = document.createElement(\"th\");\n          th.setAttribute(\"colspan\", rowAttrs.length);\n          th.setAttribute(\"rowspan\", colAttrs.length);\n          tr.appendChild(th);\n        }\n        th = document.createElement(\"th\");\n        th.className = \"pvtAxisLabel\";\n        th.textContent = c;\n        tr.appendChild(th);\n        for (i in colKeys) {\n          if (!hasProp.call(colKeys, i)) continue;\n          colKey = colKeys[i];\n          x = spanSize(colKeys, parseInt(i), parseInt(j));\n          if (x !== -1) {\n            th = document.createElement(\"th\");\n            th.className = \"pvtColLabel\";\n            th.textContent = colKey[j];\n            th.setAttribute(\"colspan\", x);\n            if (parseInt(j) === colAttrs.length - 1 && rowAttrs.length !== 0) {\n              th.setAttribute(\"rowspan\", 2);\n            }\n            tr.appendChild(th);\n          }\n        }\n        if (parseInt(j) === 0 && opts.table.rowTotals) {\n          th = document.createElement(\"th\");\n          th.className = \"pvtTotalLabel pvtRowTotalLabel\";\n          th.innerHTML = opts.localeStrings.totals;\n          th.setAttribute(\"rowspan\", colAttrs.length + (rowAttrs.length === 0 ? 0 : 1));\n          tr.appendChild(th);\n        }\n        thead.appendChild(tr);\n      }\n      if (rowAttrs.length !== 0) {\n        tr = document.createElement(\"tr\");\n        for (i in rowAttrs) {\n          if (!hasProp.call(rowAttrs, i)) continue;\n          r = rowAttrs[i];\n          th = document.createElement(\"th\");\n          th.className = \"pvtAxisLabel\";\n          th.textContent = r;\n          tr.appendChild(th);\n        }\n        th = document.createElement(\"th\");\n        if (colAttrs.length === 0) {\n          th.className = \"pvtTotalLabel pvtRowTotalLabel\";\n          th.innerHTML = opts.localeStrings.totals;\n        }\n        tr.appendChild(th);\n        thead.appendChild(tr);\n      }\n      result.appendChild(thead);\n      tbody = document.createElement(\"tbody\");\n      for (i in rowKeys) {\n        if (!hasProp.call(rowKeys, i)) continue;\n        rowKey = rowKeys[i];\n        tr = document.createElement(\"tr\");\n        for (j in rowKey) {\n          if (!hasProp.call(rowKey, j)) continue;\n          txt = rowKey[j];\n          x = spanSize(rowKeys, parseInt(i), parseInt(j));\n          if (x !== -1) {\n            th = document.createElement(\"th\");\n            th.className = \"pvtRowLabel\";\n            th.textContent = txt;\n            th.setAttribute(\"rowspan\", x);\n            if (parseInt(j) === rowAttrs.length - 1 && colAttrs.length !== 0) {\n              th.setAttribute(\"colspan\", 2);\n            }\n            tr.appendChild(th);\n          }\n        }\n        for (j in colKeys) {\n          if (!hasProp.call(colKeys, j)) continue;\n          colKey = colKeys[j];\n          aggregator = pivotData.getAggregator(rowKey, colKey);\n          val = aggregator.value();\n          td = document.createElement(\"td\");\n          td.className = \"pvtVal row\" + i + \" col\" + j;\n          td.textContent = aggregator.format(val);\n          td.setAttribute(\"data-value\", val);\n          if (getClickHandler != null) {\n            td.onclick = getClickHandler(val, rowKey, colKey);\n          }\n          tr.appendChild(td);\n        }\n        if (opts.table.rowTotals || colAttrs.length === 0) {\n          totalAggregator = pivotData.getAggregator(rowKey, []);\n          val = totalAggregator.value();\n          td = document.createElement(\"td\");\n          td.className = \"pvtTotal rowTotal\";\n          td.textContent = totalAggregator.format(val);\n          td.setAttribute(\"data-value\", val);\n          if (getClickHandler != null) {\n            td.onclick = getClickHandler(val, rowKey, []);\n          }\n          td.setAttribute(\"data-for\", \"row\" + i);\n          tr.appendChild(td);\n        }\n        tbody.appendChild(tr);\n      }\n      if (opts.table.colTotals || rowAttrs.length === 0) {\n        tr = document.createElement(\"tr\");\n        if (opts.table.colTotals || rowAttrs.length === 0) {\n          th = document.createElement(\"th\");\n          th.className = \"pvtTotalLabel pvtColTotalLabel\";\n          th.innerHTML = opts.localeStrings.totals;\n          th.setAttribute(\"colspan\", rowAttrs.length + (colAttrs.length === 0 ? 0 : 1));\n          tr.appendChild(th);\n        }\n        for (j in colKeys) {\n          if (!hasProp.call(colKeys, j)) continue;\n          colKey = colKeys[j];\n          totalAggregator = pivotData.getAggregator([], colKey);\n          val = totalAggregator.value();\n          td = document.createElement(\"td\");\n          td.className = \"pvtTotal colTotal\";\n          td.textContent = totalAggregator.format(val);\n          td.setAttribute(\"data-value\", val);\n          if (getClickHandler != null) {\n            td.onclick = getClickHandler(val, [], colKey);\n          }\n          td.setAttribute(\"data-for\", \"col\" + j);\n          tr.appendChild(td);\n        }\n        if (opts.table.rowTotals || colAttrs.length === 0) {\n          totalAggregator = pivotData.getAggregator([], []);\n          val = totalAggregator.value();\n          td = document.createElement(\"td\");\n          td.className = \"pvtGrandTotal\";\n          td.textContent = totalAggregator.format(val);\n          td.setAttribute(\"data-value\", val);\n          if (getClickHandler != null) {\n            td.onclick = getClickHandler(val, [], []);\n          }\n          tr.appendChild(td);\n        }\n        tbody.appendChild(tr);\n      }\n      result.appendChild(tbody);\n      result.setAttribute(\"data-numrows\", rowKeys.length);\n      result.setAttribute(\"data-numcols\", colKeys.length);\n      return result;\n    };\n\n    /*\n    Pivot Table core: create PivotData object and call Renderer on it\n     */\n    $.fn.pivot = function(input, inputOpts, locale) {\n      var defaults, e, localeDefaults, localeStrings, opts, pivotData, result, x;\n      if (locale == null) {\n        locale = \"en\";\n      }\n      if (locales[locale] == null) {\n        locale = \"en\";\n      }\n      defaults = {\n        cols: [],\n        rows: [],\n        vals: [],\n        rowOrder: \"key_a_to_z\",\n        colOrder: \"key_a_to_z\",\n        dataClass: PivotData,\n        filter: function() {\n          return true;\n        },\n        aggregator: aggregatorTemplates.count()(),\n        aggregatorName: \"Count\",\n        sorters: {},\n        derivedAttributes: {},\n        renderer: pivotTableRenderer\n      };\n      localeStrings = $.extend(true, {}, locales.en.localeStrings, locales[locale].localeStrings);\n      localeDefaults = {\n        rendererOptions: {\n          localeStrings: localeStrings\n        },\n        localeStrings: localeStrings\n      };\n      opts = $.extend(true, {}, localeDefaults, $.extend({}, defaults, inputOpts));\n      result = null;\n      try {\n        pivotData = new opts.dataClass(input, opts);\n        try {\n          result = opts.renderer(pivotData, opts.rendererOptions);\n        } catch (error) {\n          e = error;\n          if (typeof console !== \"undefined\" && console !== null) {\n            console.error(e.stack);\n          }\n          result = $(\"<span>\").html(opts.localeStrings.renderError);\n        }\n      } catch (error) {\n        e = error;\n        if (typeof console !== \"undefined\" && console !== null) {\n          console.error(e.stack);\n        }\n        result = $(\"<span>\").html(opts.localeStrings.computeError);\n      }\n      x = this[0];\n      while (x.hasChildNodes()) {\n        x.removeChild(x.lastChild);\n      }\n      return this.append(result);\n    };\n\n    /*\n    Pivot Table UI: calls Pivot Table core above with options set by user\n     */\n    $.fn.pivotUI = function(input, inputOpts, overwrite, locale) {\n      var a, aggregator, attr, attrLength, attrValues, c, colOrderArrow, defaults, e, existingOpts, fn1, i, initialRender, l, len1, len2, len3, localeDefaults, localeStrings, materializedInput, n, o, opts, ordering, pivotTable, recordsProcessed, ref, ref1, ref2, ref3, refresh, refreshDelayed, renderer, rendererControl, rowOrderArrow, shownAttributes, shownInAggregators, shownInDragDrop, tr1, tr2, uiTable, unused, unusedAttrsVerticalAutoCutoff, unusedAttrsVerticalAutoOverride, x;\n      if (overwrite == null) {\n        overwrite = false;\n      }\n      if (locale == null) {\n        locale = \"en\";\n      }\n      if (locales[locale] == null) {\n        locale = \"en\";\n      }\n      defaults = {\n        derivedAttributes: {},\n        aggregators: locales[locale].aggregators,\n        renderers: locales[locale].renderers,\n        hiddenAttributes: [],\n        hiddenFromAggregators: [],\n        hiddenFromDragDrop: [],\n        menuLimit: 500,\n        cols: [],\n        rows: [],\n        vals: [],\n        rowOrder: \"key_a_to_z\",\n        colOrder: \"key_a_to_z\",\n        dataClass: PivotData,\n        exclusions: {},\n        inclusions: {},\n        unusedAttrsVertical: 85,\n        autoSortUnusedAttrs: false,\n        onRefresh: null,\n        showUI: true,\n        filter: function() {\n          return true;\n        },\n        sorters: {}\n      };\n      localeStrings = $.extend(true, {}, locales.en.localeStrings, locales[locale].localeStrings);\n      localeDefaults = {\n        rendererOptions: {\n          localeStrings: localeStrings\n        },\n        localeStrings: localeStrings\n      };\n      existingOpts = this.data(\"pivotUIOptions\");\n      if ((existingOpts == null) || overwrite) {\n        opts = $.extend(true, {}, localeDefaults, $.extend({}, defaults, inputOpts));\n      } else {\n        opts = existingOpts;\n      }\n      try {\n        attrValues = {};\n        materializedInput = [];\n        recordsProcessed = 0;\n        PivotData.forEachRecord(input, opts.derivedAttributes, function(record) {\n          var attr, base, ref, value;\n          if (!opts.filter(record)) {\n            return;\n          }\n          materializedInput.push(record);\n          for (attr in record) {\n            if (!hasProp.call(record, attr)) continue;\n            if (attrValues[attr] == null) {\n              attrValues[attr] = {};\n              if (recordsProcessed > 0) {\n                attrValues[attr][\"null\"] = recordsProcessed;\n              }\n            }\n          }\n          for (attr in attrValues) {\n            value = (ref = record[attr]) != null ? ref : \"null\";\n            if ((base = attrValues[attr])[value] == null) {\n              base[value] = 0;\n            }\n            attrValues[attr][value]++;\n          }\n          return recordsProcessed++;\n        });\n        uiTable = $(\"<table>\", {\n          \"class\": \"pvtUi\"\n        }).attr(\"cellpadding\", 5);\n        rendererControl = $(\"<td>\").addClass(\"pvtUiCell\");\n        renderer = $(\"<select>\").addClass('pvtRenderer').appendTo(rendererControl).bind(\"change\", function() {\n          return refresh();\n        });\n        ref = opts.renderers;\n        for (x in ref) {\n          if (!hasProp.call(ref, x)) continue;\n          $(\"<option>\").val(x).html(x).appendTo(renderer);\n        }\n        unused = $(\"<td>\").addClass('pvtAxisContainer pvtUnused pvtUiCell');\n        shownAttributes = (function() {\n          var results;\n          results = [];\n          for (a in attrValues) {\n            if (indexOf.call(opts.hiddenAttributes, a) < 0) {\n              results.push(a);\n            }\n          }\n          return results;\n        })();\n        shownInAggregators = (function() {\n          var l, len1, results;\n          results = [];\n          for (l = 0, len1 = shownAttributes.length; l < len1; l++) {\n            c = shownAttributes[l];\n            if (indexOf.call(opts.hiddenFromAggregators, c) < 0) {\n              results.push(c);\n            }\n          }\n          return results;\n        })();\n        shownInDragDrop = (function() {\n          var l, len1, results;\n          results = [];\n          for (l = 0, len1 = shownAttributes.length; l < len1; l++) {\n            c = shownAttributes[l];\n            if (indexOf.call(opts.hiddenFromDragDrop, c) < 0) {\n              results.push(c);\n            }\n          }\n          return results;\n        })();\n        unusedAttrsVerticalAutoOverride = false;\n        if (opts.unusedAttrsVertical === \"auto\") {\n          unusedAttrsVerticalAutoCutoff = 120;\n        } else {\n          unusedAttrsVerticalAutoCutoff = parseInt(opts.unusedAttrsVertical);\n        }\n        if (!isNaN(unusedAttrsVerticalAutoCutoff)) {\n          attrLength = 0;\n          for (l = 0, len1 = shownInDragDrop.length; l < len1; l++) {\n            a = shownInDragDrop[l];\n            attrLength += a.length;\n          }\n          unusedAttrsVerticalAutoOverride = attrLength > unusedAttrsVerticalAutoCutoff;\n        }\n        if (opts.unusedAttrsVertical === true || unusedAttrsVerticalAutoOverride) {\n          unused.addClass('pvtVertList');\n        } else {\n          unused.addClass('pvtHorizList');\n        }\n        fn1 = function(attr) {\n          var attrElem, checkContainer, closeFilterBox, controls, filterItem, filterItemExcluded, finalButtons, hasExcludedItem, len2, n, placeholder, ref1, sorter, triangleLink, v, value, valueCount, valueList, values;\n          values = (function() {\n            var results;\n            results = [];\n            for (v in attrValues[attr]) {\n              results.push(v);\n            }\n            return results;\n          })();\n          hasExcludedItem = false;\n          valueList = $(\"<div>\").addClass('pvtFilterBox').hide();\n          valueList.append($(\"<h4>\").append($(\"<span>\").text(attr), $(\"<span>\").addClass(\"count\").text(\"(\" + values.length + \")\")));\n          if (values.length > opts.menuLimit) {\n            valueList.append($(\"<p>\").html(opts.localeStrings.tooMany));\n          } else {\n            if (values.length > 5) {\n              controls = $(\"<p>\").appendTo(valueList);\n              sorter = getSort(opts.sorters, attr);\n              placeholder = opts.localeStrings.filterResults;\n              $(\"<input>\", {\n                type: \"text\"\n              }).appendTo(controls).attr({\n                placeholder: placeholder,\n                \"class\": \"pvtSearch\"\n              }).bind(\"keyup\", function() {\n                var accept, accept_gen, filter;\n                filter = $(this).val().toLowerCase().trim();\n                accept_gen = function(prefix, accepted) {\n                  return function(v) {\n                    var real_filter, ref1;\n                    real_filter = filter.substring(prefix.length).trim();\n                    if (real_filter.length === 0) {\n                      return true;\n                    }\n                    return ref1 = Math.sign(sorter(v.toLowerCase(), real_filter)), indexOf.call(accepted, ref1) >= 0;\n                  };\n                };\n                accept = filter.indexOf(\">=\") === 0 ? accept_gen(\">=\", [1, 0]) : filter.indexOf(\"<=\") === 0 ? accept_gen(\"<=\", [-1, 0]) : filter.indexOf(\">\") === 0 ? accept_gen(\">\", [1]) : filter.indexOf(\"<\") === 0 ? accept_gen(\"<\", [-1]) : filter.indexOf(\"~\") === 0 ? function(v) {\n                  if (filter.substring(1).trim().length === 0) {\n                    return true;\n                  }\n                  return v.toLowerCase().match(filter.substring(1));\n                } : function(v) {\n                  return v.toLowerCase().indexOf(filter) !== -1;\n                };\n                return valueList.find('.pvtCheckContainer p label span.value').each(function() {\n                  if (accept($(this).text())) {\n                    return $(this).parent().parent().show();\n                  } else {\n                    return $(this).parent().parent().hide();\n                  }\n                });\n              });\n              controls.append($(\"<br>\"));\n              $(\"<button>\", {\n                type: \"button\"\n              }).appendTo(controls).html(opts.localeStrings.selectAll).bind(\"click\", function() {\n                valueList.find(\"input:visible:not(:checked)\").prop(\"checked\", true).toggleClass(\"changed\");\n                return false;\n              });\n              $(\"<button>\", {\n                type: \"button\"\n              }).appendTo(controls).html(opts.localeStrings.selectNone).bind(\"click\", function() {\n                valueList.find(\"input:visible:checked\").prop(\"checked\", false).toggleClass(\"changed\");\n                return false;\n              });\n            }\n            checkContainer = $(\"<div>\").addClass(\"pvtCheckContainer\").appendTo(valueList);\n            ref1 = values.sort(getSort(opts.sorters, attr));\n            for (n = 0, len2 = ref1.length; n < len2; n++) {\n              value = ref1[n];\n              valueCount = attrValues[attr][value];\n              filterItem = $(\"<label>\");\n              filterItemExcluded = false;\n              if (opts.inclusions[attr]) {\n                filterItemExcluded = (indexOf.call(opts.inclusions[attr], value) < 0);\n              } else if (opts.exclusions[attr]) {\n                filterItemExcluded = (indexOf.call(opts.exclusions[attr], value) >= 0);\n              }\n              hasExcludedItem || (hasExcludedItem = filterItemExcluded);\n              $(\"<input>\").attr(\"type\", \"checkbox\").addClass('pvtFilter').attr(\"checked\", !filterItemExcluded).data(\"filter\", [attr, value]).appendTo(filterItem).bind(\"change\", function() {\n                return $(this).toggleClass(\"changed\");\n              });\n              filterItem.append($(\"<span>\").addClass(\"value\").text(value));\n              filterItem.append($(\"<span>\").addClass(\"count\").text(\"(\" + valueCount + \")\"));\n              checkContainer.append($(\"<p>\").append(filterItem));\n            }\n          }\n          closeFilterBox = function() {\n            if (valueList.find(\"[type='checkbox']\").length > valueList.find(\"[type='checkbox']:checked\").length) {\n              attrElem.addClass(\"pvtFilteredAttribute\");\n            } else {\n              attrElem.removeClass(\"pvtFilteredAttribute\");\n            }\n            valueList.find('.pvtSearch').val('');\n            valueList.find('.pvtCheckContainer p').show();\n            return valueList.hide();\n          };\n          finalButtons = $(\"<p>\").appendTo(valueList);\n          if (values.length <= opts.menuLimit) {\n            $(\"<button>\", {\n              type: \"button\"\n            }).text(opts.localeStrings.apply).appendTo(finalButtons).bind(\"click\", function() {\n              if (valueList.find(\".changed\").removeClass(\"changed\").length) {\n                refresh();\n              }\n              return closeFilterBox();\n            });\n          }\n          $(\"<button>\", {\n            type: \"button\"\n          }).text(opts.localeStrings.cancel).appendTo(finalButtons).bind(\"click\", function() {\n            valueList.find(\".changed:checked\").removeClass(\"changed\").prop(\"checked\", false);\n            valueList.find(\".changed:not(:checked)\").removeClass(\"changed\").prop(\"checked\", true);\n            return closeFilterBox();\n          });\n          triangleLink = $(\"<span>\").addClass('pvtTriangle').html(\" &#x25BE;\").bind(\"click\", function(e) {\n            var left, ref2, top;\n            ref2 = $(e.currentTarget).position(), left = ref2.left, top = ref2.top;\n            return valueList.css({\n              left: left + 10,\n              top: top + 10\n            }).show();\n          });\n          attrElem = $(\"<li>\").addClass(\"axis_\" + i).append($(\"<span>\").addClass('pvtAttr').text(attr).data(\"attrName\", attr).append(triangleLink));\n          if (hasExcludedItem) {\n            attrElem.addClass('pvtFilteredAttribute');\n          }\n          return unused.append(attrElem).append(valueList);\n        };\n        for (i in shownInDragDrop) {\n          if (!hasProp.call(shownInDragDrop, i)) continue;\n          attr = shownInDragDrop[i];\n          fn1(attr);\n        }\n        tr1 = $(\"<tr>\").appendTo(uiTable);\n        aggregator = $(\"<select>\").addClass('pvtAggregator').bind(\"change\", function() {\n          return refresh();\n        });\n        ref1 = opts.aggregators;\n        for (x in ref1) {\n          if (!hasProp.call(ref1, x)) continue;\n          aggregator.append($(\"<option>\").val(x).html(x));\n        }\n        ordering = {\n          key_a_to_z: {\n            rowSymbol: \"&varr;\",\n            colSymbol: \"&harr;\",\n            next: \"value_a_to_z\"\n          },\n          value_a_to_z: {\n            rowSymbol: \"&darr;\",\n            colSymbol: \"&rarr;\",\n            next: \"value_z_to_a\"\n          },\n          value_z_to_a: {\n            rowSymbol: \"&uarr;\",\n            colSymbol: \"&larr;\",\n            next: \"key_a_to_z\"\n          }\n        };\n        rowOrderArrow = $(\"<a>\", {\n          role: \"button\"\n        }).addClass(\"pvtRowOrder\").data(\"order\", opts.rowOrder).html(ordering[opts.rowOrder].rowSymbol).bind(\"click\", function() {\n          $(this).data(\"order\", ordering[$(this).data(\"order\")].next);\n          $(this).html(ordering[$(this).data(\"order\")].rowSymbol);\n          return refresh();\n        });\n        colOrderArrow = $(\"<a>\", {\n          role: \"button\"\n        }).addClass(\"pvtColOrder\").data(\"order\", opts.colOrder).html(ordering[opts.colOrder].colSymbol).bind(\"click\", function() {\n          $(this).data(\"order\", ordering[$(this).data(\"order\")].next);\n          $(this).html(ordering[$(this).data(\"order\")].colSymbol);\n          return refresh();\n        });\n        $(\"<td>\").addClass('pvtVals pvtUiCell').appendTo(tr1).append(aggregator).append(rowOrderArrow).append(colOrderArrow).append($(\"<br>\"));\n        $(\"<td>\").addClass('pvtAxisContainer pvtHorizList pvtCols pvtUiCell').appendTo(tr1);\n        tr2 = $(\"<tr>\").appendTo(uiTable);\n        tr2.append($(\"<td>\").addClass('pvtAxisContainer pvtRows pvtUiCell').attr(\"valign\", \"top\"));\n        pivotTable = $(\"<td>\").attr(\"valign\", \"top\").addClass('pvtRendererArea').appendTo(tr2);\n        if (opts.unusedAttrsVertical === true || unusedAttrsVerticalAutoOverride) {\n          uiTable.find('tr:nth-child(1)').prepend(rendererControl);\n          uiTable.find('tr:nth-child(2)').prepend(unused);\n        } else {\n          uiTable.prepend($(\"<tr>\").append(rendererControl).append(unused));\n        }\n        this.html(uiTable);\n        ref2 = opts.cols;\n        for (n = 0, len2 = ref2.length; n < len2; n++) {\n          x = ref2[n];\n          this.find(\".pvtCols\").append(this.find(\".axis_\" + ($.inArray(x, shownInDragDrop))));\n        }\n        ref3 = opts.rows;\n        for (o = 0, len3 = ref3.length; o < len3; o++) {\n          x = ref3[o];\n          this.find(\".pvtRows\").append(this.find(\".axis_\" + ($.inArray(x, shownInDragDrop))));\n        }\n        if (opts.aggregatorName != null) {\n          this.find(\".pvtAggregator\").val(opts.aggregatorName);\n        }\n        if (opts.rendererName != null) {\n          this.find(\".pvtRenderer\").val(opts.rendererName);\n        }\n        if (!opts.showUI) {\n          this.find(\".pvtUiCell\").hide();\n        }\n        initialRender = true;\n        refreshDelayed = (function(_this) {\n          return function() {\n            var exclusions, inclusions, len4, newDropdown, numInputsToProcess, pivotUIOptions, pvtVals, ref4, ref5, subopts, t, u, unusedAttrsContainer, vals;\n            subopts = {\n              derivedAttributes: opts.derivedAttributes,\n              localeStrings: opts.localeStrings,\n              rendererOptions: opts.rendererOptions,\n              sorters: opts.sorters,\n              cols: [],\n              rows: [],\n              dataClass: opts.dataClass\n            };\n            numInputsToProcess = (ref4 = opts.aggregators[aggregator.val()]([])().numInputs) != null ? ref4 : 0;\n            vals = [];\n            _this.find(\".pvtRows li span.pvtAttr\").each(function() {\n              return subopts.rows.push($(this).data(\"attrName\"));\n            });\n            _this.find(\".pvtCols li span.pvtAttr\").each(function() {\n              return subopts.cols.push($(this).data(\"attrName\"));\n            });\n            _this.find(\".pvtVals select.pvtAttrDropdown\").each(function() {\n              if (numInputsToProcess === 0) {\n                return $(this).remove();\n              } else {\n                numInputsToProcess--;\n                if ($(this).val() !== \"\") {\n                  return vals.push($(this).val());\n                }\n              }\n            });\n            if (numInputsToProcess !== 0) {\n              pvtVals = _this.find(\".pvtVals\");\n              for (x = t = 0, ref5 = numInputsToProcess; 0 <= ref5 ? t < ref5 : t > ref5; x = 0 <= ref5 ? ++t : --t) {\n                newDropdown = $(\"<select>\").addClass('pvtAttrDropdown').append($(\"<option>\")).bind(\"change\", function() {\n                  return refresh();\n                });\n                for (u = 0, len4 = shownInAggregators.length; u < len4; u++) {\n                  attr = shownInAggregators[u];\n                  newDropdown.append($(\"<option>\").val(attr).text(attr));\n                }\n                pvtVals.append(newDropdown);\n              }\n            }\n            if (initialRender) {\n              vals = opts.vals;\n              i = 0;\n              _this.find(\".pvtVals select.pvtAttrDropdown\").each(function() {\n                $(this).val(vals[i]);\n                return i++;\n              });\n              initialRender = false;\n            }\n            subopts.aggregatorName = aggregator.val();\n            subopts.vals = vals;\n            subopts.aggregator = opts.aggregators[aggregator.val()](vals);\n            subopts.renderer = opts.renderers[renderer.val()];\n            subopts.rowOrder = rowOrderArrow.data(\"order\");\n            subopts.colOrder = colOrderArrow.data(\"order\");\n            exclusions = {};\n            _this.find('input.pvtFilter').not(':checked').each(function() {\n              var filter;\n              filter = $(this).data(\"filter\");\n              if (exclusions[filter[0]] != null) {\n                return exclusions[filter[0]].push(filter[1]);\n              } else {\n                return exclusions[filter[0]] = [filter[1]];\n              }\n            });\n            inclusions = {};\n            _this.find('input.pvtFilter:checked').each(function() {\n              var filter;\n              filter = $(this).data(\"filter\");\n              if (exclusions[filter[0]] != null) {\n                if (inclusions[filter[0]] != null) {\n                  return inclusions[filter[0]].push(filter[1]);\n                } else {\n                  return inclusions[filter[0]] = [filter[1]];\n                }\n              }\n            });\n            subopts.filter = function(record) {\n              var excludedItems, k, ref6, ref7;\n              if (!opts.filter(record)) {\n                return false;\n              }\n              for (k in exclusions) {\n                excludedItems = exclusions[k];\n                if (ref6 = \"\" + ((ref7 = record[k]) != null ? ref7 : 'null'), indexOf.call(excludedItems, ref6) >= 0) {\n                  return false;\n                }\n              }\n              return true;\n            };\n            pivotTable.pivot(materializedInput, subopts);\n            pivotUIOptions = $.extend({}, opts, {\n              cols: subopts.cols,\n              rows: subopts.rows,\n              colOrder: subopts.colOrder,\n              rowOrder: subopts.rowOrder,\n              vals: vals,\n              exclusions: exclusions,\n              inclusions: inclusions,\n              inclusionsInfo: inclusions,\n              aggregatorName: aggregator.val(),\n              rendererName: renderer.val()\n            });\n            _this.data(\"pivotUIOptions\", pivotUIOptions);\n            if (opts.autoSortUnusedAttrs) {\n              unusedAttrsContainer = _this.find(\"td.pvtUnused.pvtAxisContainer\");\n              $(unusedAttrsContainer).children(\"li\").sort(function(a, b) {\n                return naturalSort($(a).text(), $(b).text());\n              }).appendTo(unusedAttrsContainer);\n            }\n            pivotTable.css(\"opacity\", 1);\n            if (opts.onRefresh != null) {\n              return opts.onRefresh(pivotUIOptions);\n            }\n          };\n        })(this);\n        refresh = (function(_this) {\n          return function() {\n            pivotTable.css(\"opacity\", 0.5);\n            return setTimeout(refreshDelayed, 10);\n          };\n        })(this);\n        refresh();\n        this.find(\".pvtAxisContainer\").sortable({\n          update: function(e, ui) {\n            if (ui.sender == null) {\n              return refresh();\n            }\n          },\n          connectWith: this.find(\".pvtAxisContainer\"),\n          items: 'li',\n          placeholder: 'pvtPlaceholder'\n        });\n      } catch (error) {\n        e = error;\n        if (typeof console !== \"undefined\" && console !== null) {\n          console.error(e.stack);\n        }\n        this.html(opts.localeStrings.uiRenderError);\n      }\n      return this;\n    };\n\n    /*\n    Heatmap post-processing\n     */\n    $.fn.heatmap = function(scope, opts) {\n      var colorScaleGenerator, heatmapper, i, j, l, n, numCols, numRows, ref, ref1, ref2;\n      if (scope == null) {\n        scope = \"heatmap\";\n      }\n      numRows = this.data(\"numrows\");\n      numCols = this.data(\"numcols\");\n      colorScaleGenerator = opts != null ? (ref = opts.heatmap) != null ? ref.colorScaleGenerator : void 0 : void 0;\n      if (colorScaleGenerator == null) {\n        colorScaleGenerator = function(values) {\n          var max, min;\n          min = Math.min.apply(Math, values);\n          max = Math.max.apply(Math, values);\n          return function(x) {\n            var nonRed;\n            nonRed = 255 - Math.round(255 * (x - min) / (max - min));\n            return \"rgb(255,\" + nonRed + \",\" + nonRed + \")\";\n          };\n        };\n      }\n      heatmapper = (function(_this) {\n        return function(scope) {\n          var colorScale, forEachCell, values;\n          forEachCell = function(f) {\n            return _this.find(scope).each(function() {\n              var x;\n              x = $(this).data(\"value\");\n              if ((x != null) && isFinite(x)) {\n                return f(x, $(this));\n              }\n            });\n          };\n          values = [];\n          forEachCell(function(x) {\n            return values.push(x);\n          });\n          colorScale = colorScaleGenerator(values);\n          return forEachCell(function(x, elem) {\n            return elem.css(\"background-color\", colorScale(x));\n          });\n        };\n      })(this);\n      switch (scope) {\n        case \"heatmap\":\n          heatmapper(\".pvtVal\");\n          break;\n        case \"rowheatmap\":\n          for (i = l = 0, ref1 = numRows; 0 <= ref1 ? l < ref1 : l > ref1; i = 0 <= ref1 ? ++l : --l) {\n            heatmapper(\".pvtVal.row\" + i);\n          }\n          break;\n        case \"colheatmap\":\n          for (j = n = 0, ref2 = numCols; 0 <= ref2 ? n < ref2 : n > ref2; j = 0 <= ref2 ? ++n : --n) {\n            heatmapper(\".pvtVal.col\" + j);\n          }\n      }\n      heatmapper(\".pvtTotal.rowTotal\");\n      heatmapper(\".pvtTotal.colTotal\");\n      return this;\n    };\n\n    /*\n    Barchart post-processing\n     */\n    return $.fn.barchart = function(opts) {\n      var barcharter, i, l, numCols, numRows, ref;\n      numRows = this.data(\"numrows\");\n      numCols = this.data(\"numcols\");\n      barcharter = (function(_this) {\n        return function(scope) {\n          var forEachCell, max, min, range, scaler, values;\n          forEachCell = function(f) {\n            return _this.find(scope).each(function() {\n              var x;\n              x = $(this).data(\"value\");\n              if ((x != null) && isFinite(x)) {\n                return f(x, $(this));\n              }\n            });\n          };\n          values = [];\n          forEachCell(function(x) {\n            return values.push(x);\n          });\n          max = Math.max.apply(Math, values);\n          if (max < 0) {\n            max = 0;\n          }\n          range = max;\n          min = Math.min.apply(Math, values);\n          if (min < 0) {\n            range = max - min;\n          }\n          scaler = function(x) {\n            return 100 * x / (1.4 * range);\n          };\n          return forEachCell(function(x, elem) {\n            var bBase, bgColor, text, wrapper;\n            text = elem.text();\n            wrapper = $(\"<div>\").css({\n              \"position\": \"relative\",\n              \"height\": \"55px\"\n            });\n            bgColor = \"gray\";\n            bBase = 0;\n            if (min < 0) {\n              bBase = scaler(-min);\n            }\n            if (x < 0) {\n              bBase += scaler(x);\n              bgColor = \"darkred\";\n              x = -x;\n            }\n            wrapper.append($(\"<div>\").css({\n              \"position\": \"absolute\",\n              \"bottom\": bBase + \"%\",\n              \"left\": 0,\n              \"right\": 0,\n              \"height\": scaler(x) + \"%\",\n              \"background-color\": bgColor\n            }));\n            wrapper.append($(\"<div>\").text(text).css({\n              \"position\": \"relative\",\n              \"padding-left\": \"5px\",\n              \"padding-right\": \"5px\"\n            }));\n            return elem.css({\n              \"padding\": 0,\n              \"padding-top\": \"5px\",\n              \"text-align\": \"center\"\n            }).html(wrapper);\n          });\n        };\n      })(this);\n      for (i = l = 0, ref = numRows; 0 <= ref ? l < ref : l > ref; i = 0 <= ref ? ++l : --l) {\n        barcharter(\".pvtVal.row\" + i);\n      }\n      barcharter(\".pvtTotal.colTotal\");\n      return this;\n    };\n  });\n\n}).call(this);\n\n//# sourceMappingURL=pivot.js.map\n"]}
\ No newline at end of file
+{"version":3,"sources":["pivot.coffee","pivot.min.js"],"names":["callWithJQuery","indexOf","item","i","l","this","length","slice","bind","fn","me","apply","arguments","hasProp","hasOwnProperty","pivotModule","exports","module","require","define","amd","jQuery","$","PivotData","addSeparators","aggregatorTemplates","aggregators","dayNamesEn","derivers","getSort","locales","mthNamesEn","naturalSort","numberFormat","pivotTableRenderer","rd","renderers","rx","rz","sortAs","usFmt","usFmtInt","usFmtPct","zeroPad","nStr","thousandsSep","decimalSep","rgx","x","x1","x2","split","test","replace","opts","defaults","digitsAfterDecimal","scaler","prefix","suffix","extend","result","isNaN","isFinite","toFixed","count","formatter","data","rowKey","colKey","push","value","format","uniques","arg","attr","uniq","record","ref","call","numInputs","sum","parseFloat","extremes","mode","val","sorter","sorters","ref1","ref2","Math","quantile","q","vals","sort","a","b","floor","ceil","runningStat","ddof","n","m","s","m_new","sqrt","sumOverSum","denom","num","sumNum","sumDenom","sumOverSumBound80","upper","sign","fractionOf","wrapped","type","selector","total","row","col","inner","getAggregator","countUnique","f","listUnique","join","max","min","first","last","median","average","stdev","tpl","Count","Count Unique Values","List Unique Values","Sum","Integer Sum","Average","Median","Sample Variance","Sample Standard Deviation","Minimum","Maximum","First","Last","Sum over Sum","80% Upper Bound","80% Lower Bound","Sum as Fraction of Total","Sum as Fraction of Rows","Sum as Fraction of Columns","Count as Fraction of Total","Count as Fraction of Rows","Count as Fraction of Columns","Table","Table Barchart","barchart","Heatmap","heatmap","Row Heatmap","Col Heatmap","en","localeStrings","renderError","computeError","uiRenderError","selectAll","selectNone","tooMany","filterResults","cancel","totals","vs","by","number","substr","bin","binWidth","dateFormat","formatString","utcOutput","mthNames","dayNames","utc","date","Date","parse","p","_this","as","bs","a1","b1","nas","nbs","numDiff","String","match","shift","order","l_mapping","mapping","toLowerCase","isFunction","input","ref3","ref4","ref5","ref6","ref7","ref8","ref9","getRowKeys","getColKeys","sortKeys","arrSort","aggregator","aggregatorName","colAttrs","cols","rowAttrs","rows","valAttrs","rowOrder","colOrder","derivedAttributes","filter","tree","rowKeys","colKeys","rowTotals","colTotals","allTotal","sorted","forEachRecord","processRecord","addRecord","compactRecord","j","k","len1","results","results1","tblCols","isEmptyObject","v","isArray","each","text","Error","prototype","forEachMatchingRecord","criteria","callback","attrs","sortersArr","comparison","r","c","flatColKey","flatRowKey","len2","fromCharCode","agg","pivotUtilities","pivotData","getClickHandler","spanSize","tbody","td","th","thead","totalAggregator","tr","txt","table","clickCallback","rowValues","colValues","filters","e","document","createElement","className","arr","len","noDraw","stop","parseInt","setAttribute","appendChild","textContent","innerHTML","onclick","pivot","inputOpts","locale","localeDefaults","dataClass","renderer","rendererOptions","error","console","stack","html","hasChildNodes","removeChild","lastChild","append","pivotUI","overwrite","attrLength","attrValues","colOrderArrow","existingOpts","fn1","initialRender","len3","materializedInput","o","ordering","pivotTable","recordsProcessed","refresh","refreshDelayed","rendererControl","rowOrderArrow","shownAttributes","shownInAggregators","shownInDragDrop","tr1","tr2","uiTable","unused","unusedAttrsVerticalAutoCutoff","unusedAttrsVerticalAutoOverride","hiddenAttributes","hiddenFromAggregators","hiddenFromDragDrop","menuLimit","exclusions","inclusions","unusedAttrsVertical","autoSortUnusedAttrs","onRefresh","showUI","base","class","addClass","appendTo","attrElem","checkContainer","closeFilterBox","controls","filterItem","filterItemExcluded","finalButtons","hasExcludedItem","placeholder","triangleLink","valueCount","valueList","values","hide","accept","accept_gen","trim","accepted","real_filter","substring","find","parent","show","prop","toggleClass","removeClass","left","top","currentTarget","position","css","key_a_to_z","rowSymbol","colSymbol","next","value_a_to_z","value_z_to_a","role","prepend","inArray","rendererName","len4","newDropdown","numInputsToProcess","pivotUIOptions","pvtVals","subopts","t","u","unusedAttrsContainer","remove","not","excludedItems","inclusionsInfo","children","setTimeout","sortable","update","ui","sender","connectWith","items","scope","colorScaleGenerator","heatmapper","numCols","numRows","nonRed","round","colorScale","forEachCell","elem","barcharter","range","bBase","bgColor","wrapper","height","bottom","right","background-color","padding-left","padding-right","padding","padding-top","text-align"],"mappings":"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","file":"pivot.min.js","sourcesContent":["callWithJQuery = (pivotModule) ->\n    if typeof exports is \"object\" and typeof module is \"object\" # CommonJS\n        pivotModule require(\"jquery\")\n    else if typeof define is \"function\" and define.amd # AMD\n        define [\"jquery\"], pivotModule\n    # Plain browser env\n    else\n        pivotModule jQuery\n\ncallWithJQuery ($) ->\n\n    ###\n    Utilities\n    ###\n\n    addSeparators = (nStr, thousandsSep, decimalSep) ->\n        nStr += ''\n        x = nStr.split('.')\n        x1 = x[0]\n        x2 = if x.length > 1 then  decimalSep + x[1] else ''\n        rgx = /(\\d+)(\\d{3})/\n        x1 = x1.replace(rgx, '$1' + thousandsSep + '$2') while rgx.test(x1)\n        return x1 + x2\n\n    numberFormat = (opts) ->\n        defaults =\n            digitsAfterDecimal: 2, scaler: 1,\n            thousandsSep: \",\", decimalSep: \".\"\n            prefix: \"\", suffix: \"\"\n        opts = $.extend({}, defaults, opts)\n        (x) ->\n            return \"\" if isNaN(x) or not isFinite(x)\n            result = addSeparators (opts.scaler*x).toFixed(opts.digitsAfterDecimal), opts.thousandsSep, opts.decimalSep\n            return \"\"+opts.prefix+result+opts.suffix\n\n    #aggregator templates default to US number formatting but this is overrideable\n    usFmt = numberFormat()\n    usFmtInt = numberFormat(digitsAfterDecimal: 0)\n    usFmtPct = numberFormat(digitsAfterDecimal:1, scaler: 100, suffix: \"%\")\n\n    aggregatorTemplates =\n        count: (formatter=usFmtInt) -> () -> (data, rowKey, colKey) ->\n            count: 0\n            push:  -> @count++\n            value: -> @count\n            format: formatter\n\n        uniques: (fn, formatter=usFmtInt) -> ([attr]) -> (data, rowKey, colKey) ->\n            uniq: []\n            push: (record) -> @uniq.push(record[attr]) if record[attr] not in @uniq\n            value: -> fn(@uniq)\n            format: formatter\n            numInputs: if attr? then 0 else 1\n\n        sum: (formatter=usFmt) -> ([attr]) -> (data, rowKey, colKey) ->\n            sum: 0\n            push: (record) -> @sum += parseFloat(record[attr]) if not isNaN parseFloat(record[attr])\n            value: -> @sum\n            format: formatter\n            numInputs: if attr? then 0 else 1\n\n        extremes: (mode, formatter=usFmt) -> ([attr]) -> (data, rowKey, colKey) ->\n            val: null\n            sorter: getSort(data?.sorters, attr)\n            push: (record) ->\n                x = record[attr]\n                if mode in [\"min\", \"max\"]\n                    x = parseFloat(x)\n                    if not isNaN x then @val = Math[mode](x, @val ? x)\n                if mode == \"first\" then @val = x if @sorter(x, @val ? x) <= 0\n                if mode == \"last\"  then @val = x if @sorter(x, @val ? x) >= 0\n            value: -> @val\n            format: (x) -> if isNaN(x) then x else formatter(x)\n            numInputs: if attr? then 0 else 1\n\n        quantile: (q, formatter=usFmt) -> ([attr]) -> (data, rowKey, colKey) ->\n            vals: []\n            push: (record) ->\n                x = parseFloat(record[attr])\n                @vals.push(x) if not isNaN(x)\n            value: ->\n                return null if @vals.length == 0\n                @vals.sort((a,b) -> a-b)\n                i = (@vals.length-1)*q\n                return (@vals[Math.floor(i)] + @vals[Math.ceil(i)])/2.0\n            format: formatter\n            numInputs: if attr? then 0 else 1\n\n        runningStat: (mode=\"mean\", ddof=1, formatter=usFmt) -> ([attr]) -> (data, rowKey, colKey) ->\n            n: 0.0, m: 0.0, s: 0.0\n            push: (record) ->\n                x = parseFloat(record[attr])\n                return if isNaN(x)\n                @n += 1.0\n                if @n == 1.0\n                    @m = x\n                else\n                    m_new = @m + (x - @m)/@n\n                    @s = @s + (x - @m)*(x - m_new)\n                    @m = m_new\n            value: ->\n                if mode == \"mean\"\n                    return if @n == 0 then 0/0 else @m\n                return 0 if @n <= ddof\n                switch mode\n                    when \"var\"   then @s/(@n-ddof)\n                    when \"stdev\" then Math.sqrt(@s/(@n-ddof))\n            format: formatter\n            numInputs: if attr? then 0 else 1\n\n        sumOverSum: (formatter=usFmt) -> ([num, denom]) -> (data, rowKey, colKey) ->\n            sumNum: 0\n            sumDenom: 0\n            push: (record) ->\n                @sumNum   += parseFloat(record[num])   if not isNaN parseFloat(record[num])\n                @sumDenom += parseFloat(record[denom]) if not isNaN parseFloat(record[denom])\n            value: -> @sumNum/@sumDenom\n            format: formatter\n            numInputs: if num? and denom? then 0 else 2\n\n        sumOverSumBound80: (upper=true, formatter=usFmt) -> ([num, denom]) -> (data, rowKey, colKey) ->\n            sumNum: 0\n            sumDenom: 0\n            push: (record) ->\n                @sumNum   += parseFloat(record[num])   if not isNaN parseFloat(record[num])\n                @sumDenom += parseFloat(record[denom]) if not isNaN parseFloat(record[denom])\n            value: ->\n                sign = if upper then 1 else -1\n                (0.821187207574908/@sumDenom + @sumNum/@sumDenom + 1.2815515655446004*sign*\n                    Math.sqrt(0.410593603787454/ (@sumDenom*@sumDenom) + (@sumNum*(1 - @sumNum/ @sumDenom))/ (@sumDenom*@sumDenom)))/\n                    (1 + 1.642374415149816/@sumDenom)\n            format: formatter\n            numInputs: if num? and denom? then 0 else 2\n\n        fractionOf: (wrapped, type=\"total\", formatter=usFmtPct) -> (x...) -> (data, rowKey, colKey) ->\n            selector: {total:[[],[]],row:[rowKey,[]],col:[[],colKey]}[type]\n            inner: wrapped(x...)(data, rowKey, colKey)\n            push: (record) -> @inner.push record\n            format: formatter\n            value: -> @inner.value() / data.getAggregator(@selector...).inner.value()\n            numInputs: wrapped(x...)().numInputs\n\n    aggregatorTemplates.countUnique = (f) -> aggregatorTemplates.uniques(((x) -> x.length), f)\n    aggregatorTemplates.listUnique =  (s) -> aggregatorTemplates.uniques(((x) -> x.sort(naturalSort).join(s)), ((x)->x))\n    aggregatorTemplates.max =         (f) -> aggregatorTemplates.extremes('max', f)\n    aggregatorTemplates.min =         (f) -> aggregatorTemplates.extremes('min', f)\n    aggregatorTemplates.first =       (f) -> aggregatorTemplates.extremes('first', f)\n    aggregatorTemplates.last =        (f) -> aggregatorTemplates.extremes('last', f)\n    aggregatorTemplates.median =      (f) -> aggregatorTemplates.quantile(0.5, f)\n    aggregatorTemplates.average =     (f) -> aggregatorTemplates.runningStat(\"mean\", 1, f)\n    aggregatorTemplates.var =         (ddof, f) -> aggregatorTemplates.runningStat(\"var\", ddof, f)\n    aggregatorTemplates.stdev =       (ddof, f) -> aggregatorTemplates.runningStat(\"stdev\", ddof, f)\n\n    #default aggregators & renderers use US naming and number formatting\n    aggregators = do (tpl = aggregatorTemplates) ->\n        \"Count\":                tpl.count(usFmtInt)\n        \"Count Unique Values\":  tpl.countUnique(usFmtInt)\n        \"List Unique Values\":   tpl.listUnique(\", \")\n        \"Sum\":                  tpl.sum(usFmt)\n        \"Integer Sum\":          tpl.sum(usFmtInt)\n        \"Average\":              tpl.average(usFmt)\n        \"Median\":               tpl.median(usFmt)\n        \"Sample Variance\":      tpl.var(1, usFmt)\n        \"Sample Standard Deviation\": tpl.stdev(1, usFmt)\n        \"Minimum\":              tpl.min(usFmt)\n        \"Maximum\":              tpl.max(usFmt)\n        \"First\":                tpl.first(usFmt)\n        \"Last\":                 tpl.last(usFmt)\n        \"Sum over Sum\":         tpl.sumOverSum(usFmt)\n        \"80% Upper Bound\":      tpl.sumOverSumBound80(true, usFmt)\n        \"80% Lower Bound\":      tpl.sumOverSumBound80(false, usFmt)\n        \"Sum as Fraction of Total\":     tpl.fractionOf(tpl.sum(),   \"total\", usFmtPct)\n        \"Sum as Fraction of Rows\":      tpl.fractionOf(tpl.sum(),   \"row\",   usFmtPct)\n        \"Sum as Fraction of Columns\":   tpl.fractionOf(tpl.sum(),   \"col\",   usFmtPct)\n        \"Count as Fraction of Total\":   tpl.fractionOf(tpl.count(), \"total\", usFmtPct)\n        \"Count as Fraction of Rows\":    tpl.fractionOf(tpl.count(), \"row\",   usFmtPct)\n        \"Count as Fraction of Columns\": tpl.fractionOf(tpl.count(), \"col\",   usFmtPct)\n\n    renderers =\n        \"Table\":          (data, opts) ->   pivotTableRenderer(data, opts)\n        \"Table Barchart\": (data, opts) -> $(pivotTableRenderer(data, opts)).barchart()\n        \"Heatmap\":        (data, opts) -> $(pivotTableRenderer(data, opts)).heatmap(\"heatmap\",    opts)\n        \"Row Heatmap\":    (data, opts) -> $(pivotTableRenderer(data, opts)).heatmap(\"rowheatmap\", opts)\n        \"Col Heatmap\":    (data, opts) -> $(pivotTableRenderer(data, opts)).heatmap(\"colheatmap\", opts)\n\n    locales =\n        en:\n            aggregators: aggregators\n            renderers: renderers\n            localeStrings:\n                renderError: \"An error occurred rendering the PivotTable results.\"\n                computeError: \"An error occurred computing the PivotTable results.\"\n                uiRenderError: \"An error occurred rendering the PivotTable UI.\"\n                selectAll: \"Select All\"\n                selectNone: \"Select None\"\n                tooMany: \"(too many to list)\"\n                filterResults: \"Filter values\"\n                apply: \"Apply\"\n                cancel: \"Cancel\"\n                totals: \"Totals\" #for table renderer\n                vs: \"vs\" #for gchart renderer\n                by: \"by\" #for gchart renderer\n\n    #dateFormat deriver l10n requires month and day names to be passed in directly\n    mthNamesEn = [\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"]\n    dayNamesEn = [\"Sun\",\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\"]\n    zeroPad = (number) -> (\"0\"+number).substr(-2,2)\n\n    derivers =\n        bin: (col, binWidth) -> (record) -> record[col] - record[col] % binWidth\n        dateFormat: (col, formatString, utcOutput=false, mthNames=mthNamesEn, dayNames=dayNamesEn) ->\n            utc = if utcOutput then \"UTC\" else \"\"\n            (record) -> #thanks http://stackoverflow.com/a/12213072/112871\n                date = new Date(Date.parse(record[col]))\n                if isNaN(date) then return \"\"\n                formatString.replace /%(.)/g, (m, p) ->\n                    switch p\n                        when \"y\" then date[\"get#{utc}FullYear\"]()\n                        when \"m\" then zeroPad(date[\"get#{utc}Month\"]()+1)\n                        when \"n\" then mthNames[date[\"get#{utc}Month\"]()]\n                        when \"d\" then zeroPad(date[\"get#{utc}Date\"]())\n                        when \"w\" then dayNames[date[\"get#{utc}Day\"]()]\n                        when \"x\" then date[\"get#{utc}Day\"]()\n                        when \"H\" then zeroPad(date[\"get#{utc}Hours\"]())\n                        when \"M\" then zeroPad(date[\"get#{utc}Minutes\"]())\n                        when \"S\" then zeroPad(date[\"get#{utc}Seconds\"]())\n                        else \"%\" + p\n\n    rx = /(\\d+)|(\\D+)/g\n    rd = /\\d/\n    rz = /^0/\n    naturalSort = (as, bs) =>\n        #nulls first\n        return -1 if bs? and not as?\n        return  1 if as? and not bs?\n\n        #then raw NaNs\n        return -1 if typeof as == \"number\" and isNaN(as)\n        return  1 if typeof bs == \"number\" and isNaN(bs)\n\n        #numbers and numbery strings group together\n        nas = +as\n        nbs = +bs\n        return -1 if nas < nbs\n        return  1 if nas > nbs\n\n        #within that, true numbers before numbery strings\n        return -1 if typeof as == \"number\" and typeof bs != \"number\"\n        return  1 if typeof bs == \"number\" and typeof as != \"number\"\n        return  0 if typeof as == \"number\" and typeof bs == \"number\"\n\n        # 'Infinity' is a textual number, so less than 'A'\n        return -1 if isNaN(nbs) and not isNaN(nas)\n        return  1 if isNaN(nas) and not isNaN(nbs)\n\n        #finally, \"smart\" string sorting per http://stackoverflow.com/a/4373421/112871\n        a = String(as)\n        b = String(bs)\n        return 0 if a == b\n        return (if a > b then 1 else -1) unless rd.test(a) and rd.test(b)\n\n        #special treatment for strings containing digits\n        a = a.match(rx) #create digits vs non-digit chunks and iterate through\n        b = b.match(rx)\n        while a.length and b.length\n            a1 = a.shift()\n            b1 = b.shift()\n            if a1 != b1\n                if rd.test(a1) and rd.test(b1) #both are digit chunks\n                    numDiff = a1.replace(rz, \".0\") - b1.replace(rz, \".0\")\n                    return if numDiff != 0 then numDiff else a1.length - b1.length\n                else\n                    return (if a1 > b1 then 1 else -1)\n        return a.length - b.length\n\n    sortAs = (order) ->\n        mapping = {}\n        l_mapping = {} # sort lowercased keys similarly\n        for i, x of order\n            mapping[x] = i\n            l_mapping[x.toLowerCase()] = i if typeof x == \"string\"\n        (a, b) ->\n            if mapping[a]? and mapping[b]? then mapping[a] - mapping[b]\n            else if mapping[a]? then -1\n            else if mapping[b]? then 1\n            else if l_mapping[a]? and l_mapping[b]? then l_mapping[a] - l_mapping[b]\n            else if l_mapping[a]? then -1\n            else if l_mapping[b]? then 1\n            else naturalSort(a,b)\n\n    getSort = (sorters, attr) ->\n        if sorters?\n            if $.isFunction(sorters)\n                sort = sorters(attr)\n                return sort if $.isFunction(sort)\n            else if sorters[attr]?\n                return sorters[attr]\n        return naturalSort\n\n    ###\n    Data Model class\n    ###\n\n    class PivotData\n        constructor: (input, opts = {}) ->\n            @input = input\n            @aggregator = opts.aggregator ? aggregatorTemplates.count()()\n            @aggregatorName = opts.aggregatorName ? \"Count\"\n            @colAttrs = opts.cols ? []\n            @rowAttrs = opts.rows ? []\n            @valAttrs = opts.vals ? []\n            @sorters = opts.sorters ? {}\n            @rowOrder = opts.rowOrder ? \"key_a_to_z\"\n            @colOrder = opts.colOrder ? \"key_a_to_z\"\n            @derivedAttributes = opts.derivedAttributes ? {}\n            @filter = opts.filter ? (-> true)\n            @tree = {}\n            @rowKeys = []\n            @colKeys = []\n            @rowTotals = {}\n            @colTotals = {}\n            @allTotal = @aggregator(this, [], [])\n            @sorted = false\n\n            # iterate through input, accumulating data for cells\n            PivotData.forEachRecord @input, @derivedAttributes, (record) =>\n                @processRecord(record) if @filter(record)\n\n        #can handle arrays or jQuery selections of tables\n        @forEachRecord = (input, derivedAttributes, f) ->\n            if $.isEmptyObject derivedAttributes\n                addRecord = f\n            else\n                addRecord = (record) ->\n                    record[k] = v(record) ? record[k] for k, v of derivedAttributes\n                    f(record)\n\n            #if it's a function, have it call us back\n            if $.isFunction(input)\n                input(addRecord)\n            else if $.isArray(input)\n                if $.isArray(input[0]) #array of arrays\n                    for own i, compactRecord of input when i > 0\n                        record = {}\n                        record[k] = compactRecord[j] for own j, k of input[0]\n                        addRecord(record)\n                else #array of objects\n                    addRecord(record) for record in input\n            else if input instanceof $\n                tblCols = []\n                $(\"thead > tr > th\", input).each (i) -> tblCols.push $(this).text()\n                $(\"tbody > tr\", input).each (i) ->\n                    record = {}\n                    $(\"td\", this).each (j) -> record[tblCols[j]] = $(this).text()\n                    addRecord(record)\n            else\n                throw new Error(\"unknown input format\")\n\n        forEachMatchingRecord: (criteria, callback) ->\n            PivotData.forEachRecord @input, @derivedAttributes, (record) =>\n                return if not @filter(record)\n                for k, v of criteria\n                    return if v != (record[k] ? \"null\")\n                callback(record)\n\n        arrSort: (attrs) =>\n            sortersArr = (getSort(@sorters, a) for a in attrs)\n            (a,b) ->\n                for own i, sorter of sortersArr\n                    comparison = sorter(a[i], b[i])\n                    return comparison if comparison != 0\n                return 0\n\n        sortKeys: () =>\n            if not @sorted\n                @sorted = true\n                v = (r,c) => @getAggregator(r,c).value()\n                switch @rowOrder\n                    when \"value_a_to_z\"  then @rowKeys.sort (a,b) =>  naturalSort v(a,[]), v(b,[])\n                    when \"value_z_to_a\" then @rowKeys.sort (a,b) => -naturalSort v(a,[]), v(b,[])\n                    else             @rowKeys.sort @arrSort(@rowAttrs)\n                switch @colOrder\n                    when \"value_a_to_z\"  then @colKeys.sort (a,b) =>  naturalSort v([],a), v([],b)\n                    when \"value_z_to_a\" then @colKeys.sort (a,b) => -naturalSort v([],a), v([],b)\n                    else             @colKeys.sort @arrSort(@colAttrs)\n\n        getColKeys: () =>\n            @sortKeys()\n            return @colKeys\n\n        getRowKeys: () =>\n            @sortKeys()\n            return @rowKeys\n\n        processRecord: (record) -> #this code is called in a tight loop\n            colKey = []\n            rowKey = []\n            colKey.push record[x] ? \"null\" for x in @colAttrs\n            rowKey.push record[x] ? \"null\" for x in @rowAttrs\n            flatRowKey = rowKey.join(String.fromCharCode(0))\n            flatColKey = colKey.join(String.fromCharCode(0))\n\n            @allTotal.push record\n\n            if rowKey.length != 0\n                if not @rowTotals[flatRowKey]\n                    @rowKeys.push rowKey\n                    @rowTotals[flatRowKey] = @aggregator(this, rowKey, [])\n                @rowTotals[flatRowKey].push record\n\n            if colKey.length != 0\n                if not @colTotals[flatColKey]\n                    @colKeys.push colKey\n                    @colTotals[flatColKey] = @aggregator(this, [], colKey)\n                @colTotals[flatColKey].push record\n\n            if colKey.length != 0 and rowKey.length != 0\n                if not @tree[flatRowKey]\n                    @tree[flatRowKey] = {}\n                if not @tree[flatRowKey][flatColKey]\n                    @tree[flatRowKey][flatColKey] = @aggregator(this, rowKey, colKey)\n                @tree[flatRowKey][flatColKey].push record\n\n        getAggregator: (rowKey, colKey) =>\n            flatRowKey = rowKey.join(String.fromCharCode(0))\n            flatColKey = colKey.join(String.fromCharCode(0))\n            if rowKey.length == 0 and colKey.length == 0\n                agg = @allTotal\n            else if rowKey.length == 0\n                agg = @colTotals[flatColKey]\n            else if colKey.length == 0\n                agg = @rowTotals[flatRowKey]\n            else\n                agg = @tree[flatRowKey][flatColKey]\n            return agg ? {value: (-> null), format: -> \"\"}\n\n    #expose these to the outside world\n    $.pivotUtilities = {aggregatorTemplates, aggregators, renderers, derivers, locales,\n        naturalSort, numberFormat, sortAs, PivotData}\n\n    ###\n    Default Renderer for hierarchical table layout\n    ###\n\n    pivotTableRenderer = (pivotData, opts) ->\n\n        defaults =\n            table:\n                clickCallback: null\n                rowTotals: true\n                colTotals: true\n            localeStrings: totals: \"Totals\"\n\n        opts = $.extend(true, {}, defaults, opts)\n\n        colAttrs = pivotData.colAttrs\n        rowAttrs = pivotData.rowAttrs\n        rowKeys = pivotData.getRowKeys()\n        colKeys = pivotData.getColKeys()\n\n        if opts.table.clickCallback\n            getClickHandler = (value, rowValues, colValues) ->\n                filters = {}\n                filters[attr] = colValues[i] for own i, attr of colAttrs when colValues[i]?\n                filters[attr] = rowValues[i] for own i, attr of rowAttrs when rowValues[i]?\n                return (e) -> opts.table.clickCallback(e, value, filters, pivotData)\n\n        #now actually build the output\n        result = document.createElement(\"table\")\n        result.className = \"pvtTable\"\n\n        #helper function for setting row/col-span in pivotTableRenderer\n        spanSize = (arr, i, j) ->\n            if i != 0\n                noDraw = true\n                for x in [0..j]\n                    if arr[i-1][x] != arr[i][x]\n                        noDraw = false\n                if noDraw\n                  return -1 #do not draw cell\n            len = 0\n            while i+len < arr.length\n                stop = false\n                for x in [0..j]\n                    stop = true if arr[i][x] != arr[i+len][x]\n                break if stop\n                len++\n            return len\n\n        #the first few rows are for col headers\n        thead = document.createElement(\"thead\")\n        for own j, c of colAttrs\n            tr = document.createElement(\"tr\")\n            if parseInt(j) == 0 and rowAttrs.length != 0\n                th = document.createElement(\"th\")\n                th.setAttribute(\"colspan\", rowAttrs.length)\n                th.setAttribute(\"rowspan\", colAttrs.length)\n                tr.appendChild th\n            th = document.createElement(\"th\")\n            th.className = \"pvtAxisLabel\"\n            th.textContent = c\n            tr.appendChild th\n            for own i, colKey of colKeys\n                x = spanSize(colKeys, parseInt(i), parseInt(j))\n                if x != -1\n                    th = document.createElement(\"th\")\n                    th.className = \"pvtColLabel\"\n                    th.textContent = colKey[j]\n                    th.setAttribute(\"colspan\", x)\n                    if parseInt(j) == colAttrs.length-1 and rowAttrs.length != 0\n                        th.setAttribute(\"rowspan\", 2)\n                    tr.appendChild th\n            if parseInt(j) == 0 && opts.table.rowTotals\n                th = document.createElement(\"th\")\n                th.className = \"pvtTotalLabel pvtRowTotalLabel\"\n                th.innerHTML = opts.localeStrings.totals\n                th.setAttribute(\"rowspan\", colAttrs.length + (if rowAttrs.length ==0 then 0 else 1))\n                tr.appendChild th\n            thead.appendChild tr\n\n        #then a row for row header headers\n        if rowAttrs.length !=0\n            tr = document.createElement(\"tr\")\n            for own i, r of rowAttrs\n                th = document.createElement(\"th\")\n                th.className = \"pvtAxisLabel\"\n                th.textContent = r\n                tr.appendChild th\n            th = document.createElement(\"th\")\n            if colAttrs.length ==0\n                th.className = \"pvtTotalLabel pvtRowTotalLabel\"\n                th.innerHTML = opts.localeStrings.totals\n            tr.appendChild th\n            thead.appendChild tr\n        result.appendChild thead\n\n        #now the actual data rows, with their row headers and totals\n        tbody = document.createElement(\"tbody\")\n        for own i, rowKey of rowKeys\n            tr = document.createElement(\"tr\")\n            for own j, txt of rowKey\n                x = spanSize(rowKeys, parseInt(i), parseInt(j))\n                if x != -1\n                    th = document.createElement(\"th\")\n                    th.className = \"pvtRowLabel\"\n                    th.textContent = txt\n                    th.setAttribute(\"rowspan\", x)\n                    if parseInt(j) == rowAttrs.length-1 and colAttrs.length !=0\n                        th.setAttribute(\"colspan\",2)\n                    tr.appendChild th\n            for own j, colKey of colKeys #this is the tight loop\n                aggregator = pivotData.getAggregator(rowKey, colKey)\n                val = aggregator.value()\n                td = document.createElement(\"td\")\n                td.className = \"pvtVal row#{i} col#{j}\"\n                td.textContent = aggregator.format(val)\n                td.setAttribute(\"data-value\", val)\n                if getClickHandler?\n                    td.onclick = getClickHandler(val, rowKey, colKey)\n                tr.appendChild td\n\n            if opts.table.rowTotals || colAttrs.length == 0\n                totalAggregator = pivotData.getAggregator(rowKey, [])\n                val = totalAggregator.value()\n                td = document.createElement(\"td\")\n                td.className = \"pvtTotal rowTotal\"\n                td.textContent = totalAggregator.format(val)\n                td.setAttribute(\"data-value\", val)\n                if getClickHandler?\n                    td.onclick = getClickHandler(val, rowKey, [])\n                td.setAttribute(\"data-for\", \"row\"+i)\n                tr.appendChild td\n            tbody.appendChild tr\n\n        #finally, the row for col totals, and a grand total\n        if opts.table.colTotals || rowAttrs.length == 0\n            tr = document.createElement(\"tr\")\n            if opts.table.colTotals || rowAttrs.length == 0\n                th = document.createElement(\"th\")\n                th.className = \"pvtTotalLabel pvtColTotalLabel\"\n                th.innerHTML = opts.localeStrings.totals\n                th.setAttribute(\"colspan\", rowAttrs.length + (if colAttrs.length == 0 then 0 else 1))\n                tr.appendChild th\n            for own j, colKey of colKeys\n                totalAggregator = pivotData.getAggregator([], colKey)\n                val = totalAggregator.value()\n                td = document.createElement(\"td\")\n                td.className = \"pvtTotal colTotal\"\n                td.textContent = totalAggregator.format(val)\n                td.setAttribute(\"data-value\", val)\n                if getClickHandler?\n                    td.onclick = getClickHandler(val, [], colKey)\n                td.setAttribute(\"data-for\", \"col\"+j)\n                tr.appendChild td\n            if opts.table.rowTotals || colAttrs.length == 0\n                totalAggregator = pivotData.getAggregator([], [])\n                val = totalAggregator.value()\n                td = document.createElement(\"td\")\n                td.className = \"pvtGrandTotal\"\n                td.textContent = totalAggregator.format(val)\n                td.setAttribute(\"data-value\", val)\n                if getClickHandler?\n                    td.onclick = getClickHandler(val, [], [])\n                tr.appendChild td\n            tbody.appendChild tr\n        result.appendChild tbody\n\n        #squirrel this away for later\n        result.setAttribute(\"data-numrows\", rowKeys.length)\n        result.setAttribute(\"data-numcols\", colKeys.length)\n\n        return result\n\n    ###\n    Pivot Table core: create PivotData object and call Renderer on it\n    ###\n\n    $.fn.pivot = (input, inputOpts, locale=\"en\") ->\n        locale = \"en\" if not locales[locale]?\n        defaults =\n            cols : [], rows: [], vals: []\n            rowOrder: \"key_a_to_z\", colOrder: \"key_a_to_z\"\n            dataClass: PivotData\n            filter: -> true\n            aggregator: aggregatorTemplates.count()()\n            aggregatorName: \"Count\"\n            sorters: {}\n            derivedAttributes: {}\n            renderer: pivotTableRenderer\n\n        localeStrings = $.extend(true, {}, locales.en.localeStrings, locales[locale].localeStrings)\n        localeDefaults =\n            rendererOptions: {localeStrings}\n            localeStrings: localeStrings\n\n        opts = $.extend(true, {}, localeDefaults, $.extend({}, defaults, inputOpts))\n\n        result = null\n        try\n            pivotData = new opts.dataClass(input, opts)\n            try\n                result = opts.renderer(pivotData, opts.rendererOptions)\n            catch e\n                console.error(e.stack) if console?\n                result = $(\"<span>\").html opts.localeStrings.renderError\n        catch e\n            console.error(e.stack) if console?\n            result = $(\"<span>\").html opts.localeStrings.computeError\n\n        x = this[0]\n        x.removeChild(x.lastChild) while x.hasChildNodes()\n        return @append result\n\n\n    ###\n    Pivot Table UI: calls Pivot Table core above with options set by user\n    ###\n\n    $.fn.pivotUI = (input, inputOpts, overwrite = false, locale=\"en\") ->\n        locale = \"en\" if not locales[locale]?\n        defaults =\n            derivedAttributes: {}\n            aggregators: locales[locale].aggregators\n            renderers: locales[locale].renderers\n            hiddenAttributes: []\n            hiddenFromAggregators: []\n            hiddenFromDragDrop: []\n            menuLimit: 500\n            cols: [], rows: [], vals: []\n            rowOrder: \"key_a_to_z\", colOrder: \"key_a_to_z\"\n            dataClass: PivotData\n            exclusions: {}\n            inclusions: {}\n            unusedAttrsVertical: 85\n            autoSortUnusedAttrs: false\n            onRefresh: null\n            showUI: true\n            filter: -> true\n            sorters: {}\n\n        localeStrings = $.extend(true, {}, locales.en.localeStrings, locales[locale].localeStrings)\n        localeDefaults =\n            rendererOptions: {localeStrings}\n            localeStrings: localeStrings\n\n        existingOpts = @data \"pivotUIOptions\"\n        if not existingOpts? or overwrite\n            opts = $.extend(true, {}, localeDefaults, $.extend({}, defaults, inputOpts))\n        else\n            opts = existingOpts\n\n        try\n            # do a first pass on the data to cache a materialized copy of any\n            # function-valued inputs and to compute dimension cardinalities\n            attrValues = {}\n            materializedInput = []\n            recordsProcessed = 0\n            PivotData.forEachRecord input, opts.derivedAttributes, (record) ->\n                return unless opts.filter(record)\n                materializedInput.push(record)\n                for own attr of record\n                    if not attrValues[attr]?\n                        attrValues[attr] = {}\n                        if recordsProcessed > 0\n                            attrValues[attr][\"null\"] = recordsProcessed\n                for attr of attrValues\n                    value = record[attr] ? \"null\"\n                    attrValues[attr][value] ?= 0\n                    attrValues[attr][value]++\n                recordsProcessed++\n\n            #start building the output\n            uiTable = $(\"<table>\", \"class\": \"pvtUi\").attr(\"cellpadding\", 5)\n\n            #renderer control\n            rendererControl = $(\"<td>\").addClass(\"pvtUiCell\")\n\n            renderer = $(\"<select>\")\n                .addClass('pvtRenderer')\n                .appendTo(rendererControl)\n                .bind \"change\", -> refresh() #capture reference\n            for own x of opts.renderers\n                $(\"<option>\").val(x).html(x).appendTo(renderer)\n\n\n            #axis list, including the double-click menu\n            unused = $(\"<td>\").addClass('pvtAxisContainer pvtUnused pvtUiCell')\n            shownAttributes = (a for a of attrValues when a not in opts.hiddenAttributes)\n            shownInAggregators = (c for c in shownAttributes when c not in opts.hiddenFromAggregators)\n            shownInDragDrop = (c for c in shownAttributes when c not in opts.hiddenFromDragDrop)\n\n\n            unusedAttrsVerticalAutoOverride = false\n            if opts.unusedAttrsVertical == \"auto\"\n                unusedAttrsVerticalAutoCutoff = 120 # legacy support\n            else\n                unusedAttrsVerticalAutoCutoff = parseInt opts.unusedAttrsVertical\n\n            if not isNaN(unusedAttrsVerticalAutoCutoff)\n                attrLength = 0\n                attrLength += a.length for a in shownInDragDrop\n                unusedAttrsVerticalAutoOverride = attrLength > unusedAttrsVerticalAutoCutoff\n\n            if opts.unusedAttrsVertical == true or unusedAttrsVerticalAutoOverride\n                unused.addClass('pvtVertList')\n            else\n                unused.addClass('pvtHorizList')\n\n            for own i, attr of shownInDragDrop\n                do (attr) ->\n                    values = (v for v of attrValues[attr])\n                    hasExcludedItem = false\n                    valueList = $(\"<div>\").addClass('pvtFilterBox').hide()\n\n                    valueList.append $(\"<h4>\").append(\n                        $(\"<span>\").text(attr),\n                        $(\"<span>\").addClass(\"count\").text(\"(#{values.length})\"),\n                        )\n                    if values.length > opts.menuLimit\n                        valueList.append $(\"<p>\").html(opts.localeStrings.tooMany)\n                    else\n                        if values.length > 5\n                            controls = $(\"<p>\").appendTo(valueList)\n                            sorter = getSort(opts.sorters, attr)\n                            placeholder = opts.localeStrings.filterResults\n                            $(\"<input>\", {type: \"text\"}).appendTo(controls)\n                                .attr({placeholder: placeholder, class: \"pvtSearch\"})\n                                .bind \"keyup\", ->\n                                    filter = $(this).val().toLowerCase().trim()\n                                    accept_gen = (prefix, accepted) -> (v) ->\n                                        real_filter = filter.substring(prefix.length).trim()\n                                        return true if real_filter.length == 0\n                                        return Math.sign(sorter(v.toLowerCase(), real_filter)) in accepted\n                                    accept =\n                                        if      filter.indexOf(\">=\") == 0 then accept_gen(\">=\", [1,0])\n                                        else if filter.indexOf(\"<=\") == 0 then accept_gen(\"<=\", [-1,0])\n                                        else if filter.indexOf(\">\") == 0  then accept_gen(\">\",  [1])\n                                        else if filter.indexOf(\"<\") == 0  then accept_gen(\"<\",  [-1])\n                                        else if filter.indexOf(\"~\") == 0  then (v) ->\n                                                return true if filter.substring(1).trim().length == 0\n                                                v.toLowerCase().match(filter.substring(1))\n                                        else (v) -> v.toLowerCase().indexOf(filter) != -1\n\n                                    valueList.find('.pvtCheckContainer p label span.value').each ->\n                                        if accept($(this).text())\n                                            $(this).parent().parent().show()\n                                        else\n                                            $(this).parent().parent().hide()\n                            controls.append $(\"<br>\")\n                            $(\"<button>\", {type:\"button\"}).appendTo(controls)\n                                .html(opts.localeStrings.selectAll)\n                                .bind \"click\", ->\n                                    valueList.find(\"input:visible:not(:checked)\")\n                                        .prop(\"checked\", true).toggleClass(\"changed\")\n                                    return false\n                            $(\"<button>\", {type:\"button\"}).appendTo(controls)\n                                .html(opts.localeStrings.selectNone)\n                                .bind \"click\", ->\n                                    valueList.find(\"input:visible:checked\")\n                                        .prop(\"checked\", false).toggleClass(\"changed\")\n                                    return false\n\n                        checkContainer = $(\"<div>\").addClass(\"pvtCheckContainer\").appendTo(valueList)\n\n                        for value in values.sort(getSort(opts.sorters, attr))\n                             valueCount = attrValues[attr][value]\n                             filterItem = $(\"<label>\")\n                             filterItemExcluded = false\n                             if opts.inclusions[attr]\n                                filterItemExcluded = (value not in opts.inclusions[attr])\n                             else if opts.exclusions[attr]\n                                filterItemExcluded = (value in opts.exclusions[attr])\n                             hasExcludedItem ||= filterItemExcluded\n                             $(\"<input>\")\n                                .attr(\"type\", \"checkbox\").addClass('pvtFilter')\n                                .attr(\"checked\", !filterItemExcluded).data(\"filter\", [attr,value])\n                                .appendTo(filterItem)\n                                .bind \"change\", -> $(this).toggleClass(\"changed\")\n                             filterItem.append $(\"<span>\").addClass(\"value\").text(value)\n                             filterItem.append $(\"<span>\").addClass(\"count\").text(\"(\"+valueCount+\")\")\n                             checkContainer.append $(\"<p>\").append(filterItem)\n\n                    closeFilterBox = ->\n                        if valueList.find(\"[type='checkbox']\").length >\n                               valueList.find(\"[type='checkbox']:checked\").length\n                                attrElem.addClass \"pvtFilteredAttribute\"\n                            else\n                                attrElem.removeClass \"pvtFilteredAttribute\"\n\n                            valueList.find('.pvtSearch').val('')\n                            valueList.find('.pvtCheckContainer p').show()\n                            valueList.hide()\n\n                    finalButtons = $(\"<p>\").appendTo(valueList)\n\n                    if values.length <= opts.menuLimit\n                        $(\"<button>\", {type: \"button\"}).text(opts.localeStrings.apply)\n                            .appendTo(finalButtons).bind \"click\", ->\n                                if valueList.find(\".changed\").removeClass(\"changed\").length\n                                    refresh()\n                                closeFilterBox()\n\n                    $(\"<button>\", {type: \"button\"}).text(opts.localeStrings.cancel)\n                        .appendTo(finalButtons).bind \"click\", ->\n                            valueList.find(\".changed:checked\")\n                                .removeClass(\"changed\").prop(\"checked\", false)\n                            valueList.find(\".changed:not(:checked)\")\n                                .removeClass(\"changed\").prop(\"checked\", true)\n                            closeFilterBox()\n\n                    triangleLink = $(\"<span>\").addClass('pvtTriangle')\n                        .html(\" &#x25BE;\").bind \"click\", (e) ->\n                            {left, top} = $(e.currentTarget).position()\n                            valueList.css(left: left+10, top: top+10).show()\n\n                    attrElem = $(\"<li>\").addClass(\"axis_#{i}\")\n                        .append $(\"<span>\").addClass('pvtAttr').text(attr).data(\"attrName\", attr).append(triangleLink)\n\n                    attrElem.addClass('pvtFilteredAttribute') if hasExcludedItem\n                    unused.append(attrElem).append(valueList)\n\n            tr1 = $(\"<tr>\").appendTo(uiTable)\n\n            #aggregator menu and value area\n\n            aggregator = $(\"<select>\").addClass('pvtAggregator')\n                .bind \"change\", -> refresh() #capture reference\n            for own x of opts.aggregators\n                aggregator.append $(\"<option>\").val(x).html(x)\n\n            ordering =\n                key_a_to_z:   {rowSymbol: \"&varr;\", colSymbol: \"&harr;\", next: \"value_a_to_z\"}\n                value_a_to_z: {rowSymbol: \"&darr;\", colSymbol: \"&rarr;\", next: \"value_z_to_a\"}\n                value_z_to_a: {rowSymbol: \"&uarr;\", colSymbol: \"&larr;\", next: \"key_a_to_z\"}\n\n            rowOrderArrow = $(\"<a>\", role: \"button\").addClass(\"pvtRowOrder\")\n                .data(\"order\", opts.rowOrder).html(ordering[opts.rowOrder].rowSymbol)\n                .bind \"click\", ->\n                    $(this).data(\"order\", ordering[$(this).data(\"order\")].next)\n                    $(this).html(ordering[$(this).data(\"order\")].rowSymbol)\n                    refresh()\n\n            colOrderArrow = $(\"<a>\", role: \"button\").addClass(\"pvtColOrder\")\n                .data(\"order\", opts.colOrder).html(ordering[opts.colOrder].colSymbol)\n                .bind \"click\", ->\n                    $(this).data(\"order\", ordering[$(this).data(\"order\")].next)\n                    $(this).html(ordering[$(this).data(\"order\")].colSymbol)\n                    refresh()\n\n            $(\"<td>\").addClass('pvtVals pvtUiCell')\n              .appendTo(tr1)\n              .append(aggregator)\n              .append(rowOrderArrow)\n              .append(colOrderArrow)\n              .append($(\"<br>\"))\n\n            #column axes\n            $(\"<td>\").addClass('pvtAxisContainer pvtHorizList pvtCols pvtUiCell').appendTo(tr1)\n\n            tr2 = $(\"<tr>\").appendTo(uiTable)\n\n            #row axes\n            tr2.append $(\"<td>\").addClass('pvtAxisContainer pvtRows pvtUiCell').attr(\"valign\", \"top\")\n\n            #the actual pivot table container\n            pivotTable = $(\"<td>\")\n                .attr(\"valign\", \"top\")\n                .addClass('pvtRendererArea')\n                .appendTo(tr2)\n\n            #finally the renderer dropdown and unused attribs are inserted at the requested location\n            if opts.unusedAttrsVertical == true or unusedAttrsVerticalAutoOverride\n                uiTable.find('tr:nth-child(1)').prepend rendererControl\n                uiTable.find('tr:nth-child(2)').prepend unused\n            else\n                uiTable.prepend $(\"<tr>\").append(rendererControl).append(unused)\n\n            #render the UI in its default state\n            @html uiTable\n\n            #set up the UI initial state as requested by moving elements around\n\n            for x in opts.cols\n                @find(\".pvtCols\").append @find(\".axis_#{$.inArray(x, shownInDragDrop)}\")\n            for x in opts.rows\n                @find(\".pvtRows\").append @find(\".axis_#{$.inArray(x, shownInDragDrop)}\")\n            if opts.aggregatorName?\n                @find(\".pvtAggregator\").val opts.aggregatorName\n            if opts.rendererName?\n                @find(\".pvtRenderer\").val opts.rendererName\n\n            @find(\".pvtUiCell\").hide() unless opts.showUI\n\n            initialRender = true\n\n            #set up for refreshing\n            refreshDelayed = =>\n                subopts =\n                    derivedAttributes: opts.derivedAttributes\n                    localeStrings: opts.localeStrings\n                    rendererOptions: opts.rendererOptions\n                    sorters: opts.sorters\n                    cols: [], rows: []\n                    dataClass: opts.dataClass\n\n                numInputsToProcess = opts.aggregators[aggregator.val()]([])().numInputs ? 0\n                vals = []\n                @find(\".pvtRows li span.pvtAttr\").each -> subopts.rows.push $(this).data(\"attrName\")\n                @find(\".pvtCols li span.pvtAttr\").each -> subopts.cols.push $(this).data(\"attrName\")\n                @find(\".pvtVals select.pvtAttrDropdown\").each ->\n                    if numInputsToProcess == 0\n                        $(this).remove()\n                    else\n                        numInputsToProcess--\n                        vals.push $(this).val() if $(this).val() != \"\"\n\n                if numInputsToProcess != 0\n                    pvtVals = @find(\".pvtVals\")\n                    for x in [0...numInputsToProcess]\n                        newDropdown = $(\"<select>\")\n                            .addClass('pvtAttrDropdown')\n                            .append($(\"<option>\"))\n                            .bind \"change\", -> refresh()\n                        for attr in shownInAggregators\n                            newDropdown.append($(\"<option>\").val(attr).text(attr))\n                        pvtVals.append(newDropdown)\n\n                if initialRender\n                    vals = opts.vals\n                    i = 0\n                    @find(\".pvtVals select.pvtAttrDropdown\").each ->\n                        $(this).val vals[i]\n                        i++\n                    initialRender = false\n\n                subopts.aggregatorName = aggregator.val()\n                subopts.vals = vals\n                subopts.aggregator = opts.aggregators[aggregator.val()](vals)\n                subopts.renderer = opts.renderers[renderer.val()]\n                subopts.rowOrder = rowOrderArrow.data(\"order\")\n                subopts.colOrder = colOrderArrow.data(\"order\")\n                #construct filter here\n                exclusions = {}\n                @find('input.pvtFilter').not(':checked').each ->\n                    filter = $(this).data(\"filter\")\n                    if exclusions[filter[0]]?\n                        exclusions[filter[0]].push( filter[1] )\n                    else\n                        exclusions[filter[0]] = [ filter[1] ]\n                #include inclusions when exclusions present\n                inclusions = {}\n                @find('input.pvtFilter:checked').each ->\n                    filter = $(this).data(\"filter\")\n                    if exclusions[filter[0]]?\n                        if inclusions[filter[0]]?\n                            inclusions[filter[0]].push( filter[1] )\n                        else\n                            inclusions[filter[0]] = [ filter[1] ]\n\n                subopts.filter = (record) ->\n                    return false if not opts.filter(record)\n                    for k,excludedItems of exclusions\n                        return false if \"\"+(record[k] ? 'null') in excludedItems\n                    return true\n\n                pivotTable.pivot(materializedInput,subopts)\n                pivotUIOptions = $.extend {}, opts,\n                    cols: subopts.cols\n                    rows: subopts.rows\n                    colOrder: subopts.colOrder\n                    rowOrder: subopts.rowOrder\n                    vals: vals\n                    exclusions: exclusions\n                    inclusions: inclusions\n                    inclusionsInfo: inclusions #duplicated for backwards-compatibility\n                    aggregatorName: aggregator.val()\n                    rendererName: renderer.val()\n\n                @data \"pivotUIOptions\", pivotUIOptions\n\n                # if requested make sure unused columns are in alphabetical order\n                if opts.autoSortUnusedAttrs\n                    unusedAttrsContainer = @find(\"td.pvtUnused.pvtAxisContainer\")\n                    $(unusedAttrsContainer).children(\"li\")\n                        .sort((a, b) => naturalSort($(a).text(), $(b).text()))\n                        .appendTo unusedAttrsContainer\n\n                pivotTable.css(\"opacity\", 1)\n                opts.onRefresh(pivotUIOptions) if opts.onRefresh?\n\n            refresh = =>\n                pivotTable.css(\"opacity\", 0.5)\n                setTimeout refreshDelayed, 10\n\n            #the very first refresh will actually display the table\n            refresh()\n\n            @find(\".pvtAxisContainer\").sortable\n                    update: (e, ui) -> refresh() if not ui.sender?\n                    connectWith: @find(\".pvtAxisContainer\")\n                    items: 'li'\n                    placeholder: 'pvtPlaceholder'\n        catch e\n            console.error(e.stack) if console?\n            @html opts.localeStrings.uiRenderError\n        return this\n\n    ###\n    Heatmap post-processing\n    ###\n\n    $.fn.heatmap = (scope = \"heatmap\", opts) ->\n        numRows = @data \"numrows\"\n        numCols = @data \"numcols\"\n\n        # given a series of values\n        # must return a function to map a given value to a CSS color\n        colorScaleGenerator = opts?.heatmap?.colorScaleGenerator\n        colorScaleGenerator ?= (values) ->\n            min = Math.min(values...)\n            max = Math.max(values...)\n            return (x) ->\n                nonRed = 255 - Math.round 255*(x-min)/(max-min)\n                return \"rgb(255,#{nonRed},#{nonRed})\"\n\n        heatmapper = (scope) =>\n            forEachCell = (f) =>\n                @find(scope).each ->\n                    x = $(this).data(\"value\")\n                    f(x, $(this)) if x? and isFinite(x)\n\n            values = []\n            forEachCell (x) -> values.push x\n            colorScale = colorScaleGenerator(values)\n            forEachCell (x, elem) -> elem.css \"background-color\", colorScale(x)\n\n        switch scope\n            when \"heatmap\"    then heatmapper \".pvtVal\"\n            when \"rowheatmap\" then heatmapper \".pvtVal.row#{i}\" for i in [0...numRows]\n            when \"colheatmap\" then heatmapper \".pvtVal.col#{j}\" for j in [0...numCols]\n\n        heatmapper \".pvtTotal.rowTotal\"\n        heatmapper \".pvtTotal.colTotal\"\n\n        return this\n\n    ###\n    Barchart post-processing\n    ###\n\n    $.fn.barchart = (opts) ->\n        numRows = @data \"numrows\"\n        numCols = @data \"numcols\"\n\n        barcharter = (scope) =>\n            forEachCell = (f) =>\n                @find(scope).each ->\n                    x = $(this).data(\"value\")\n                    f(x, $(this)) if x? and isFinite(x)\n\n            values = []\n            forEachCell (x) -> values.push x\n            max = Math.max(values...)\n            if max < 0\n                max = 0\n            range = max;\n            min = Math.min(values...)\n            if min < 0\n                range = max - min\n            scaler = (x) -> 100*x/(1.4*range)\n            forEachCell (x, elem) ->\n                text = elem.text()\n                wrapper = $(\"<div>\").css\n                    \"position\": \"relative\"\n                    \"height\": \"55px\"\n                bgColor = \"gray\"\n                bBase = 0\n                if min < 0\n                    bBase = scaler(-min)\n                if x < 0\n                    bBase += scaler(x)\n                    bgColor = \"darkred\"\n                    x = -x\n                wrapper.append $(\"<div>\").css\n                    \"position\": \"absolute\"\n                    \"bottom\": bBase + \"%\"\n                    \"left\": 0\n                    \"right\": 0\n                    \"height\": scaler(x) + \"%\"\n                    \"background-color\": bgColor\n                wrapper.append $(\"<div>\").text(text).css\n                    \"position\":\"relative\"\n                    \"padding-left\":\"5px\"\n                    \"padding-right\":\"5px\"\n\n                elem.css(\"padding\": 0,\"padding-top\": \"5px\", \"text-align\": \"center\").html wrapper\n\n        barcharter \".pvtVal.row#{i}\" for i in [0...numRows]\n        barcharter \".pvtTotal.colTotal\"\n\n        return this\n","(function() {\n  var callWithJQuery,\n    indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },\n    slice = [].slice,\n    bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },\n    hasProp = {}.hasOwnProperty;\n\n  callWithJQuery = function(pivotModule) {\n    if (typeof exports === \"object\" && typeof module === \"object\") {\n      return pivotModule(require(\"jquery\"));\n    } else if (typeof define === \"function\" && define.amd) {\n      return define([\"jquery\"], pivotModule);\n    } else {\n      return pivotModule(jQuery);\n    }\n  };\n\n  callWithJQuery(function($) {\n\n    /*\n    Utilities\n     */\n    var PivotData, addSeparators, aggregatorTemplates, aggregators, dayNamesEn, derivers, getSort, locales, mthNamesEn, naturalSort, numberFormat, pivotTableRenderer, rd, renderers, rx, rz, sortAs, usFmt, usFmtInt, usFmtPct, zeroPad;\n    addSeparators = function(nStr, thousandsSep, decimalSep) {\n      var rgx, x, x1, x2;\n      nStr += '';\n      x = nStr.split('.');\n      x1 = x[0];\n      x2 = x.length > 1 ? decimalSep + x[1] : '';\n      rgx = /(\\d+)(\\d{3})/;\n      while (rgx.test(x1)) {\n        x1 = x1.replace(rgx, '$1' + thousandsSep + '$2');\n      }\n      return x1 + x2;\n    };\n    numberFormat = function(opts) {\n      var defaults;\n      defaults = {\n        digitsAfterDecimal: 2,\n        scaler: 1,\n        thousandsSep: \",\",\n        decimalSep: \".\",\n        prefix: \"\",\n        suffix: \"\"\n      };\n      opts = $.extend({}, defaults, opts);\n      return function(x) {\n        var result;\n        if (isNaN(x) || !isFinite(x)) {\n          return \"\";\n        }\n        result = addSeparators((opts.scaler * x).toFixed(opts.digitsAfterDecimal), opts.thousandsSep, opts.decimalSep);\n        return \"\" + opts.prefix + result + opts.suffix;\n      };\n    };\n    usFmt = numberFormat();\n    usFmtInt = numberFormat({\n      digitsAfterDecimal: 0\n    });\n    usFmtPct = numberFormat({\n      digitsAfterDecimal: 1,\n      scaler: 100,\n      suffix: \"%\"\n    });\n    aggregatorTemplates = {\n      count: function(formatter) {\n        if (formatter == null) {\n          formatter = usFmtInt;\n        }\n        return function() {\n          return function(data, rowKey, colKey) {\n            return {\n              count: 0,\n              push: function() {\n                return this.count++;\n              },\n              value: function() {\n                return this.count;\n              },\n              format: formatter\n            };\n          };\n        };\n      },\n      uniques: function(fn, formatter) {\n        if (formatter == null) {\n          formatter = usFmtInt;\n        }\n        return function(arg) {\n          var attr;\n          attr = arg[0];\n          return function(data, rowKey, colKey) {\n            return {\n              uniq: [],\n              push: function(record) {\n                var ref;\n                if (ref = record[attr], indexOf.call(this.uniq, ref) < 0) {\n                  return this.uniq.push(record[attr]);\n                }\n              },\n              value: function() {\n                return fn(this.uniq);\n              },\n              format: formatter,\n              numInputs: attr != null ? 0 : 1\n            };\n          };\n        };\n      },\n      sum: function(formatter) {\n        if (formatter == null) {\n          formatter = usFmt;\n        }\n        return function(arg) {\n          var attr;\n          attr = arg[0];\n          return function(data, rowKey, colKey) {\n            return {\n              sum: 0,\n              push: function(record) {\n                if (!isNaN(parseFloat(record[attr]))) {\n                  return this.sum += parseFloat(record[attr]);\n                }\n              },\n              value: function() {\n                return this.sum;\n              },\n              format: formatter,\n              numInputs: attr != null ? 0 : 1\n            };\n          };\n        };\n      },\n      extremes: function(mode, formatter) {\n        if (formatter == null) {\n          formatter = usFmt;\n        }\n        return function(arg) {\n          var attr;\n          attr = arg[0];\n          return function(data, rowKey, colKey) {\n            return {\n              val: null,\n              sorter: getSort(data != null ? data.sorters : void 0, attr),\n              push: function(record) {\n                var ref, ref1, ref2, x;\n                x = record[attr];\n                if (mode === \"min\" || mode === \"max\") {\n                  x = parseFloat(x);\n                  if (!isNaN(x)) {\n                    this.val = Math[mode](x, (ref = this.val) != null ? ref : x);\n                  }\n                }\n                if (mode === \"first\") {\n                  if (this.sorter(x, (ref1 = this.val) != null ? ref1 : x) <= 0) {\n                    this.val = x;\n                  }\n                }\n                if (mode === \"last\") {\n                  if (this.sorter(x, (ref2 = this.val) != null ? ref2 : x) >= 0) {\n                    return this.val = x;\n                  }\n                }\n              },\n              value: function() {\n                return this.val;\n              },\n              format: function(x) {\n                if (isNaN(x)) {\n                  return x;\n                } else {\n                  return formatter(x);\n                }\n              },\n              numInputs: attr != null ? 0 : 1\n            };\n          };\n        };\n      },\n      quantile: function(q, formatter) {\n        if (formatter == null) {\n          formatter = usFmt;\n        }\n        return function(arg) {\n          var attr;\n          attr = arg[0];\n          return function(data, rowKey, colKey) {\n            return {\n              vals: [],\n              push: function(record) {\n                var x;\n                x = parseFloat(record[attr]);\n                if (!isNaN(x)) {\n                  return this.vals.push(x);\n                }\n              },\n              value: function() {\n                var i;\n                if (this.vals.length === 0) {\n                  return null;\n                }\n                this.vals.sort(function(a, b) {\n                  return a - b;\n                });\n                i = (this.vals.length - 1) * q;\n                return (this.vals[Math.floor(i)] + this.vals[Math.ceil(i)]) / 2.0;\n              },\n              format: formatter,\n              numInputs: attr != null ? 0 : 1\n            };\n          };\n        };\n      },\n      runningStat: function(mode, ddof, formatter) {\n        if (mode == null) {\n          mode = \"mean\";\n        }\n        if (ddof == null) {\n          ddof = 1;\n        }\n        if (formatter == null) {\n          formatter = usFmt;\n        }\n        return function(arg) {\n          var attr;\n          attr = arg[0];\n          return function(data, rowKey, colKey) {\n            return {\n              n: 0.0,\n              m: 0.0,\n              s: 0.0,\n              push: function(record) {\n                var m_new, x;\n                x = parseFloat(record[attr]);\n                if (isNaN(x)) {\n                  return;\n                }\n                this.n += 1.0;\n                if (this.n === 1.0) {\n                  return this.m = x;\n                } else {\n                  m_new = this.m + (x - this.m) / this.n;\n                  this.s = this.s + (x - this.m) * (x - m_new);\n                  return this.m = m_new;\n                }\n              },\n              value: function() {\n                if (mode === \"mean\") {\n                  if (this.n === 0) {\n                    return 0 / 0;\n                  } else {\n                    return this.m;\n                  }\n                }\n                if (this.n <= ddof) {\n                  return 0;\n                }\n                switch (mode) {\n                  case \"var\":\n                    return this.s / (this.n - ddof);\n                  case \"stdev\":\n                    return Math.sqrt(this.s / (this.n - ddof));\n                }\n              },\n              format: formatter,\n              numInputs: attr != null ? 0 : 1\n            };\n          };\n        };\n      },\n      sumOverSum: function(formatter) {\n        if (formatter == null) {\n          formatter = usFmt;\n        }\n        return function(arg) {\n          var denom, num;\n          num = arg[0], denom = arg[1];\n          return function(data, rowKey, colKey) {\n            return {\n              sumNum: 0,\n              sumDenom: 0,\n              push: function(record) {\n                if (!isNaN(parseFloat(record[num]))) {\n                  this.sumNum += parseFloat(record[num]);\n                }\n                if (!isNaN(parseFloat(record[denom]))) {\n                  return this.sumDenom += parseFloat(record[denom]);\n                }\n              },\n              value: function() {\n                return this.sumNum / this.sumDenom;\n              },\n              format: formatter,\n              numInputs: (num != null) && (denom != null) ? 0 : 2\n            };\n          };\n        };\n      },\n      sumOverSumBound80: function(upper, formatter) {\n        if (upper == null) {\n          upper = true;\n        }\n        if (formatter == null) {\n          formatter = usFmt;\n        }\n        return function(arg) {\n          var denom, num;\n          num = arg[0], denom = arg[1];\n          return function(data, rowKey, colKey) {\n            return {\n              sumNum: 0,\n              sumDenom: 0,\n              push: function(record) {\n                if (!isNaN(parseFloat(record[num]))) {\n                  this.sumNum += parseFloat(record[num]);\n                }\n                if (!isNaN(parseFloat(record[denom]))) {\n                  return this.sumDenom += parseFloat(record[denom]);\n                }\n              },\n              value: function() {\n                var sign;\n                sign = upper ? 1 : -1;\n                return (0.821187207574908 / this.sumDenom + this.sumNum / this.sumDenom + 1.2815515655446004 * sign * Math.sqrt(0.410593603787454 / (this.sumDenom * this.sumDenom) + (this.sumNum * (1 - this.sumNum / this.sumDenom)) / (this.sumDenom * this.sumDenom))) / (1 + 1.642374415149816 / this.sumDenom);\n              },\n              format: formatter,\n              numInputs: (num != null) && (denom != null) ? 0 : 2\n            };\n          };\n        };\n      },\n      fractionOf: function(wrapped, type, formatter) {\n        if (type == null) {\n          type = \"total\";\n        }\n        if (formatter == null) {\n          formatter = usFmtPct;\n        }\n        return function() {\n          var x;\n          x = 1 <= arguments.length ? slice.call(arguments, 0) : [];\n          return function(data, rowKey, colKey) {\n            return {\n              selector: {\n                total: [[], []],\n                row: [rowKey, []],\n                col: [[], colKey]\n              }[type],\n              inner: wrapped.apply(null, x)(data, rowKey, colKey),\n              push: function(record) {\n                return this.inner.push(record);\n              },\n              format: formatter,\n              value: function() {\n                return this.inner.value() / data.getAggregator.apply(data, this.selector).inner.value();\n              },\n              numInputs: wrapped.apply(null, x)().numInputs\n            };\n          };\n        };\n      }\n    };\n    aggregatorTemplates.countUnique = function(f) {\n      return aggregatorTemplates.uniques((function(x) {\n        return x.length;\n      }), f);\n    };\n    aggregatorTemplates.listUnique = function(s) {\n      return aggregatorTemplates.uniques((function(x) {\n        return x.sort(naturalSort).join(s);\n      }), (function(x) {\n        return x;\n      }));\n    };\n    aggregatorTemplates.max = function(f) {\n      return aggregatorTemplates.extremes('max', f);\n    };\n    aggregatorTemplates.min = function(f) {\n      return aggregatorTemplates.extremes('min', f);\n    };\n    aggregatorTemplates.first = function(f) {\n      return aggregatorTemplates.extremes('first', f);\n    };\n    aggregatorTemplates.last = function(f) {\n      return aggregatorTemplates.extremes('last', f);\n    };\n    aggregatorTemplates.median = function(f) {\n      return aggregatorTemplates.quantile(0.5, f);\n    };\n    aggregatorTemplates.average = function(f) {\n      return aggregatorTemplates.runningStat(\"mean\", 1, f);\n    };\n    aggregatorTemplates[\"var\"] = function(ddof, f) {\n      return aggregatorTemplates.runningStat(\"var\", ddof, f);\n    };\n    aggregatorTemplates.stdev = function(ddof, f) {\n      return aggregatorTemplates.runningStat(\"stdev\", ddof, f);\n    };\n    aggregators = (function(tpl) {\n      return {\n        \"Count\": tpl.count(usFmtInt),\n        \"Count Unique Values\": tpl.countUnique(usFmtInt),\n        \"List Unique Values\": tpl.listUnique(\", \"),\n        \"Sum\": tpl.sum(usFmt),\n        \"Integer Sum\": tpl.sum(usFmtInt),\n        \"Average\": tpl.average(usFmt),\n        \"Median\": tpl.median(usFmt),\n        \"Sample Variance\": tpl[\"var\"](1, usFmt),\n        \"Sample Standard Deviation\": tpl.stdev(1, usFmt),\n        \"Minimum\": tpl.min(usFmt),\n        \"Maximum\": tpl.max(usFmt),\n        \"First\": tpl.first(usFmt),\n        \"Last\": tpl.last(usFmt),\n        \"Sum over Sum\": tpl.sumOverSum(usFmt),\n        \"80% Upper Bound\": tpl.sumOverSumBound80(true, usFmt),\n        \"80% Lower Bound\": tpl.sumOverSumBound80(false, usFmt),\n        \"Sum as Fraction of Total\": tpl.fractionOf(tpl.sum(), \"total\", usFmtPct),\n        \"Sum as Fraction of Rows\": tpl.fractionOf(tpl.sum(), \"row\", usFmtPct),\n        \"Sum as Fraction of Columns\": tpl.fractionOf(tpl.sum(), \"col\", usFmtPct),\n        \"Count as Fraction of Total\": tpl.fractionOf(tpl.count(), \"total\", usFmtPct),\n        \"Count as Fraction of Rows\": tpl.fractionOf(tpl.count(), \"row\", usFmtPct),\n        \"Count as Fraction of Columns\": tpl.fractionOf(tpl.count(), \"col\", usFmtPct)\n      };\n    })(aggregatorTemplates);\n    renderers = {\n      \"Table\": function(data, opts) {\n        return pivotTableRenderer(data, opts);\n      },\n      \"Table Barchart\": function(data, opts) {\n        return $(pivotTableRenderer(data, opts)).barchart();\n      },\n      \"Heatmap\": function(data, opts) {\n        return $(pivotTableRenderer(data, opts)).heatmap(\"heatmap\", opts);\n      },\n      \"Row Heatmap\": function(data, opts) {\n        return $(pivotTableRenderer(data, opts)).heatmap(\"rowheatmap\", opts);\n      },\n      \"Col Heatmap\": function(data, opts) {\n        return $(pivotTableRenderer(data, opts)).heatmap(\"colheatmap\", opts);\n      }\n    };\n    locales = {\n      en: {\n        aggregators: aggregators,\n        renderers: renderers,\n        localeStrings: {\n          renderError: \"An error occurred rendering the PivotTable results.\",\n          computeError: \"An error occurred computing the PivotTable results.\",\n          uiRenderError: \"An error occurred rendering the PivotTable UI.\",\n          selectAll: \"Select All\",\n          selectNone: \"Select None\",\n          tooMany: \"(too many to list)\",\n          filterResults: \"Filter values\",\n          apply: \"Apply\",\n          cancel: \"Cancel\",\n          totals: \"Totals\",\n          vs: \"vs\",\n          by: \"by\"\n        }\n      }\n    };\n    mthNamesEn = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"];\n    dayNamesEn = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\n    zeroPad = function(number) {\n      return (\"0\" + number).substr(-2, 2);\n    };\n    derivers = {\n      bin: function(col, binWidth) {\n        return function(record) {\n          return record[col] - record[col] % binWidth;\n        };\n      },\n      dateFormat: function(col, formatString, utcOutput, mthNames, dayNames) {\n        var utc;\n        if (utcOutput == null) {\n          utcOutput = false;\n        }\n        if (mthNames == null) {\n          mthNames = mthNamesEn;\n        }\n        if (dayNames == null) {\n          dayNames = dayNamesEn;\n        }\n        utc = utcOutput ? \"UTC\" : \"\";\n        return function(record) {\n          var date;\n          date = new Date(Date.parse(record[col]));\n          if (isNaN(date)) {\n            return \"\";\n          }\n          return formatString.replace(/%(.)/g, function(m, p) {\n            switch (p) {\n              case \"y\":\n                return date[\"get\" + utc + \"FullYear\"]();\n              case \"m\":\n                return zeroPad(date[\"get\" + utc + \"Month\"]() + 1);\n              case \"n\":\n                return mthNames[date[\"get\" + utc + \"Month\"]()];\n              case \"d\":\n                return zeroPad(date[\"get\" + utc + \"Date\"]());\n              case \"w\":\n                return dayNames[date[\"get\" + utc + \"Day\"]()];\n              case \"x\":\n                return date[\"get\" + utc + \"Day\"]();\n              case \"H\":\n                return zeroPad(date[\"get\" + utc + \"Hours\"]());\n              case \"M\":\n                return zeroPad(date[\"get\" + utc + \"Minutes\"]());\n              case \"S\":\n                return zeroPad(date[\"get\" + utc + \"Seconds\"]());\n              default:\n                return \"%\" + p;\n            }\n          });\n        };\n      }\n    };\n    rx = /(\\d+)|(\\D+)/g;\n    rd = /\\d/;\n    rz = /^0/;\n    naturalSort = (function(_this) {\n      return function(as, bs) {\n        var a, a1, b, b1, nas, nbs, numDiff;\n        if ((bs != null) && (as == null)) {\n          return -1;\n        }\n        if ((as != null) && (bs == null)) {\n          return 1;\n        }\n        if (typeof as === \"number\" && isNaN(as)) {\n          return -1;\n        }\n        if (typeof bs === \"number\" && isNaN(bs)) {\n          return 1;\n        }\n        nas = +as;\n        nbs = +bs;\n        if (nas < nbs) {\n          return -1;\n        }\n        if (nas > nbs) {\n          return 1;\n        }\n        if (typeof as === \"number\" && typeof bs !== \"number\") {\n          return -1;\n        }\n        if (typeof bs === \"number\" && typeof as !== \"number\") {\n          return 1;\n        }\n        if (typeof as === \"number\" && typeof bs === \"number\") {\n          return 0;\n        }\n        if (isNaN(nbs) && !isNaN(nas)) {\n          return -1;\n        }\n        if (isNaN(nas) && !isNaN(nbs)) {\n          return 1;\n        }\n        a = String(as);\n        b = String(bs);\n        if (a === b) {\n          return 0;\n        }\n        if (!(rd.test(a) && rd.test(b))) {\n          return (a > b ? 1 : -1);\n        }\n        a = a.match(rx);\n        b = b.match(rx);\n        while (a.length && b.length) {\n          a1 = a.shift();\n          b1 = b.shift();\n          if (a1 !== b1) {\n            if (rd.test(a1) && rd.test(b1)) {\n              numDiff = a1.replace(rz, \".0\") - b1.replace(rz, \".0\");\n              if (numDiff !== 0) {\n                return numDiff;\n              } else {\n                return a1.length - b1.length;\n              }\n            } else {\n              return (a1 > b1 ? 1 : -1);\n            }\n          }\n        }\n        return a.length - b.length;\n      };\n    })(this);\n    sortAs = function(order) {\n      var i, l_mapping, mapping, x;\n      mapping = {};\n      l_mapping = {};\n      for (i in order) {\n        x = order[i];\n        mapping[x] = i;\n        if (typeof x === \"string\") {\n          l_mapping[x.toLowerCase()] = i;\n        }\n      }\n      return function(a, b) {\n        if ((mapping[a] != null) && (mapping[b] != null)) {\n          return mapping[a] - mapping[b];\n        } else if (mapping[a] != null) {\n          return -1;\n        } else if (mapping[b] != null) {\n          return 1;\n        } else if ((l_mapping[a] != null) && (l_mapping[b] != null)) {\n          return l_mapping[a] - l_mapping[b];\n        } else if (l_mapping[a] != null) {\n          return -1;\n        } else if (l_mapping[b] != null) {\n          return 1;\n        } else {\n          return naturalSort(a, b);\n        }\n      };\n    };\n    getSort = function(sorters, attr) {\n      var sort;\n      if (sorters != null) {\n        if ($.isFunction(sorters)) {\n          sort = sorters(attr);\n          if ($.isFunction(sort)) {\n            return sort;\n          }\n        } else if (sorters[attr] != null) {\n          return sorters[attr];\n        }\n      }\n      return naturalSort;\n    };\n\n    /*\n    Data Model class\n     */\n    PivotData = (function() {\n      function PivotData(input, opts) {\n        var ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9;\n        if (opts == null) {\n          opts = {};\n        }\n        this.getAggregator = bind(this.getAggregator, this);\n        this.getRowKeys = bind(this.getRowKeys, this);\n        this.getColKeys = bind(this.getColKeys, this);\n        this.sortKeys = bind(this.sortKeys, this);\n        this.arrSort = bind(this.arrSort, this);\n        this.input = input;\n        this.aggregator = (ref = opts.aggregator) != null ? ref : aggregatorTemplates.count()();\n        this.aggregatorName = (ref1 = opts.aggregatorName) != null ? ref1 : \"Count\";\n        this.colAttrs = (ref2 = opts.cols) != null ? ref2 : [];\n        this.rowAttrs = (ref3 = opts.rows) != null ? ref3 : [];\n        this.valAttrs = (ref4 = opts.vals) != null ? ref4 : [];\n        this.sorters = (ref5 = opts.sorters) != null ? ref5 : {};\n        this.rowOrder = (ref6 = opts.rowOrder) != null ? ref6 : \"key_a_to_z\";\n        this.colOrder = (ref7 = opts.colOrder) != null ? ref7 : \"key_a_to_z\";\n        this.derivedAttributes = (ref8 = opts.derivedAttributes) != null ? ref8 : {};\n        this.filter = (ref9 = opts.filter) != null ? ref9 : (function() {\n          return true;\n        });\n        this.tree = {};\n        this.rowKeys = [];\n        this.colKeys = [];\n        this.rowTotals = {};\n        this.colTotals = {};\n        this.allTotal = this.aggregator(this, [], []);\n        this.sorted = false;\n        PivotData.forEachRecord(this.input, this.derivedAttributes, (function(_this) {\n          return function(record) {\n            if (_this.filter(record)) {\n              return _this.processRecord(record);\n            }\n          };\n        })(this));\n      }\n\n      PivotData.forEachRecord = function(input, derivedAttributes, f) {\n        var addRecord, compactRecord, i, j, k, l, len1, record, ref, results, results1, tblCols;\n        if ($.isEmptyObject(derivedAttributes)) {\n          addRecord = f;\n        } else {\n          addRecord = function(record) {\n            var k, ref, v;\n            for (k in derivedAttributes) {\n              v = derivedAttributes[k];\n              record[k] = (ref = v(record)) != null ? ref : record[k];\n            }\n            return f(record);\n          };\n        }\n        if ($.isFunction(input)) {\n          return input(addRecord);\n        } else if ($.isArray(input)) {\n          if ($.isArray(input[0])) {\n            results = [];\n            for (i in input) {\n              if (!hasProp.call(input, i)) continue;\n              compactRecord = input[i];\n              if (!(i > 0)) {\n                continue;\n              }\n              record = {};\n              ref = input[0];\n              for (j in ref) {\n                if (!hasProp.call(ref, j)) continue;\n                k = ref[j];\n                record[k] = compactRecord[j];\n              }\n              results.push(addRecord(record));\n            }\n            return results;\n          } else {\n            results1 = [];\n            for (l = 0, len1 = input.length; l < len1; l++) {\n              record = input[l];\n              results1.push(addRecord(record));\n            }\n            return results1;\n          }\n        } else if (input instanceof $) {\n          tblCols = [];\n          $(\"thead > tr > th\", input).each(function(i) {\n            return tblCols.push($(this).text());\n          });\n          return $(\"tbody > tr\", input).each(function(i) {\n            record = {};\n            $(\"td\", this).each(function(j) {\n              return record[tblCols[j]] = $(this).text();\n            });\n            return addRecord(record);\n          });\n        } else {\n          throw new Error(\"unknown input format\");\n        }\n      };\n\n      PivotData.prototype.forEachMatchingRecord = function(criteria, callback) {\n        return PivotData.forEachRecord(this.input, this.derivedAttributes, (function(_this) {\n          return function(record) {\n            var k, ref, v;\n            if (!_this.filter(record)) {\n              return;\n            }\n            for (k in criteria) {\n              v = criteria[k];\n              if (v !== ((ref = record[k]) != null ? ref : \"null\")) {\n                return;\n              }\n            }\n            return callback(record);\n          };\n        })(this));\n      };\n\n      PivotData.prototype.arrSort = function(attrs) {\n        var a, sortersArr;\n        sortersArr = (function() {\n          var l, len1, results;\n          results = [];\n          for (l = 0, len1 = attrs.length; l < len1; l++) {\n            a = attrs[l];\n            results.push(getSort(this.sorters, a));\n          }\n          return results;\n        }).call(this);\n        return function(a, b) {\n          var comparison, i, sorter;\n          for (i in sortersArr) {\n            if (!hasProp.call(sortersArr, i)) continue;\n            sorter = sortersArr[i];\n            comparison = sorter(a[i], b[i]);\n            if (comparison !== 0) {\n              return comparison;\n            }\n          }\n          return 0;\n        };\n      };\n\n      PivotData.prototype.sortKeys = function() {\n        var v;\n        if (!this.sorted) {\n          this.sorted = true;\n          v = (function(_this) {\n            return function(r, c) {\n              return _this.getAggregator(r, c).value();\n            };\n          })(this);\n          switch (this.rowOrder) {\n            case \"value_a_to_z\":\n              this.rowKeys.sort((function(_this) {\n                return function(a, b) {\n                  return naturalSort(v(a, []), v(b, []));\n                };\n              })(this));\n              break;\n            case \"value_z_to_a\":\n              this.rowKeys.sort((function(_this) {\n                return function(a, b) {\n                  return -naturalSort(v(a, []), v(b, []));\n                };\n              })(this));\n              break;\n            default:\n              this.rowKeys.sort(this.arrSort(this.rowAttrs));\n          }\n          switch (this.colOrder) {\n            case \"value_a_to_z\":\n              return this.colKeys.sort((function(_this) {\n                return function(a, b) {\n                  return naturalSort(v([], a), v([], b));\n                };\n              })(this));\n            case \"value_z_to_a\":\n              return this.colKeys.sort((function(_this) {\n                return function(a, b) {\n                  return -naturalSort(v([], a), v([], b));\n                };\n              })(this));\n            default:\n              return this.colKeys.sort(this.arrSort(this.colAttrs));\n          }\n        }\n      };\n\n      PivotData.prototype.getColKeys = function() {\n        this.sortKeys();\n        return this.colKeys;\n      };\n\n      PivotData.prototype.getRowKeys = function() {\n        this.sortKeys();\n        return this.rowKeys;\n      };\n\n      PivotData.prototype.processRecord = function(record) {\n        var colKey, flatColKey, flatRowKey, l, len1, len2, n, ref, ref1, ref2, ref3, rowKey, x;\n        colKey = [];\n        rowKey = [];\n        ref = this.colAttrs;\n        for (l = 0, len1 = ref.length; l < len1; l++) {\n          x = ref[l];\n          colKey.push((ref1 = record[x]) != null ? ref1 : \"null\");\n        }\n        ref2 = this.rowAttrs;\n        for (n = 0, len2 = ref2.length; n < len2; n++) {\n          x = ref2[n];\n          rowKey.push((ref3 = record[x]) != null ? ref3 : \"null\");\n        }\n        flatRowKey = rowKey.join(String.fromCharCode(0));\n        flatColKey = colKey.join(String.fromCharCode(0));\n        this.allTotal.push(record);\n        if (rowKey.length !== 0) {\n          if (!this.rowTotals[flatRowKey]) {\n            this.rowKeys.push(rowKey);\n            this.rowTotals[flatRowKey] = this.aggregator(this, rowKey, []);\n          }\n          this.rowTotals[flatRowKey].push(record);\n        }\n        if (colKey.length !== 0) {\n          if (!this.colTotals[flatColKey]) {\n            this.colKeys.push(colKey);\n            this.colTotals[flatColKey] = this.aggregator(this, [], colKey);\n          }\n          this.colTotals[flatColKey].push(record);\n        }\n        if (colKey.length !== 0 && rowKey.length !== 0) {\n          if (!this.tree[flatRowKey]) {\n            this.tree[flatRowKey] = {};\n          }\n          if (!this.tree[flatRowKey][flatColKey]) {\n            this.tree[flatRowKey][flatColKey] = this.aggregator(this, rowKey, colKey);\n          }\n          return this.tree[flatRowKey][flatColKey].push(record);\n        }\n      };\n\n      PivotData.prototype.getAggregator = function(rowKey, colKey) {\n        var agg, flatColKey, flatRowKey;\n        flatRowKey = rowKey.join(String.fromCharCode(0));\n        flatColKey = colKey.join(String.fromCharCode(0));\n        if (rowKey.length === 0 && colKey.length === 0) {\n          agg = this.allTotal;\n        } else if (rowKey.length === 0) {\n          agg = this.colTotals[flatColKey];\n        } else if (colKey.length === 0) {\n          agg = this.rowTotals[flatRowKey];\n        } else {\n          agg = this.tree[flatRowKey][flatColKey];\n        }\n        return agg != null ? agg : {\n          value: (function() {\n            return null;\n          }),\n          format: function() {\n            return \"\";\n          }\n        };\n      };\n\n      return PivotData;\n\n    })();\n    $.pivotUtilities = {\n      aggregatorTemplates: aggregatorTemplates,\n      aggregators: aggregators,\n      renderers: renderers,\n      derivers: derivers,\n      locales: locales,\n      naturalSort: naturalSort,\n      numberFormat: numberFormat,\n      sortAs: sortAs,\n      PivotData: PivotData\n    };\n\n    /*\n    Default Renderer for hierarchical table layout\n     */\n    pivotTableRenderer = function(pivotData, opts) {\n      var aggregator, c, colAttrs, colKey, colKeys, defaults, getClickHandler, i, j, r, result, rowAttrs, rowKey, rowKeys, spanSize, tbody, td, th, thead, totalAggregator, tr, txt, val, x;\n      defaults = {\n        table: {\n          clickCallback: null,\n          rowTotals: true,\n          colTotals: true\n        },\n        localeStrings: {\n          totals: \"Totals\"\n        }\n      };\n      opts = $.extend(true, {}, defaults, opts);\n      colAttrs = pivotData.colAttrs;\n      rowAttrs = pivotData.rowAttrs;\n      rowKeys = pivotData.getRowKeys();\n      colKeys = pivotData.getColKeys();\n      if (opts.table.clickCallback) {\n        getClickHandler = function(value, rowValues, colValues) {\n          var attr, filters, i;\n          filters = {};\n          for (i in colAttrs) {\n            if (!hasProp.call(colAttrs, i)) continue;\n            attr = colAttrs[i];\n            if (colValues[i] != null) {\n              filters[attr] = colValues[i];\n            }\n          }\n          for (i in rowAttrs) {\n            if (!hasProp.call(rowAttrs, i)) continue;\n            attr = rowAttrs[i];\n            if (rowValues[i] != null) {\n              filters[attr] = rowValues[i];\n            }\n          }\n          return function(e) {\n            return opts.table.clickCallback(e, value, filters, pivotData);\n          };\n        };\n      }\n      result = document.createElement(\"table\");\n      result.className = \"pvtTable\";\n      spanSize = function(arr, i, j) {\n        var l, len, n, noDraw, ref, ref1, stop, x;\n        if (i !== 0) {\n          noDraw = true;\n          for (x = l = 0, ref = j; 0 <= ref ? l <= ref : l >= ref; x = 0 <= ref ? ++l : --l) {\n            if (arr[i - 1][x] !== arr[i][x]) {\n              noDraw = false;\n            }\n          }\n          if (noDraw) {\n            return -1;\n          }\n        }\n        len = 0;\n        while (i + len < arr.length) {\n          stop = false;\n          for (x = n = 0, ref1 = j; 0 <= ref1 ? n <= ref1 : n >= ref1; x = 0 <= ref1 ? ++n : --n) {\n            if (arr[i][x] !== arr[i + len][x]) {\n              stop = true;\n            }\n          }\n          if (stop) {\n            break;\n          }\n          len++;\n        }\n        return len;\n      };\n      thead = document.createElement(\"thead\");\n      for (j in colAttrs) {\n        if (!hasProp.call(colAttrs, j)) continue;\n        c = colAttrs[j];\n        tr = document.createElement(\"tr\");\n        if (parseInt(j) === 0 && rowAttrs.length !== 0) {\n          th = document.createElement(\"th\");\n          th.setAttribute(\"colspan\", rowAttrs.length);\n          th.setAttribute(\"rowspan\", colAttrs.length);\n          tr.appendChild(th);\n        }\n        th = document.createElement(\"th\");\n        th.className = \"pvtAxisLabel\";\n        th.textContent = c;\n        tr.appendChild(th);\n        for (i in colKeys) {\n          if (!hasProp.call(colKeys, i)) continue;\n          colKey = colKeys[i];\n          x = spanSize(colKeys, parseInt(i), parseInt(j));\n          if (x !== -1) {\n            th = document.createElement(\"th\");\n            th.className = \"pvtColLabel\";\n            th.textContent = colKey[j];\n            th.setAttribute(\"colspan\", x);\n            if (parseInt(j) === colAttrs.length - 1 && rowAttrs.length !== 0) {\n              th.setAttribute(\"rowspan\", 2);\n            }\n            tr.appendChild(th);\n          }\n        }\n        if (parseInt(j) === 0 && opts.table.rowTotals) {\n          th = document.createElement(\"th\");\n          th.className = \"pvtTotalLabel pvtRowTotalLabel\";\n          th.innerHTML = opts.localeStrings.totals;\n          th.setAttribute(\"rowspan\", colAttrs.length + (rowAttrs.length === 0 ? 0 : 1));\n          tr.appendChild(th);\n        }\n        thead.appendChild(tr);\n      }\n      if (rowAttrs.length !== 0) {\n        tr = document.createElement(\"tr\");\n        for (i in rowAttrs) {\n          if (!hasProp.call(rowAttrs, i)) continue;\n          r = rowAttrs[i];\n          th = document.createElement(\"th\");\n          th.className = \"pvtAxisLabel\";\n          th.textContent = r;\n          tr.appendChild(th);\n        }\n        th = document.createElement(\"th\");\n        if (colAttrs.length === 0) {\n          th.className = \"pvtTotalLabel pvtRowTotalLabel\";\n          th.innerHTML = opts.localeStrings.totals;\n        }\n        tr.appendChild(th);\n        thead.appendChild(tr);\n      }\n      result.appendChild(thead);\n      tbody = document.createElement(\"tbody\");\n      for (i in rowKeys) {\n        if (!hasProp.call(rowKeys, i)) continue;\n        rowKey = rowKeys[i];\n        tr = document.createElement(\"tr\");\n        for (j in rowKey) {\n          if (!hasProp.call(rowKey, j)) continue;\n          txt = rowKey[j];\n          x = spanSize(rowKeys, parseInt(i), parseInt(j));\n          if (x !== -1) {\n            th = document.createElement(\"th\");\n            th.className = \"pvtRowLabel\";\n            th.textContent = txt;\n            th.setAttribute(\"rowspan\", x);\n            if (parseInt(j) === rowAttrs.length - 1 && colAttrs.length !== 0) {\n              th.setAttribute(\"colspan\", 2);\n            }\n            tr.appendChild(th);\n          }\n        }\n        for (j in colKeys) {\n          if (!hasProp.call(colKeys, j)) continue;\n          colKey = colKeys[j];\n          aggregator = pivotData.getAggregator(rowKey, colKey);\n          val = aggregator.value();\n          td = document.createElement(\"td\");\n          td.className = \"pvtVal row\" + i + \" col\" + j;\n          td.textContent = aggregator.format(val);\n          td.setAttribute(\"data-value\", val);\n          if (getClickHandler != null) {\n            td.onclick = getClickHandler(val, rowKey, colKey);\n          }\n          tr.appendChild(td);\n        }\n        if (opts.table.rowTotals || colAttrs.length === 0) {\n          totalAggregator = pivotData.getAggregator(rowKey, []);\n          val = totalAggregator.value();\n          td = document.createElement(\"td\");\n          td.className = \"pvtTotal rowTotal\";\n          td.textContent = totalAggregator.format(val);\n          td.setAttribute(\"data-value\", val);\n          if (getClickHandler != null) {\n            td.onclick = getClickHandler(val, rowKey, []);\n          }\n          td.setAttribute(\"data-for\", \"row\" + i);\n          tr.appendChild(td);\n        }\n        tbody.appendChild(tr);\n      }\n      if (opts.table.colTotals || rowAttrs.length === 0) {\n        tr = document.createElement(\"tr\");\n        if (opts.table.colTotals || rowAttrs.length === 0) {\n          th = document.createElement(\"th\");\n          th.className = \"pvtTotalLabel pvtColTotalLabel\";\n          th.innerHTML = opts.localeStrings.totals;\n          th.setAttribute(\"colspan\", rowAttrs.length + (colAttrs.length === 0 ? 0 : 1));\n          tr.appendChild(th);\n        }\n        for (j in colKeys) {\n          if (!hasProp.call(colKeys, j)) continue;\n          colKey = colKeys[j];\n          totalAggregator = pivotData.getAggregator([], colKey);\n          val = totalAggregator.value();\n          td = document.createElement(\"td\");\n          td.className = \"pvtTotal colTotal\";\n          td.textContent = totalAggregator.format(val);\n          td.setAttribute(\"data-value\", val);\n          if (getClickHandler != null) {\n            td.onclick = getClickHandler(val, [], colKey);\n          }\n          td.setAttribute(\"data-for\", \"col\" + j);\n          tr.appendChild(td);\n        }\n        if (opts.table.rowTotals || colAttrs.length === 0) {\n          totalAggregator = pivotData.getAggregator([], []);\n          val = totalAggregator.value();\n          td = document.createElement(\"td\");\n          td.className = \"pvtGrandTotal\";\n          td.textContent = totalAggregator.format(val);\n          td.setAttribute(\"data-value\", val);\n          if (getClickHandler != null) {\n            td.onclick = getClickHandler(val, [], []);\n          }\n          tr.appendChild(td);\n        }\n        tbody.appendChild(tr);\n      }\n      result.appendChild(tbody);\n      result.setAttribute(\"data-numrows\", rowKeys.length);\n      result.setAttribute(\"data-numcols\", colKeys.length);\n      return result;\n    };\n\n    /*\n    Pivot Table core: create PivotData object and call Renderer on it\n     */\n    $.fn.pivot = function(input, inputOpts, locale) {\n      var defaults, e, localeDefaults, localeStrings, opts, pivotData, result, x;\n      if (locale == null) {\n        locale = \"en\";\n      }\n      if (locales[locale] == null) {\n        locale = \"en\";\n      }\n      defaults = {\n        cols: [],\n        rows: [],\n        vals: [],\n        rowOrder: \"key_a_to_z\",\n        colOrder: \"key_a_to_z\",\n        dataClass: PivotData,\n        filter: function() {\n          return true;\n        },\n        aggregator: aggregatorTemplates.count()(),\n        aggregatorName: \"Count\",\n        sorters: {},\n        derivedAttributes: {},\n        renderer: pivotTableRenderer\n      };\n      localeStrings = $.extend(true, {}, locales.en.localeStrings, locales[locale].localeStrings);\n      localeDefaults = {\n        rendererOptions: {\n          localeStrings: localeStrings\n        },\n        localeStrings: localeStrings\n      };\n      opts = $.extend(true, {}, localeDefaults, $.extend({}, defaults, inputOpts));\n      result = null;\n      try {\n        pivotData = new opts.dataClass(input, opts);\n        try {\n          result = opts.renderer(pivotData, opts.rendererOptions);\n        } catch (error) {\n          e = error;\n          if (typeof console !== \"undefined\" && console !== null) {\n            console.error(e.stack);\n          }\n          result = $(\"<span>\").html(opts.localeStrings.renderError);\n        }\n      } catch (error) {\n        e = error;\n        if (typeof console !== \"undefined\" && console !== null) {\n          console.error(e.stack);\n        }\n        result = $(\"<span>\").html(opts.localeStrings.computeError);\n      }\n      x = this[0];\n      while (x.hasChildNodes()) {\n        x.removeChild(x.lastChild);\n      }\n      return this.append(result);\n    };\n\n    /*\n    Pivot Table UI: calls Pivot Table core above with options set by user\n     */\n    $.fn.pivotUI = function(input, inputOpts, overwrite, locale) {\n      var a, aggregator, attr, attrLength, attrValues, c, colOrderArrow, defaults, e, existingOpts, fn1, i, initialRender, l, len1, len2, len3, localeDefaults, localeStrings, materializedInput, n, o, opts, ordering, pivotTable, recordsProcessed, ref, ref1, ref2, ref3, refresh, refreshDelayed, renderer, rendererControl, rowOrderArrow, shownAttributes, shownInAggregators, shownInDragDrop, tr1, tr2, uiTable, unused, unusedAttrsVerticalAutoCutoff, unusedAttrsVerticalAutoOverride, x;\n      if (overwrite == null) {\n        overwrite = false;\n      }\n      if (locale == null) {\n        locale = \"en\";\n      }\n      if (locales[locale] == null) {\n        locale = \"en\";\n      }\n      defaults = {\n        derivedAttributes: {},\n        aggregators: locales[locale].aggregators,\n        renderers: locales[locale].renderers,\n        hiddenAttributes: [],\n        hiddenFromAggregators: [],\n        hiddenFromDragDrop: [],\n        menuLimit: 500,\n        cols: [],\n        rows: [],\n        vals: [],\n        rowOrder: \"key_a_to_z\",\n        colOrder: \"key_a_to_z\",\n        dataClass: PivotData,\n        exclusions: {},\n        inclusions: {},\n        unusedAttrsVertical: 85,\n        autoSortUnusedAttrs: false,\n        onRefresh: null,\n        showUI: true,\n        filter: function() {\n          return true;\n        },\n        sorters: {}\n      };\n      localeStrings = $.extend(true, {}, locales.en.localeStrings, locales[locale].localeStrings);\n      localeDefaults = {\n        rendererOptions: {\n          localeStrings: localeStrings\n        },\n        localeStrings: localeStrings\n      };\n      existingOpts = this.data(\"pivotUIOptions\");\n      if ((existingOpts == null) || overwrite) {\n        opts = $.extend(true, {}, localeDefaults, $.extend({}, defaults, inputOpts));\n      } else {\n        opts = existingOpts;\n      }\n      try {\n        attrValues = {};\n        materializedInput = [];\n        recordsProcessed = 0;\n        PivotData.forEachRecord(input, opts.derivedAttributes, function(record) {\n          var attr, base, ref, value;\n          if (!opts.filter(record)) {\n            return;\n          }\n          materializedInput.push(record);\n          for (attr in record) {\n            if (!hasProp.call(record, attr)) continue;\n            if (attrValues[attr] == null) {\n              attrValues[attr] = {};\n              if (recordsProcessed > 0) {\n                attrValues[attr][\"null\"] = recordsProcessed;\n              }\n            }\n          }\n          for (attr in attrValues) {\n            value = (ref = record[attr]) != null ? ref : \"null\";\n            if ((base = attrValues[attr])[value] == null) {\n              base[value] = 0;\n            }\n            attrValues[attr][value]++;\n          }\n          return recordsProcessed++;\n        });\n        uiTable = $(\"<table>\", {\n          \"class\": \"pvtUi\"\n        }).attr(\"cellpadding\", 5);\n        rendererControl = $(\"<td>\").addClass(\"pvtUiCell\");\n        renderer = $(\"<select>\").addClass('pvtRenderer').appendTo(rendererControl).bind(\"change\", function() {\n          return refresh();\n        });\n        ref = opts.renderers;\n        for (x in ref) {\n          if (!hasProp.call(ref, x)) continue;\n          $(\"<option>\").val(x).html(x).appendTo(renderer);\n        }\n        unused = $(\"<td>\").addClass('pvtAxisContainer pvtUnused pvtUiCell');\n        shownAttributes = (function() {\n          var results;\n          results = [];\n          for (a in attrValues) {\n            if (indexOf.call(opts.hiddenAttributes, a) < 0) {\n              results.push(a);\n            }\n          }\n          return results;\n        })();\n        shownInAggregators = (function() {\n          var l, len1, results;\n          results = [];\n          for (l = 0, len1 = shownAttributes.length; l < len1; l++) {\n            c = shownAttributes[l];\n            if (indexOf.call(opts.hiddenFromAggregators, c) < 0) {\n              results.push(c);\n            }\n          }\n          return results;\n        })();\n        shownInDragDrop = (function() {\n          var l, len1, results;\n          results = [];\n          for (l = 0, len1 = shownAttributes.length; l < len1; l++) {\n            c = shownAttributes[l];\n            if (indexOf.call(opts.hiddenFromDragDrop, c) < 0) {\n              results.push(c);\n            }\n          }\n          return results;\n        })();\n        unusedAttrsVerticalAutoOverride = false;\n        if (opts.unusedAttrsVertical === \"auto\") {\n          unusedAttrsVerticalAutoCutoff = 120;\n        } else {\n          unusedAttrsVerticalAutoCutoff = parseInt(opts.unusedAttrsVertical);\n        }\n        if (!isNaN(unusedAttrsVerticalAutoCutoff)) {\n          attrLength = 0;\n          for (l = 0, len1 = shownInDragDrop.length; l < len1; l++) {\n            a = shownInDragDrop[l];\n            attrLength += a.length;\n          }\n          unusedAttrsVerticalAutoOverride = attrLength > unusedAttrsVerticalAutoCutoff;\n        }\n        if (opts.unusedAttrsVertical === true || unusedAttrsVerticalAutoOverride) {\n          unused.addClass('pvtVertList');\n        } else {\n          unused.addClass('pvtHorizList');\n        }\n        fn1 = function(attr) {\n          var attrElem, checkContainer, closeFilterBox, controls, filterItem, filterItemExcluded, finalButtons, hasExcludedItem, len2, n, placeholder, ref1, sorter, triangleLink, v, value, valueCount, valueList, values;\n          values = (function() {\n            var results;\n            results = [];\n            for (v in attrValues[attr]) {\n              results.push(v);\n            }\n            return results;\n          })();\n          hasExcludedItem = false;\n          valueList = $(\"<div>\").addClass('pvtFilterBox').hide();\n          valueList.append($(\"<h4>\").append($(\"<span>\").text(attr), $(\"<span>\").addClass(\"count\").text(\"(\" + values.length + \")\")));\n          if (values.length > opts.menuLimit) {\n            valueList.append($(\"<p>\").html(opts.localeStrings.tooMany));\n          } else {\n            if (values.length > 5) {\n              controls = $(\"<p>\").appendTo(valueList);\n              sorter = getSort(opts.sorters, attr);\n              placeholder = opts.localeStrings.filterResults;\n              $(\"<input>\", {\n                type: \"text\"\n              }).appendTo(controls).attr({\n                placeholder: placeholder,\n                \"class\": \"pvtSearch\"\n              }).bind(\"keyup\", function() {\n                var accept, accept_gen, filter;\n                filter = $(this).val().toLowerCase().trim();\n                accept_gen = function(prefix, accepted) {\n                  return function(v) {\n                    var real_filter, ref1;\n                    real_filter = filter.substring(prefix.length).trim();\n                    if (real_filter.length === 0) {\n                      return true;\n                    }\n                    return ref1 = Math.sign(sorter(v.toLowerCase(), real_filter)), indexOf.call(accepted, ref1) >= 0;\n                  };\n                };\n                accept = filter.indexOf(\">=\") === 0 ? accept_gen(\">=\", [1, 0]) : filter.indexOf(\"<=\") === 0 ? accept_gen(\"<=\", [-1, 0]) : filter.indexOf(\">\") === 0 ? accept_gen(\">\", [1]) : filter.indexOf(\"<\") === 0 ? accept_gen(\"<\", [-1]) : filter.indexOf(\"~\") === 0 ? function(v) {\n                  if (filter.substring(1).trim().length === 0) {\n                    return true;\n                  }\n                  return v.toLowerCase().match(filter.substring(1));\n                } : function(v) {\n                  return v.toLowerCase().indexOf(filter) !== -1;\n                };\n                return valueList.find('.pvtCheckContainer p label span.value').each(function() {\n                  if (accept($(this).text())) {\n                    return $(this).parent().parent().show();\n                  } else {\n                    return $(this).parent().parent().hide();\n                  }\n                });\n              });\n              controls.append($(\"<br>\"));\n              $(\"<button>\", {\n                type: \"button\"\n              }).appendTo(controls).html(opts.localeStrings.selectAll).bind(\"click\", function() {\n                valueList.find(\"input:visible:not(:checked)\").prop(\"checked\", true).toggleClass(\"changed\");\n                return false;\n              });\n              $(\"<button>\", {\n                type: \"button\"\n              }).appendTo(controls).html(opts.localeStrings.selectNone).bind(\"click\", function() {\n                valueList.find(\"input:visible:checked\").prop(\"checked\", false).toggleClass(\"changed\");\n                return false;\n              });\n            }\n            checkContainer = $(\"<div>\").addClass(\"pvtCheckContainer\").appendTo(valueList);\n            ref1 = values.sort(getSort(opts.sorters, attr));\n            for (n = 0, len2 = ref1.length; n < len2; n++) {\n              value = ref1[n];\n              valueCount = attrValues[attr][value];\n              filterItem = $(\"<label>\");\n              filterItemExcluded = false;\n              if (opts.inclusions[attr]) {\n                filterItemExcluded = (indexOf.call(opts.inclusions[attr], value) < 0);\n              } else if (opts.exclusions[attr]) {\n                filterItemExcluded = (indexOf.call(opts.exclusions[attr], value) >= 0);\n              }\n              hasExcludedItem || (hasExcludedItem = filterItemExcluded);\n              $(\"<input>\").attr(\"type\", \"checkbox\").addClass('pvtFilter').attr(\"checked\", !filterItemExcluded).data(\"filter\", [attr, value]).appendTo(filterItem).bind(\"change\", function() {\n                return $(this).toggleClass(\"changed\");\n              });\n              filterItem.append($(\"<span>\").addClass(\"value\").text(value));\n              filterItem.append($(\"<span>\").addClass(\"count\").text(\"(\" + valueCount + \")\"));\n              checkContainer.append($(\"<p>\").append(filterItem));\n            }\n          }\n          closeFilterBox = function() {\n            if (valueList.find(\"[type='checkbox']\").length > valueList.find(\"[type='checkbox']:checked\").length) {\n              attrElem.addClass(\"pvtFilteredAttribute\");\n            } else {\n              attrElem.removeClass(\"pvtFilteredAttribute\");\n            }\n            valueList.find('.pvtSearch').val('');\n            valueList.find('.pvtCheckContainer p').show();\n            return valueList.hide();\n          };\n          finalButtons = $(\"<p>\").appendTo(valueList);\n          if (values.length <= opts.menuLimit) {\n            $(\"<button>\", {\n              type: \"button\"\n            }).text(opts.localeStrings.apply).appendTo(finalButtons).bind(\"click\", function() {\n              if (valueList.find(\".changed\").removeClass(\"changed\").length) {\n                refresh();\n              }\n              return closeFilterBox();\n            });\n          }\n          $(\"<button>\", {\n            type: \"button\"\n          }).text(opts.localeStrings.cancel).appendTo(finalButtons).bind(\"click\", function() {\n            valueList.find(\".changed:checked\").removeClass(\"changed\").prop(\"checked\", false);\n            valueList.find(\".changed:not(:checked)\").removeClass(\"changed\").prop(\"checked\", true);\n            return closeFilterBox();\n          });\n          triangleLink = $(\"<span>\").addClass('pvtTriangle').html(\" &#x25BE;\").bind(\"click\", function(e) {\n            var left, ref2, top;\n            ref2 = $(e.currentTarget).position(), left = ref2.left, top = ref2.top;\n            return valueList.css({\n              left: left + 10,\n              top: top + 10\n            }).show();\n          });\n          attrElem = $(\"<li>\").addClass(\"axis_\" + i).append($(\"<span>\").addClass('pvtAttr').text(attr).data(\"attrName\", attr).append(triangleLink));\n          if (hasExcludedItem) {\n            attrElem.addClass('pvtFilteredAttribute');\n          }\n          return unused.append(attrElem).append(valueList);\n        };\n        for (i in shownInDragDrop) {\n          if (!hasProp.call(shownInDragDrop, i)) continue;\n          attr = shownInDragDrop[i];\n          fn1(attr);\n        }\n        tr1 = $(\"<tr>\").appendTo(uiTable);\n        aggregator = $(\"<select>\").addClass('pvtAggregator').bind(\"change\", function() {\n          return refresh();\n        });\n        ref1 = opts.aggregators;\n        for (x in ref1) {\n          if (!hasProp.call(ref1, x)) continue;\n          aggregator.append($(\"<option>\").val(x).html(x));\n        }\n        ordering = {\n          key_a_to_z: {\n            rowSymbol: \"&varr;\",\n            colSymbol: \"&harr;\",\n            next: \"value_a_to_z\"\n          },\n          value_a_to_z: {\n            rowSymbol: \"&darr;\",\n            colSymbol: \"&rarr;\",\n            next: \"value_z_to_a\"\n          },\n          value_z_to_a: {\n            rowSymbol: \"&uarr;\",\n            colSymbol: \"&larr;\",\n            next: \"key_a_to_z\"\n          }\n        };\n        rowOrderArrow = $(\"<a>\", {\n          role: \"button\"\n        }).addClass(\"pvtRowOrder\").data(\"order\", opts.rowOrder).html(ordering[opts.rowOrder].rowSymbol).bind(\"click\", function() {\n          $(this).data(\"order\", ordering[$(this).data(\"order\")].next);\n          $(this).html(ordering[$(this).data(\"order\")].rowSymbol);\n          return refresh();\n        });\n        colOrderArrow = $(\"<a>\", {\n          role: \"button\"\n        }).addClass(\"pvtColOrder\").data(\"order\", opts.colOrder).html(ordering[opts.colOrder].colSymbol).bind(\"click\", function() {\n          $(this).data(\"order\", ordering[$(this).data(\"order\")].next);\n          $(this).html(ordering[$(this).data(\"order\")].colSymbol);\n          return refresh();\n        });\n        $(\"<td>\").addClass('pvtVals pvtUiCell').appendTo(tr1).append(aggregator).append(rowOrderArrow).append(colOrderArrow).append($(\"<br>\"));\n        $(\"<td>\").addClass('pvtAxisContainer pvtHorizList pvtCols pvtUiCell').appendTo(tr1);\n        tr2 = $(\"<tr>\").appendTo(uiTable);\n        tr2.append($(\"<td>\").addClass('pvtAxisContainer pvtRows pvtUiCell').attr(\"valign\", \"top\"));\n        pivotTable = $(\"<td>\").attr(\"valign\", \"top\").addClass('pvtRendererArea').appendTo(tr2);\n        if (opts.unusedAttrsVertical === true || unusedAttrsVerticalAutoOverride) {\n          uiTable.find('tr:nth-child(1)').prepend(rendererControl);\n          uiTable.find('tr:nth-child(2)').prepend(unused);\n        } else {\n          uiTable.prepend($(\"<tr>\").append(rendererControl).append(unused));\n        }\n        this.html(uiTable);\n        ref2 = opts.cols;\n        for (n = 0, len2 = ref2.length; n < len2; n++) {\n          x = ref2[n];\n          this.find(\".pvtCols\").append(this.find(\".axis_\" + ($.inArray(x, shownInDragDrop))));\n        }\n        ref3 = opts.rows;\n        for (o = 0, len3 = ref3.length; o < len3; o++) {\n          x = ref3[o];\n          this.find(\".pvtRows\").append(this.find(\".axis_\" + ($.inArray(x, shownInDragDrop))));\n        }\n        if (opts.aggregatorName != null) {\n          this.find(\".pvtAggregator\").val(opts.aggregatorName);\n        }\n        if (opts.rendererName != null) {\n          this.find(\".pvtRenderer\").val(opts.rendererName);\n        }\n        if (!opts.showUI) {\n          this.find(\".pvtUiCell\").hide();\n        }\n        initialRender = true;\n        refreshDelayed = (function(_this) {\n          return function() {\n            var exclusions, inclusions, len4, newDropdown, numInputsToProcess, pivotUIOptions, pvtVals, ref4, ref5, subopts, t, u, unusedAttrsContainer, vals;\n            subopts = {\n              derivedAttributes: opts.derivedAttributes,\n              localeStrings: opts.localeStrings,\n              rendererOptions: opts.rendererOptions,\n              sorters: opts.sorters,\n              cols: [],\n              rows: [],\n              dataClass: opts.dataClass\n            };\n            numInputsToProcess = (ref4 = opts.aggregators[aggregator.val()]([])().numInputs) != null ? ref4 : 0;\n            vals = [];\n            _this.find(\".pvtRows li span.pvtAttr\").each(function() {\n              return subopts.rows.push($(this).data(\"attrName\"));\n            });\n            _this.find(\".pvtCols li span.pvtAttr\").each(function() {\n              return subopts.cols.push($(this).data(\"attrName\"));\n            });\n            _this.find(\".pvtVals select.pvtAttrDropdown\").each(function() {\n              if (numInputsToProcess === 0) {\n                return $(this).remove();\n              } else {\n                numInputsToProcess--;\n                if ($(this).val() !== \"\") {\n                  return vals.push($(this).val());\n                }\n              }\n            });\n            if (numInputsToProcess !== 0) {\n              pvtVals = _this.find(\".pvtVals\");\n              for (x = t = 0, ref5 = numInputsToProcess; 0 <= ref5 ? t < ref5 : t > ref5; x = 0 <= ref5 ? ++t : --t) {\n                newDropdown = $(\"<select>\").addClass('pvtAttrDropdown').append($(\"<option>\")).bind(\"change\", function() {\n                  return refresh();\n                });\n                for (u = 0, len4 = shownInAggregators.length; u < len4; u++) {\n                  attr = shownInAggregators[u];\n                  newDropdown.append($(\"<option>\").val(attr).text(attr));\n                }\n                pvtVals.append(newDropdown);\n              }\n            }\n            if (initialRender) {\n              vals = opts.vals;\n              i = 0;\n              _this.find(\".pvtVals select.pvtAttrDropdown\").each(function() {\n                $(this).val(vals[i]);\n                return i++;\n              });\n              initialRender = false;\n            }\n            subopts.aggregatorName = aggregator.val();\n            subopts.vals = vals;\n            subopts.aggregator = opts.aggregators[aggregator.val()](vals);\n            subopts.renderer = opts.renderers[renderer.val()];\n            subopts.rowOrder = rowOrderArrow.data(\"order\");\n            subopts.colOrder = colOrderArrow.data(\"order\");\n            exclusions = {};\n            _this.find('input.pvtFilter').not(':checked').each(function() {\n              var filter;\n              filter = $(this).data(\"filter\");\n              if (exclusions[filter[0]] != null) {\n                return exclusions[filter[0]].push(filter[1]);\n              } else {\n                return exclusions[filter[0]] = [filter[1]];\n              }\n            });\n            inclusions = {};\n            _this.find('input.pvtFilter:checked').each(function() {\n              var filter;\n              filter = $(this).data(\"filter\");\n              if (exclusions[filter[0]] != null) {\n                if (inclusions[filter[0]] != null) {\n                  return inclusions[filter[0]].push(filter[1]);\n                } else {\n                  return inclusions[filter[0]] = [filter[1]];\n                }\n              }\n            });\n            subopts.filter = function(record) {\n              var excludedItems, k, ref6, ref7;\n              if (!opts.filter(record)) {\n                return false;\n              }\n              for (k in exclusions) {\n                excludedItems = exclusions[k];\n                if (ref6 = \"\" + ((ref7 = record[k]) != null ? ref7 : 'null'), indexOf.call(excludedItems, ref6) >= 0) {\n                  return false;\n                }\n              }\n              return true;\n            };\n            pivotTable.pivot(materializedInput, subopts);\n            pivotUIOptions = $.extend({}, opts, {\n              cols: subopts.cols,\n              rows: subopts.rows,\n              colOrder: subopts.colOrder,\n              rowOrder: subopts.rowOrder,\n              vals: vals,\n              exclusions: exclusions,\n              inclusions: inclusions,\n              inclusionsInfo: inclusions,\n              aggregatorName: aggregator.val(),\n              rendererName: renderer.val()\n            });\n            _this.data(\"pivotUIOptions\", pivotUIOptions);\n            if (opts.autoSortUnusedAttrs) {\n              unusedAttrsContainer = _this.find(\"td.pvtUnused.pvtAxisContainer\");\n              $(unusedAttrsContainer).children(\"li\").sort(function(a, b) {\n                return naturalSort($(a).text(), $(b).text());\n              }).appendTo(unusedAttrsContainer);\n            }\n            pivotTable.css(\"opacity\", 1);\n            if (opts.onRefresh != null) {\n              return opts.onRefresh(pivotUIOptions);\n            }\n          };\n        })(this);\n        refresh = (function(_this) {\n          return function() {\n            pivotTable.css(\"opacity\", 0.5);\n            return setTimeout(refreshDelayed, 10);\n          };\n        })(this);\n        refresh();\n        this.find(\".pvtAxisContainer\").sortable({\n          update: function(e, ui) {\n            if (ui.sender == null) {\n              return refresh();\n            }\n          },\n          connectWith: this.find(\".pvtAxisContainer\"),\n          items: 'li',\n          placeholder: 'pvtPlaceholder'\n        });\n      } catch (error) {\n        e = error;\n        if (typeof console !== \"undefined\" && console !== null) {\n          console.error(e.stack);\n        }\n        this.html(opts.localeStrings.uiRenderError);\n      }\n      return this;\n    };\n\n    /*\n    Heatmap post-processing\n     */\n    $.fn.heatmap = function(scope, opts) {\n      var colorScaleGenerator, heatmapper, i, j, l, n, numCols, numRows, ref, ref1, ref2;\n      if (scope == null) {\n        scope = \"heatmap\";\n      }\n      numRows = this.data(\"numrows\");\n      numCols = this.data(\"numcols\");\n      colorScaleGenerator = opts != null ? (ref = opts.heatmap) != null ? ref.colorScaleGenerator : void 0 : void 0;\n      if (colorScaleGenerator == null) {\n        colorScaleGenerator = function(values) {\n          var max, min;\n          min = Math.min.apply(Math, values);\n          max = Math.max.apply(Math, values);\n          return function(x) {\n            var nonRed;\n            nonRed = 255 - Math.round(255 * (x - min) / (max - min));\n            return \"rgb(255,\" + nonRed + \",\" + nonRed + \")\";\n          };\n        };\n      }\n      heatmapper = (function(_this) {\n        return function(scope) {\n          var colorScale, forEachCell, values;\n          forEachCell = function(f) {\n            return _this.find(scope).each(function() {\n              var x;\n              x = $(this).data(\"value\");\n              if ((x != null) && isFinite(x)) {\n                return f(x, $(this));\n              }\n            });\n          };\n          values = [];\n          forEachCell(function(x) {\n            return values.push(x);\n          });\n          colorScale = colorScaleGenerator(values);\n          return forEachCell(function(x, elem) {\n            return elem.css(\"background-color\", colorScale(x));\n          });\n        };\n      })(this);\n      switch (scope) {\n        case \"heatmap\":\n          heatmapper(\".pvtVal\");\n          break;\n        case \"rowheatmap\":\n          for (i = l = 0, ref1 = numRows; 0 <= ref1 ? l < ref1 : l > ref1; i = 0 <= ref1 ? ++l : --l) {\n            heatmapper(\".pvtVal.row\" + i);\n          }\n          break;\n        case \"colheatmap\":\n          for (j = n = 0, ref2 = numCols; 0 <= ref2 ? n < ref2 : n > ref2; j = 0 <= ref2 ? ++n : --n) {\n            heatmapper(\".pvtVal.col\" + j);\n          }\n      }\n      heatmapper(\".pvtTotal.rowTotal\");\n      heatmapper(\".pvtTotal.colTotal\");\n      return this;\n    };\n\n    /*\n    Barchart post-processing\n     */\n    return $.fn.barchart = function(opts) {\n      var barcharter, i, l, numCols, numRows, ref;\n      numRows = this.data(\"numrows\");\n      numCols = this.data(\"numcols\");\n      barcharter = (function(_this) {\n        return function(scope) {\n          var forEachCell, max, min, range, scaler, values;\n          forEachCell = function(f) {\n            return _this.find(scope).each(function() {\n              var x;\n              x = $(this).data(\"value\");\n              if ((x != null) && isFinite(x)) {\n                return f(x, $(this));\n              }\n            });\n          };\n          values = [];\n          forEachCell(function(x) {\n            return values.push(x);\n          });\n          max = Math.max.apply(Math, values);\n          if (max < 0) {\n            max = 0;\n          }\n          range = max;\n          min = Math.min.apply(Math, values);\n          if (min < 0) {\n            range = max - min;\n          }\n          scaler = function(x) {\n            return 100 * x / (1.4 * range);\n          };\n          return forEachCell(function(x, elem) {\n            var bBase, bgColor, text, wrapper;\n            text = elem.text();\n            wrapper = $(\"<div>\").css({\n              \"position\": \"relative\",\n              \"height\": \"55px\"\n            });\n            bgColor = \"gray\";\n            bBase = 0;\n            if (min < 0) {\n              bBase = scaler(-min);\n            }\n            if (x < 0) {\n              bBase += scaler(x);\n              bgColor = \"darkred\";\n              x = -x;\n            }\n            wrapper.append($(\"<div>\").css({\n              \"position\": \"absolute\",\n              \"bottom\": bBase + \"%\",\n              \"left\": 0,\n              \"right\": 0,\n              \"height\": scaler(x) + \"%\",\n              \"background-color\": bgColor\n            }));\n            wrapper.append($(\"<div>\").text(text).css({\n              \"position\": \"relative\",\n              \"padding-left\": \"5px\",\n              \"padding-right\": \"5px\"\n            }));\n            return elem.css({\n              \"padding\": 0,\n              \"padding-top\": \"5px\",\n              \"text-align\": \"center\"\n            }).html(wrapper);\n          });\n        };\n      })(this);\n      for (i = l = 0, ref = numRows; 0 <= ref ? l < ref : l > ref; i = 0 <= ref ? ++l : --l) {\n        barcharter(\".pvtVal.row\" + i);\n      }\n      barcharter(\".pvtTotal.colTotal\");\n      return this;\n    };\n  });\n\n}).call(this);\n\n//# sourceMappingURL=pivot.js.map\n"]}
\ No newline at end of file
diff --git a/dist/pivot_spec.js b/dist/pivot_spec.js
index fadadced..7720ed2a 100644
--- a/dist/pivot_spec.js
+++ b/dist/pivot_spec.js
@@ -322,6 +322,31 @@
           return expect(pd.getAggregator([], []).value()).toBe((1 + 3) / (2 + 4));
         });
       });
+      describe("with a0-a00 input", function() {
+        var aoaInput, pd;
+        aoaInput = [
+          {
+            key: 'a0',
+            ym: '2020-01'
+          }, {
+            key: 'a0',
+            ym: '2020-02'
+          }, {
+            key: 'a00',
+            ym: '2020-01'
+          }, {
+            key: 'a00',
+            ym: '2020-02'
+          }
+        ];
+        pd = new $.pivotUtilities.PivotData(aoaInput, {
+          rows: ["key", "ym"],
+          cols: []
+        });
+        return it("has correctly-ordered row keys", function() {
+          return expect(pd.getRowKeys()).toEqual([["a0", "2020-01"], ["a0", "2020-02"], ["a00", "2020-01"], ["a00", "2020-02"]]);
+        });
+      });
       return describe("with rows/cols", function() {
         var pd;
         pd = new $.pivotUtilities.PivotData(fixtureData, {
diff --git a/dist/pivot_spec.js.map b/dist/pivot_spec.js.map
index d5d27b95..df707f48 100644
--- a/dist/pivot_spec.js.map
+++ b/dist/pivot_spec.js.map
@@ -1 +1 @@
-{"version":3,"file":"pivot_spec.js","sources":["pivot_spec.coffee"],"names":[],"mappings":"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","sourcesContent":["fixtureData = [\n    [\"name\",    \"gender\",   \"colour\",    \"birthday\",     \"trials\",   \"successes\"],\n    [\"Nick\",    \"male\",     \"blue\",      \"1982-11-07\",   103,        12],\n    [\"Jane\",    \"female\",   \"red\",       \"1982-11-08\",   95,         25],\n    [\"John\",    \"male\",     \"blue\",      \"1982-12-08\",   112,        30],\n    [\"Carol\",   \"female\",   \"yellow\",    \"1983-12-08\",   102,        14]\n]\n\nraggedFixtureData = [\n    {name: \"Nick\", \"colour\": \"red\", \"age\": 34}\n    {name: \"Jane\", \"gender\": \"female\"}\n    {name: \"John\", \"gender\": \"male\", \"age\": 12}\n    {name: \"Jim\", \"gender\": null, \"age\": 12}\n]\n\ndescribe \"$.pivotUI()\", ->\n    describe \"with no rows/cols, default count aggregator, default TableRenderer\",  ->\n        table = null\n\n        beforeEach (done) ->\n            table = $(\"<div>\").pivotUI fixtureData, onRefresh: done\n        it \"has all the basic UI elements\", (done) ->\n            expect table.find(\"td.pvtAxisContainer\").length\n            .toBe  3\n            expect table.find(\"td.pvtRendererArea\").length\n            .toBe  1\n            expect table.find(\"td.pvtVals\").length\n            .toBe  1\n            expect table.find(\"select.pvtRenderer\").length\n            .toBe  1\n            expect table.find(\"select.pvtAggregator\").length\n            .toBe  1\n            expect table.find(\"span.pvtAttr\").length\n            .toBe  6\n            done()\n\n        it \"reflects its inputs\", (done) ->\n            expect table.find(\"td.pvtUnused span.pvtAttr\").length\n            .toBe  6\n            expect table.find(\"select.pvtRenderer\").val()\n            .toBe  \"Table\"\n            expect table.find(\"select.pvtAggregator\").val()\n            .toBe  \"Count\"\n            done()\n\n        it \"renders a table\", (done) ->\n            expect table.find(\"table.pvtTable\").length\n            .toBe  1\n            done()\n\n\n        describe \"its renderer output\", ->\n            it \"has the correct type and number of cells\", (done) ->\n                expect table.find(\"th.pvtTotalLabel\").length\n                .toBe  1\n                expect table.find(\"td.pvtGrandTotal\").length\n                .toBe  1\n                done()\n\n            it \"has the correct textual representation\", (done) ->\n                expect table.find(\"table.pvtTable\").text()\n                .toBe [\"Totals\", \"4\"].join(\"\")\n                done()\n\n            it \"has a correct grand total with data value\", (done) ->\n                expect table.find(\"td.pvtGrandTotal\").text()\n                .toBe  \"4\"\n                expect table.find(\"td.pvtGrandTotal\").data(\"value\")\n                .toBe  4\n                done()\n\n    describe \"with rows/cols, sum-over-sum aggregator, Heatmap renderer\",  ->\n        table = null\n\n        beforeEach (done) ->\n            table = $(\"<div>\").pivotUI fixtureData,\n                rows: [\"gender\"], cols: [\"colour\"]\n                aggregatorName: \"Sum over Sum\"\n                vals: [\"successes\", \"trials\"]\n                rendererName: \"Heatmap\"\n                onRefresh: done\n\n        it \"has all the basic UI elements\", (done) ->\n            expect table.find(\"td.pvtAxisContainer\").length\n            .toBe  3\n            expect table.find(\"td.pvtRendererArea\").length\n            .toBe  1\n            expect table.find(\"td.pvtVals\").length\n            .toBe  1\n            expect table.find(\"select.pvtRenderer\").length\n            .toBe  1\n            expect table.find(\"select.pvtAggregator\").length\n            .toBe  1\n            expect table.find(\"span.pvtAttr\").length\n            .toBe  6\n            done()\n\n        it \"reflects its inputs\", (done) ->\n            expect table.find(\"td.pvtUnused span.pvtAttr\").length\n            .toBe  4\n            expect table.find(\"td.pvtRows span.pvtAttr\").length\n            .toBe  1\n            expect table.find(\"td.pvtCols span.pvtAttr\").length\n            .toBe  1\n            expect table.find(\"select.pvtRenderer\").val()\n            .toBe  \"Heatmap\"\n            expect table.find(\"select.pvtAggregator\").val()\n            .toBe  \"Sum over Sum\"\n            done()\n\n        it \"renders a table\", (done) ->\n            expect table.find(\"table.pvtTable\").length\n            .toBe  1\n            done()\n\n        describe \"its renderer output\", ->\n            it \"has the correct type and number of cells\", (done) ->\n                expect table.find(\"th.pvtAxisLabel\").length\n                .toBe  2\n                expect table.find(\"th.pvtRowLabel\").length\n                .toBe  2\n                expect table.find(\"th.pvtColLabel\").length\n                .toBe  3\n                expect table.find(\"th.pvtTotalLabel\").length\n                .toBe  2\n                expect table.find(\"td.pvtVal\").length\n                .toBe  6\n                expect table.find(\"td.pvtTotal\").length\n                .toBe  5\n                expect table.find(\"td.pvtGrandTotal\").length\n                .toBe  1\n                done()\n\n            it \"has the correct textual representation\", (done) ->\n                expect table.find(\"table.pvtTable\").text()\n                .toBe [\n                    \"colour\",   \"blue\", \"red\",  \"yellow\",   \"Totals\",\n                    \"gender\",\n                    \"female\",           \"0.26\", \"0.14\",     \"0.20\",\n                    \"male\",     \"0.20\",                     \"0.20\",\n                    \"Totals\",   \"0.20\", \"0.26\", \"0.14\",     \"0.20\"\n                    ].join(\"\")\n                done()\n\n            it \"has a correct spot-checked cell with data value\", (done) ->\n                expect table.find(\"td.col0.row1\").text()\n                .toBe  \"0.20\"\n                expect table.find(\"td.col0.row1\").data(\"value\")\n                .toBe  (12+30)/(103+112)\n                done()\n\n    describe \"with ragged input\",  ->\n        table = $(\"<div>\").pivotUI raggedFixtureData, rows: [\"gender\"], cols: [\"age\"]\n\n        it \"renders a table with the correct textual representation\", ->\n            expect table.find(\"table.pvtTable\").text()\n            .toBe [\n                \"age\",     \"12\",  \"34\",  \"null\",  \"Totals\"\n                \"gender\",\n                \"female\",                 \"1\",    \"1\"\n                \"male\",    \"1\",                   \"1\"\n                \"null\",    \"1\",    \"1\",           \"2\"\n                \"Totals\",  \"2\",    \"1\",   \"1\",    \"4\"\n                ].join(\"\")\n\ndescribe \"$.pivot()\", ->\n\n    describe \"with no rows/cols, default count aggregator, default TableRenderer\",  ->\n        table = $(\"<div>\").pivot fixtureData\n\n        it \"renders a table\", ->\n            expect table.find(\"table.pvtTable\").length\n            .toBe  1\n\n        describe \"its renderer output\", ->\n\n            it \"has the correct textual representation\", ->\n                expect table.find(\"table.pvtTable\").text()\n                .toBe [\"Totals\", \"4\"].join(\"\")\n\n            it \"has a correct grand total with data value\", ->\n                expect table.find(\"td.pvtGrandTotal\").text()\n                .toBe  \"4\"\n                expect table.find(\"td.pvtGrandTotal\").data(\"value\")\n                .toBe  4\n\n    describe \"with rows/cols, sum aggregator, derivedAttributes, filter and sorters\",  ->\n        {sortAs, derivers, aggregators} = $.pivotUtilities\n        table = $(\"<div>\").pivot fixtureData,\n            rows: [\"gender\"], cols: [\"birthyear\"], aggregator: aggregators[\"Sum\"]([\"trialbins\"])\n            filter: (record) -> record.name != \"Nick\"\n            derivedAttributes:\n                birthyear: derivers.dateFormat \"birthday\", \"%y\"\n                trialbins: derivers.bin \"trials\", 10\n            sorters: (attr) ->\n                if attr == \"gender\" then return sortAs([\"male\", \"female\"])\n\n        it \"renders a table with the correct textual representation\", ->\n            expect table.find(\"table.pvtTable\").text()\n            .toBe [\n                \"birthyear\",    \"1982\",     \"1983\",     \"Totals\"\n                \"gender\",\n                \"male\",         \"110.00\",               \"110.00\"\n                \"female\",       \"90.00\",    \"100.00\",   \"190.00\"\n                \"Totals\",       \"200.00\",   \"100.00\",   \"300.00\"\n                ].join(\"\")\n\n    describe \"with rows/cols, fraction-of aggregator\",  ->\n        {aggregators} = $.pivotUtilities\n        table = $(\"<div>\").pivot fixtureData,\n            rows: [\"gender\"]\n            aggregator: aggregators[\"Sum as Fraction of Total\"]([\"trials\"])\n\n        it \"renders a table with the correct textual representation\", ->\n            expect table.find(\"table.pvtTable\").text()\n            .toBe [\n                \"gender\",  \"Totals\"\n                \"female\",  \"47.8%\"\n                \"male\",    \"52.2%\"\n                \"Totals\",  \"100.0%\"\n                ].join(\"\")\n\n    describe \"with rows/cols, custom aggregator, custom renderer with options\",  ->\n        received_PivotData = null\n        received_rendererOptions = null\n\n        table = $(\"<div>\").pivot fixtureData,\n            rows: [\"name\", \"colour\"], cols: [\"trials\", \"successes\"]\n            aggregator: ->\n                count2x: 0\n                push: -> @count2x +=2\n                value: -> @count2x\n                format: (x) -> \"formatted \" + x\n            renderer: (a,b) ->\n                received_PivotData = a\n                received_rendererOptions = b\n                return $(\"<div>\").addClass(b.greeting).text(\"world\")\n            rendererOptions: {greeting:\"hithere\"}\n\n        it \"renders the custom renderer as per options\", ->\n            expect table.find(\"div.hithere\").length\n            .toBe  1\n\n        describe \"its received PivotData object\", ->\n            it \"has a correct grand total value and format for custom aggregator\", ->\n                agg = received_PivotData.getAggregator([],[])\n                val = agg.value()\n                expect(val).toBe 8\n                expect(agg.format(val)).toBe \"formatted 8\"\n\n\n    describe \"with ragged input\",  ->\n        table = $(\"<div>\").pivot raggedFixtureData, rows: [\"gender\"], cols: [\"age\"]\n\n        it \"renders a table with the correct textual representation\", ->\n            expect table.find(\"table.pvtTable\").text()\n            .toBe [\n                \"age\",     \"12\",  \"34\",  \"null\",  \"Totals\"\n                \"gender\",\n                \"female\",                 \"1\",    \"1\"\n                \"male\",    \"1\",                   \"1\"\n                \"null\",    \"1\",    \"1\",           \"2\"\n                \"Totals\",  \"2\",    \"1\",   \"1\",    \"4\"\n                ].join(\"\")\n\ndescribe \"$.pivotUtilities\", ->\n\n    describe \".PivotData()\", ->\n        sumOverSumOpts =\n            aggregator: $.pivotUtilities.aggregators[\"Sum over Sum\"]([\"a\",\"b\"])\n\n        describe \"with no options\", ->\n            aoaInput =  [ [\"a\",\"b\"], [1,2], [3,4] ]\n            pd = new $.pivotUtilities.PivotData aoaInput\n\n            it \"has the correct grand total value\", ->\n                expect pd.getAggregator([],[]).value()\n                .toBe 2\n\n        describe \"with array-of-array input\", ->\n            aoaInput =  [ [\"a\",\"b\"], [1,2], [3,4] ]\n            pd = new $.pivotUtilities.PivotData aoaInput, sumOverSumOpts\n\n            it \"has the correct grand total value\", ->\n                expect pd.getAggregator([],[]).value()\n                .toBe (1+3)/(2+4)\n\n        describe \"with array-of-object input\", ->\n            aosInput =  [ {a:1, b:2}, {a:3, b:4} ]\n            pd = new $.pivotUtilities.PivotData aosInput, sumOverSumOpts\n\n            it \"has the correct grand total value\", ->\n                expect pd.getAggregator([],[]).value()\n                .toBe (1+3)/(2+4)\n\n        describe \"with ragged array-of-object input\", ->\n            raggedAosInput =  [ {a:1}, {b:4}, {a: 3, b: 2} ]\n            pd = new $.pivotUtilities.PivotData raggedAosInput, sumOverSumOpts\n\n            it \"has the correct grand total value\", ->\n                expect pd.getAggregator([],[]).value()\n                .toBe (1+3)/(2+4)\n\n        describe \"with function input\", ->\n            functionInput = (record) ->\n                record a:1, b:2\n                record a:3, b:4\n            pd = new $.pivotUtilities.PivotData functionInput, sumOverSumOpts\n\n            it \"has the correct grand total value\", ->\n                expect pd.getAggregator([],[]).value()\n                .toBe (1+3)/(2+4)\n\n        describe \"with jQuery table element input\", ->\n            tableInput = $ \"\"\"\n                <table>\n                    <thead>\n                        <tr> <th>a</th><th>b</th> </tr>\n                    </thead>\n                    <tbody>\n                        <tr> <td>1</td> <td>2</td> </tr>\n                        <tr> <td>3</td> <td>4</td> </tr>\n                    </tbody>\n                </table>\n                \"\"\"\n            pd = new $.pivotUtilities.PivotData tableInput, sumOverSumOpts\n\n            it \"has the correct grand total value\", ->\n                expect pd.getAggregator([],[]).value()\n                .toBe (1+3)/(2+4)\n\n\n        describe \"with rows/cols\", ->\n            pd = new $.pivotUtilities.PivotData fixtureData,\n                rows: [\"name\", \"colour\"],\n                cols: [\"trials\", \"successes\"]\n\n            it \"has correctly-ordered row keys\", ->\n                expect pd.getRowKeys()\n                .toEqual [ [ 'Carol', 'yellow' ], [ 'Jane', 'red' ], [ 'John', 'blue' ], [ 'Nick', 'blue' ] ]\n\n            it \"has correctly-ordered col keys\", ->\n                expect pd.getColKeys()\n                .toEqual [ [ 95, 25 ], [ 102, 14 ], [ 103, 12 ], [ 112, 30 ] ]\n\n            it \"can be iterated over\", ->\n                numNotNull = 0\n                numNull = 0\n                for r in pd.getRowKeys()\n                    for c in pd.getColKeys()\n                        if pd.getAggregator(r, c).value()?\n                            numNotNull++\n                        else\n                            numNull++\n                expect numNotNull\n                .toBe 4\n                expect numNull\n                .toBe 12\n\n            it \"returns matching records\", ->\n                records = []\n                pd.forEachMatchingRecord gender: \"male\", (x) -> records.push(x.name)\n                expect records\n                .toEqual [\"Nick\", \"John\"]\n\n            it \"has a correct spot-checked aggregator\", ->\n                agg = pd.getAggregator([ 'Carol', 'yellow' ],[ 102, 14 ])\n                val = agg.value()\n                expect(val).toBe 1\n                expect(agg.format(val)).toBe \"1\"\n\n            it \"has a correct grand total aggregator\", ->\n                agg = pd.getAggregator([],[])\n                val = agg.value()\n                expect(val).toBe 4\n                expect(agg.format(val)).toBe \"4\"\n\n    describe \".aggregatorTemplates\", ->\n\n        getVal = (aggregator) ->\n            pd = new $.pivotUtilities.PivotData(fixtureData, {aggregator})\n            return pd.getAggregator([],[]).value()\n        tpl = $.pivotUtilities.aggregatorTemplates\n\n        describe \".count\", ->\n            it \"works\", ->\n                expect getVal(tpl.count()())\n                .toBe 4\n\n        describe \".countUnique\", ->\n            it \"works\", ->\n                expect getVal(tpl.countUnique()(['gender']))\n                .toBe 2\n\n        describe \".listUnique\", ->\n            it \"works\", ->\n                expect getVal(tpl.listUnique()(['gender']))\n                .toBe 'female,male'\n\n        describe \".average\", ->\n            it \"works\", ->\n                expect getVal(tpl.average()(['trials']))\n                .toBe 103\n\n        describe \".sum\", ->\n            it \"works\", ->\n                expect getVal(tpl.sum()(['trials']))\n                .toBe 412\n\n        describe \".min\", ->\n            it \"works\", ->\n                expect getVal(tpl.min()(['trials']))\n                .toBe 95\n\n        describe \".max\", ->\n            it \"works\", ->\n                expect getVal(tpl.max()(['trials']))\n                .toBe 112\n\n        describe \".first\", ->\n            it \"works\", ->\n                expect getVal(tpl.first()(['name']))\n                .toBe 'Carol'\n\n        describe \".last\", ->\n            it \"works\", ->\n                expect getVal(tpl.last()(['name']))\n                .toBe 'Nick'\n\n        describe \".average\", ->\n            it \"works\", ->\n                expect getVal(tpl.average()(['trials']))\n                .toBe 103\n\n        describe \".median\", ->\n            it \"works\", ->\n                expect getVal(tpl.median()(['trials']))\n                .toBe 102.5\n\n        describe \".quantile\", ->\n            it \"works\", ->\n                expect getVal(tpl.quantile(0)(['trials']))\n                .toBe 95\n                expect getVal(tpl.quantile(0.1)(['trials']))\n                .toBe 98.5\n                expect getVal(tpl.quantile(0.25)(['trials']))\n                .toBe 98.5\n                expect getVal(tpl.quantile(1/3)(['trials']))\n                .toBe 102\n                expect getVal(tpl.quantile(1)(['trials']))\n                .toBe 112\n\n        describe \".var\", ->\n            it \"works\", ->\n                expect getVal(tpl.var()(['trials']))\n                .toBe 48.666666666666686\n\n        describe \".stdev\", ->\n            it \"works\", ->\n                expect getVal(tpl.stdev()(['trials']))\n                .toBe 6.976149845485451\n\n        describe \".sumOverSum\", ->\n            it \"works\", ->\n                expect getVal(tpl.sumOverSum()(['successes', 'trials']))\n                .toBe (12+25+30+14)/(95+102+103+112)\n\n    describe \".naturalSort()\", ->\n        naturalSort = $.pivotUtilities.naturalSort\n\n        sortedArr = [\n            null, NaN,\n            -Infinity, '-Infinity', -3, '-3', -2, '-2', -1, '-1',\n            0, '2e-1', 1, '01', '1', 2, '002', '002e0', '02', '2', '2e-0',\n            3, 10, '10', '11', '12', '1e2', '112', Infinity, 'Infinity',\n            '1a', '2a','12a','20a',\n            'A', 'A', 'NaN', 'a', 'a',\n            'a01', 'a012', 'a02', 'a1', 'a2', 'a12', 'a12', 'a21', 'a21',\n            'b', 'c', 'd', 'null'\n        ]\n\n        it \"sorts naturally (null, NaN, numbers & numbery strings, Alphanum for text strings)\", ->\n            expect sortedArr.slice().sort(naturalSort)\n            .toEqual sortedArr\n\n    describe \".sortAs()\", ->\n        sortAs = $.pivotUtilities.sortAs\n\n        it \"sorts with unknown values sorted at the end\", ->\n            expect [5,2,3,4,1].sort sortAs([4,3,2])\n            .toEqual [4,3,2,1,5]\n\n        it \"sorts lowercase after uppercase\", ->\n            expect [\"Ab\",\"aA\",\"aa\",\"ab\"].sort sortAs([\"Ab\",\"Aa\"])\n            .toEqual [\"Ab\",\"ab\",\"aa\",\"aA\"]\n\n    describe \".numberFormat()\", ->\n        numberFormat = $.pivotUtilities.numberFormat\n\n        it \"formats numbers\", ->\n            nf = numberFormat()\n            expect nf 1234567.89123456\n            .toEqual \"1,234,567.89\"\n\n        it \"formats booleans\", ->\n            nf = numberFormat()\n            expect nf true\n            .toEqual \"1.00\"\n\n        it \"formats numbers in strings\", ->\n            nf = numberFormat()\n            expect nf \"1234567.89123456\"\n            .toEqual \"1,234,567.89\"\n\n        it \"doesn't formats strings\", ->\n            nf = numberFormat()\n            expect nf \"hi there\"\n            .toEqual \"\"\n\n        it \"doesn't formats objects\", ->\n            nf = numberFormat()\n            expect nf {a:1}\n            .toEqual \"\"\n\n        it \"formats percentages\", ->\n            nf = numberFormat(scaler: 100, suffix: \"%\")\n            expect nf 0.12345\n            .toEqual \"12.35%\"\n\n        it \"adds separators\", ->\n            nf = numberFormat(thousandsSep: \"a\", decimalSep: \"b\")\n            expect nf 1234567.89123456\n            .toEqual \"1a234a567b89\"\n\n        it \"adds prefixes and suffixes\", ->\n            nf = numberFormat(prefix: \"a\", suffix: \"b\")\n            expect nf 1234567.89123456\n            .toEqual \"a1,234,567.89b\"\n\n        it \"scales and rounds\", ->\n            nf = numberFormat(digitsAfterDecimal: 3, scaler: 1000)\n            expect nf 1234567.89123456\n            .toEqual \"1,234,567,891.235\"\n\n    describe \".derivers\", ->\n        describe \".dateFormat()\", ->\n            df = $.pivotUtilities.derivers.dateFormat \"x\", \"abc % %% %%% %a %y %m %n %d %w %x %H %M %S\", true\n\n            it \"formats date objects\", ->\n                expect df {x: new Date(\"2015-01-02T23:43:11Z\")}\n                .toBe 'abc % %% %%% %a 2015 01 Jan 02 Fri 5 23 43 11'\n\n            it \"formats input parsed by Date.parse()\", ->\n                expect df {x: \"2015-01-02T23:43:11Z\"}\n                .toBe 'abc % %% %%% %a 2015 01 Jan 02 Fri 5 23 43 11'\n\n                expect df {x: \"bla\"}\n                .toBe ''\n\n        describe \".bin()\", ->\n            binner = $.pivotUtilities.derivers.bin \"x\", 10\n\n            it \"bins numbers\", ->\n                expect binner {x: 11}\n                .toBe 10\n\n                expect binner {x: 9}\n                .toBe 0\n\n                expect binner {x: 111}\n                .toBe 110\n\n            it \"bins booleans\", ->\n                expect binner {x: true}\n                .toBe 0\n\n            it \"bins negative numbers\", ->\n                expect binner {x: -12}\n                .toBe -10\n\n            it \"doesn't bin strings\", ->\n                expect binner {x: \"a\"}\n                .toBeNaN()\n\n            it \"doesn't bin objects\", ->\n                expect binner {x: {a:1}}\n                .toBeNaN()\n"]}
\ No newline at end of file
+{"version":3,"file":"pivot_spec.js","sources":["pivot_spec.coffee"],"names":[],"mappings":"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","sourcesContent":["fixtureData = [\n    [\"name\",    \"gender\",   \"colour\",    \"birthday\",     \"trials\",   \"successes\"],\n    [\"Nick\",    \"male\",     \"blue\",      \"1982-11-07\",   103,        12],\n    [\"Jane\",    \"female\",   \"red\",       \"1982-11-08\",   95,         25],\n    [\"John\",    \"male\",     \"blue\",      \"1982-12-08\",   112,        30],\n    [\"Carol\",   \"female\",   \"yellow\",    \"1983-12-08\",   102,        14]\n]\n\nraggedFixtureData = [\n    {name: \"Nick\", \"colour\": \"red\", \"age\": 34}\n    {name: \"Jane\", \"gender\": \"female\"}\n    {name: \"John\", \"gender\": \"male\", \"age\": 12}\n    {name: \"Jim\", \"gender\": null, \"age\": 12}\n]\n\ndescribe \"$.pivotUI()\", ->\n    describe \"with no rows/cols, default count aggregator, default TableRenderer\",  ->\n        table = null\n\n        beforeEach (done) ->\n            table = $(\"<div>\").pivotUI fixtureData, onRefresh: done\n        it \"has all the basic UI elements\", (done) ->\n            expect table.find(\"td.pvtAxisContainer\").length\n            .toBe  3\n            expect table.find(\"td.pvtRendererArea\").length\n            .toBe  1\n            expect table.find(\"td.pvtVals\").length\n            .toBe  1\n            expect table.find(\"select.pvtRenderer\").length\n            .toBe  1\n            expect table.find(\"select.pvtAggregator\").length\n            .toBe  1\n            expect table.find(\"span.pvtAttr\").length\n            .toBe  6\n            done()\n\n        it \"reflects its inputs\", (done) ->\n            expect table.find(\"td.pvtUnused span.pvtAttr\").length\n            .toBe  6\n            expect table.find(\"select.pvtRenderer\").val()\n            .toBe  \"Table\"\n            expect table.find(\"select.pvtAggregator\").val()\n            .toBe  \"Count\"\n            done()\n\n        it \"renders a table\", (done) ->\n            expect table.find(\"table.pvtTable\").length\n            .toBe  1\n            done()\n\n\n        describe \"its renderer output\", ->\n            it \"has the correct type and number of cells\", (done) ->\n                expect table.find(\"th.pvtTotalLabel\").length\n                .toBe  1\n                expect table.find(\"td.pvtGrandTotal\").length\n                .toBe  1\n                done()\n\n            it \"has the correct textual representation\", (done) ->\n                expect table.find(\"table.pvtTable\").text()\n                .toBe [\"Totals\", \"4\"].join(\"\")\n                done()\n\n            it \"has a correct grand total with data value\", (done) ->\n                expect table.find(\"td.pvtGrandTotal\").text()\n                .toBe  \"4\"\n                expect table.find(\"td.pvtGrandTotal\").data(\"value\")\n                .toBe  4\n                done()\n\n    describe \"with rows/cols, sum-over-sum aggregator, Heatmap renderer\",  ->\n        table = null\n\n        beforeEach (done) ->\n            table = $(\"<div>\").pivotUI fixtureData,\n                rows: [\"gender\"], cols: [\"colour\"]\n                aggregatorName: \"Sum over Sum\"\n                vals: [\"successes\", \"trials\"]\n                rendererName: \"Heatmap\"\n                onRefresh: done\n\n        it \"has all the basic UI elements\", (done) ->\n            expect table.find(\"td.pvtAxisContainer\").length\n            .toBe  3\n            expect table.find(\"td.pvtRendererArea\").length\n            .toBe  1\n            expect table.find(\"td.pvtVals\").length\n            .toBe  1\n            expect table.find(\"select.pvtRenderer\").length\n            .toBe  1\n            expect table.find(\"select.pvtAggregator\").length\n            .toBe  1\n            expect table.find(\"span.pvtAttr\").length\n            .toBe  6\n            done()\n\n        it \"reflects its inputs\", (done) ->\n            expect table.find(\"td.pvtUnused span.pvtAttr\").length\n            .toBe  4\n            expect table.find(\"td.pvtRows span.pvtAttr\").length\n            .toBe  1\n            expect table.find(\"td.pvtCols span.pvtAttr\").length\n            .toBe  1\n            expect table.find(\"select.pvtRenderer\").val()\n            .toBe  \"Heatmap\"\n            expect table.find(\"select.pvtAggregator\").val()\n            .toBe  \"Sum over Sum\"\n            done()\n\n        it \"renders a table\", (done) ->\n            expect table.find(\"table.pvtTable\").length\n            .toBe  1\n            done()\n\n        describe \"its renderer output\", ->\n            it \"has the correct type and number of cells\", (done) ->\n                expect table.find(\"th.pvtAxisLabel\").length\n                .toBe  2\n                expect table.find(\"th.pvtRowLabel\").length\n                .toBe  2\n                expect table.find(\"th.pvtColLabel\").length\n                .toBe  3\n                expect table.find(\"th.pvtTotalLabel\").length\n                .toBe  2\n                expect table.find(\"td.pvtVal\").length\n                .toBe  6\n                expect table.find(\"td.pvtTotal\").length\n                .toBe  5\n                expect table.find(\"td.pvtGrandTotal\").length\n                .toBe  1\n                done()\n\n            it \"has the correct textual representation\", (done) ->\n                expect table.find(\"table.pvtTable\").text()\n                .toBe [\n                    \"colour\",   \"blue\", \"red\",  \"yellow\",   \"Totals\",\n                    \"gender\",\n                    \"female\",           \"0.26\", \"0.14\",     \"0.20\",\n                    \"male\",     \"0.20\",                     \"0.20\",\n                    \"Totals\",   \"0.20\", \"0.26\", \"0.14\",     \"0.20\"\n                    ].join(\"\")\n                done()\n\n            it \"has a correct spot-checked cell with data value\", (done) ->\n                expect table.find(\"td.col0.row1\").text()\n                .toBe  \"0.20\"\n                expect table.find(\"td.col0.row1\").data(\"value\")\n                .toBe  (12+30)/(103+112)\n                done()\n\n    describe \"with ragged input\",  ->\n        table = $(\"<div>\").pivotUI raggedFixtureData, rows: [\"gender\"], cols: [\"age\"]\n\n        it \"renders a table with the correct textual representation\", ->\n            expect table.find(\"table.pvtTable\").text()\n            .toBe [\n                \"age\",     \"12\",  \"34\",  \"null\",  \"Totals\"\n                \"gender\",\n                \"female\",                 \"1\",    \"1\"\n                \"male\",    \"1\",                   \"1\"\n                \"null\",    \"1\",    \"1\",           \"2\"\n                \"Totals\",  \"2\",    \"1\",   \"1\",    \"4\"\n                ].join(\"\")\n\ndescribe \"$.pivot()\", ->\n\n    describe \"with no rows/cols, default count aggregator, default TableRenderer\",  ->\n        table = $(\"<div>\").pivot fixtureData\n\n        it \"renders a table\", ->\n            expect table.find(\"table.pvtTable\").length\n            .toBe  1\n\n        describe \"its renderer output\", ->\n\n            it \"has the correct textual representation\", ->\n                expect table.find(\"table.pvtTable\").text()\n                .toBe [\"Totals\", \"4\"].join(\"\")\n\n            it \"has a correct grand total with data value\", ->\n                expect table.find(\"td.pvtGrandTotal\").text()\n                .toBe  \"4\"\n                expect table.find(\"td.pvtGrandTotal\").data(\"value\")\n                .toBe  4\n\n    describe \"with rows/cols, sum aggregator, derivedAttributes, filter and sorters\",  ->\n        {sortAs, derivers, aggregators} = $.pivotUtilities\n        table = $(\"<div>\").pivot fixtureData,\n            rows: [\"gender\"], cols: [\"birthyear\"], aggregator: aggregators[\"Sum\"]([\"trialbins\"])\n            filter: (record) -> record.name != \"Nick\"\n            derivedAttributes:\n                birthyear: derivers.dateFormat \"birthday\", \"%y\"\n                trialbins: derivers.bin \"trials\", 10\n            sorters: (attr) ->\n                if attr == \"gender\" then return sortAs([\"male\", \"female\"])\n\n        it \"renders a table with the correct textual representation\", ->\n            expect table.find(\"table.pvtTable\").text()\n            .toBe [\n                \"birthyear\",    \"1982\",     \"1983\",     \"Totals\"\n                \"gender\",\n                \"male\",         \"110.00\",               \"110.00\"\n                \"female\",       \"90.00\",    \"100.00\",   \"190.00\"\n                \"Totals\",       \"200.00\",   \"100.00\",   \"300.00\"\n                ].join(\"\")\n\n    describe \"with rows/cols, fraction-of aggregator\",  ->\n        {aggregators} = $.pivotUtilities\n        table = $(\"<div>\").pivot fixtureData,\n            rows: [\"gender\"]\n            aggregator: aggregators[\"Sum as Fraction of Total\"]([\"trials\"])\n\n        it \"renders a table with the correct textual representation\", ->\n            expect table.find(\"table.pvtTable\").text()\n            .toBe [\n                \"gender\",  \"Totals\"\n                \"female\",  \"47.8%\"\n                \"male\",    \"52.2%\"\n                \"Totals\",  \"100.0%\"\n                ].join(\"\")\n\n    describe \"with rows/cols, custom aggregator, custom renderer with options\",  ->\n        received_PivotData = null\n        received_rendererOptions = null\n\n        table = $(\"<div>\").pivot fixtureData,\n            rows: [\"name\", \"colour\"], cols: [\"trials\", \"successes\"]\n            aggregator: ->\n                count2x: 0\n                push: -> @count2x +=2\n                value: -> @count2x\n                format: (x) -> \"formatted \" + x\n            renderer: (a,b) ->\n                received_PivotData = a\n                received_rendererOptions = b\n                return $(\"<div>\").addClass(b.greeting).text(\"world\")\n            rendererOptions: {greeting:\"hithere\"}\n\n        it \"renders the custom renderer as per options\", ->\n            expect table.find(\"div.hithere\").length\n            .toBe  1\n\n        describe \"its received PivotData object\", ->\n            it \"has a correct grand total value and format for custom aggregator\", ->\n                agg = received_PivotData.getAggregator([],[])\n                val = agg.value()\n                expect(val).toBe 8\n                expect(agg.format(val)).toBe \"formatted 8\"\n\n\n    describe \"with ragged input\",  ->\n        table = $(\"<div>\").pivot raggedFixtureData, rows: [\"gender\"], cols: [\"age\"]\n\n        it \"renders a table with the correct textual representation\", ->\n            expect table.find(\"table.pvtTable\").text()\n            .toBe [\n                \"age\",     \"12\",  \"34\",  \"null\",  \"Totals\"\n                \"gender\",\n                \"female\",                 \"1\",    \"1\"\n                \"male\",    \"1\",                   \"1\"\n                \"null\",    \"1\",    \"1\",           \"2\"\n                \"Totals\",  \"2\",    \"1\",   \"1\",    \"4\"\n                ].join(\"\")\n\ndescribe \"$.pivotUtilities\", ->\n\n    describe \".PivotData()\", ->\n        sumOverSumOpts =\n            aggregator: $.pivotUtilities.aggregators[\"Sum over Sum\"]([\"a\",\"b\"])\n\n        describe \"with no options\", ->\n            aoaInput =  [ [\"a\",\"b\"], [1,2], [3,4] ]\n            pd = new $.pivotUtilities.PivotData aoaInput\n\n            it \"has the correct grand total value\", ->\n                expect pd.getAggregator([],[]).value()\n                .toBe 2\n\n        describe \"with array-of-array input\", ->\n            aoaInput =  [ [\"a\",\"b\"], [1,2], [3,4] ]\n            pd = new $.pivotUtilities.PivotData aoaInput, sumOverSumOpts\n\n            it \"has the correct grand total value\", ->\n                expect pd.getAggregator([],[]).value()\n                .toBe (1+3)/(2+4)\n\n        describe \"with array-of-object input\", ->\n            aosInput =  [ {a:1, b:2}, {a:3, b:4} ]\n            pd = new $.pivotUtilities.PivotData aosInput, sumOverSumOpts\n\n            it \"has the correct grand total value\", ->\n                expect pd.getAggregator([],[]).value()\n                .toBe (1+3)/(2+4)\n\n        describe \"with ragged array-of-object input\", ->\n            raggedAosInput =  [ {a:1}, {b:4}, {a: 3, b: 2} ]\n            pd = new $.pivotUtilities.PivotData raggedAosInput, sumOverSumOpts\n\n            it \"has the correct grand total value\", ->\n                expect pd.getAggregator([],[]).value()\n                .toBe (1+3)/(2+4)\n\n        describe \"with function input\", ->\n            functionInput = (record) ->\n                record a:1, b:2\n                record a:3, b:4\n            pd = new $.pivotUtilities.PivotData functionInput, sumOverSumOpts\n\n            it \"has the correct grand total value\", ->\n                expect pd.getAggregator([],[]).value()\n                .toBe (1+3)/(2+4)\n\n        describe \"with jQuery table element input\", ->\n            tableInput = $ \"\"\"\n                <table>\n                    <thead>\n                        <tr> <th>a</th><th>b</th> </tr>\n                    </thead>\n                    <tbody>\n                        <tr> <td>1</td> <td>2</td> </tr>\n                        <tr> <td>3</td> <td>4</td> </tr>\n                    </tbody>\n                </table>\n                \"\"\"\n            pd = new $.pivotUtilities.PivotData tableInput, sumOverSumOpts\n\n            it \"has the correct grand total value\", ->\n                expect pd.getAggregator([],[]).value()\n                .toBe (1+3)/(2+4)\n\n        describe \"with a0-a00 input\", ->\n            aoaInput =  [\n                {key: 'a0', ym: '2020-01'},\n                {key: 'a0', ym: '2020-02'},\n                {key: 'a00', ym: '2020-01'},\n                {key: 'a00', ym: '2020-02'}\n            ]\n            pd = new $.pivotUtilities.PivotData aoaInput, rows: [\"key\", \"ym\"], cols: []\n\n            it \"has correctly-ordered row keys\", ->\n                expect pd.getRowKeys()\n                .toEqual [[\"a0\",\"2020-01\"],[\"a0\",\"2020-02\"],[\"a00\",\"2020-01\"],[\"a00\",\"2020-02\"]]\n\n        describe \"with rows/cols\", ->\n            pd = new $.pivotUtilities.PivotData fixtureData,\n                rows: [\"name\", \"colour\"],\n                cols: [\"trials\", \"successes\"]\n\n            it \"has correctly-ordered row keys\", ->\n                expect pd.getRowKeys()\n                .toEqual [ [ 'Carol', 'yellow' ], [ 'Jane', 'red' ], [ 'John', 'blue' ], [ 'Nick', 'blue' ] ]\n\n            it \"has correctly-ordered col keys\", ->\n                expect pd.getColKeys()\n                .toEqual [ [ 95, 25 ], [ 102, 14 ], [ 103, 12 ], [ 112, 30 ] ]\n\n            it \"can be iterated over\", ->\n                numNotNull = 0\n                numNull = 0\n                for r in pd.getRowKeys()\n                    for c in pd.getColKeys()\n                        if pd.getAggregator(r, c).value()?\n                            numNotNull++\n                        else\n                            numNull++\n                expect numNotNull\n                .toBe 4\n                expect numNull\n                .toBe 12\n\n            it \"returns matching records\", ->\n                records = []\n                pd.forEachMatchingRecord gender: \"male\", (x) -> records.push(x.name)\n                expect records\n                .toEqual [\"Nick\", \"John\"]\n\n            it \"has a correct spot-checked aggregator\", ->\n                agg = pd.getAggregator([ 'Carol', 'yellow' ],[ 102, 14 ])\n                val = agg.value()\n                expect(val).toBe 1\n                expect(agg.format(val)).toBe \"1\"\n\n            it \"has a correct grand total aggregator\", ->\n                agg = pd.getAggregator([],[])\n                val = agg.value()\n                expect(val).toBe 4\n                expect(agg.format(val)).toBe \"4\"\n\n    describe \".aggregatorTemplates\", ->\n\n        getVal = (aggregator) ->\n            pd = new $.pivotUtilities.PivotData(fixtureData, {aggregator})\n            return pd.getAggregator([],[]).value()\n        tpl = $.pivotUtilities.aggregatorTemplates\n\n        describe \".count\", ->\n            it \"works\", ->\n                expect getVal(tpl.count()())\n                .toBe 4\n\n        describe \".countUnique\", ->\n            it \"works\", ->\n                expect getVal(tpl.countUnique()(['gender']))\n                .toBe 2\n\n        describe \".listUnique\", ->\n            it \"works\", ->\n                expect getVal(tpl.listUnique()(['gender']))\n                .toBe 'female,male'\n\n        describe \".average\", ->\n            it \"works\", ->\n                expect getVal(tpl.average()(['trials']))\n                .toBe 103\n\n        describe \".sum\", ->\n            it \"works\", ->\n                expect getVal(tpl.sum()(['trials']))\n                .toBe 412\n\n        describe \".min\", ->\n            it \"works\", ->\n                expect getVal(tpl.min()(['trials']))\n                .toBe 95\n\n        describe \".max\", ->\n            it \"works\", ->\n                expect getVal(tpl.max()(['trials']))\n                .toBe 112\n\n        describe \".first\", ->\n            it \"works\", ->\n                expect getVal(tpl.first()(['name']))\n                .toBe 'Carol'\n\n        describe \".last\", ->\n            it \"works\", ->\n                expect getVal(tpl.last()(['name']))\n                .toBe 'Nick'\n\n        describe \".average\", ->\n            it \"works\", ->\n                expect getVal(tpl.average()(['trials']))\n                .toBe 103\n\n        describe \".median\", ->\n            it \"works\", ->\n                expect getVal(tpl.median()(['trials']))\n                .toBe 102.5\n\n        describe \".quantile\", ->\n            it \"works\", ->\n                expect getVal(tpl.quantile(0)(['trials']))\n                .toBe 95\n                expect getVal(tpl.quantile(0.1)(['trials']))\n                .toBe 98.5\n                expect getVal(tpl.quantile(0.25)(['trials']))\n                .toBe 98.5\n                expect getVal(tpl.quantile(1/3)(['trials']))\n                .toBe 102\n                expect getVal(tpl.quantile(1)(['trials']))\n                .toBe 112\n\n        describe \".var\", ->\n            it \"works\", ->\n                expect getVal(tpl.var()(['trials']))\n                .toBe 48.666666666666686\n\n        describe \".stdev\", ->\n            it \"works\", ->\n                expect getVal(tpl.stdev()(['trials']))\n                .toBe 6.976149845485451\n\n        describe \".sumOverSum\", ->\n            it \"works\", ->\n                expect getVal(tpl.sumOverSum()(['successes', 'trials']))\n                .toBe (12+25+30+14)/(95+102+103+112)\n\n    describe \".naturalSort()\", ->\n        naturalSort = $.pivotUtilities.naturalSort\n\n        sortedArr = [\n            null, NaN,\n            -Infinity, '-Infinity', -3, '-3', -2, '-2', -1, '-1',\n            0, '2e-1', 1, '01', '1', 2, '002', '002e0', '02', '2', '2e-0',\n            3, 10, '10', '11', '12', '1e2', '112', Infinity, 'Infinity',\n            '1a', '2a','12a','20a',\n            'A', 'A', 'NaN', 'a', 'a',\n            'a01', 'a012', 'a02', 'a1', 'a2', 'a12', 'a12', 'a21', 'a21',\n            'b', 'c', 'd', 'null'\n        ]\n\n        it \"sorts naturally (null, NaN, numbers & numbery strings, Alphanum for text strings)\", ->\n            expect sortedArr.slice().sort(naturalSort)\n            .toEqual sortedArr\n\n    describe \".sortAs()\", ->\n        sortAs = $.pivotUtilities.sortAs\n\n        it \"sorts with unknown values sorted at the end\", ->\n            expect [5,2,3,4,1].sort sortAs([4,3,2])\n            .toEqual [4,3,2,1,5]\n\n        it \"sorts lowercase after uppercase\", ->\n            expect [\"Ab\",\"aA\",\"aa\",\"ab\"].sort sortAs([\"Ab\",\"Aa\"])\n            .toEqual [\"Ab\",\"ab\",\"aa\",\"aA\"]\n\n    describe \".numberFormat()\", ->\n        numberFormat = $.pivotUtilities.numberFormat\n\n        it \"formats numbers\", ->\n            nf = numberFormat()\n            expect nf 1234567.89123456\n            .toEqual \"1,234,567.89\"\n\n        it \"formats booleans\", ->\n            nf = numberFormat()\n            expect nf true\n            .toEqual \"1.00\"\n\n        it \"formats numbers in strings\", ->\n            nf = numberFormat()\n            expect nf \"1234567.89123456\"\n            .toEqual \"1,234,567.89\"\n\n        it \"doesn't formats strings\", ->\n            nf = numberFormat()\n            expect nf \"hi there\"\n            .toEqual \"\"\n\n        it \"doesn't formats objects\", ->\n            nf = numberFormat()\n            expect nf {a:1}\n            .toEqual \"\"\n\n        it \"formats percentages\", ->\n            nf = numberFormat(scaler: 100, suffix: \"%\")\n            expect nf 0.12345\n            .toEqual \"12.35%\"\n\n        it \"adds separators\", ->\n            nf = numberFormat(thousandsSep: \"a\", decimalSep: \"b\")\n            expect nf 1234567.89123456\n            .toEqual \"1a234a567b89\"\n\n        it \"adds prefixes and suffixes\", ->\n            nf = numberFormat(prefix: \"a\", suffix: \"b\")\n            expect nf 1234567.89123456\n            .toEqual \"a1,234,567.89b\"\n\n        it \"scales and rounds\", ->\n            nf = numberFormat(digitsAfterDecimal: 3, scaler: 1000)\n            expect nf 1234567.89123456\n            .toEqual \"1,234,567,891.235\"\n\n    describe \".derivers\", ->\n        describe \".dateFormat()\", ->\n            df = $.pivotUtilities.derivers.dateFormat \"x\", \"abc % %% %%% %a %y %m %n %d %w %x %H %M %S\", true\n\n            it \"formats date objects\", ->\n                expect df {x: new Date(\"2015-01-02T23:43:11Z\")}\n                .toBe 'abc % %% %%% %a 2015 01 Jan 02 Fri 5 23 43 11'\n\n            it \"formats input parsed by Date.parse()\", ->\n                expect df {x: \"2015-01-02T23:43:11Z\"}\n                .toBe 'abc % %% %%% %a 2015 01 Jan 02 Fri 5 23 43 11'\n\n                expect df {x: \"bla\"}\n                .toBe ''\n\n        describe \".bin()\", ->\n            binner = $.pivotUtilities.derivers.bin \"x\", 10\n\n            it \"bins numbers\", ->\n                expect binner {x: 11}\n                .toBe 10\n\n                expect binner {x: 9}\n                .toBe 0\n\n                expect binner {x: 111}\n                .toBe 110\n\n            it \"bins booleans\", ->\n                expect binner {x: true}\n                .toBe 0\n\n            it \"bins negative numbers\", ->\n                expect binner {x: -12}\n                .toBe -10\n\n            it \"doesn't bin strings\", ->\n                expect binner {x: \"a\"}\n                .toBeNaN()\n\n            it \"doesn't bin objects\", ->\n                expect binner {x: {a:1}}\n                .toBeNaN()\n"]}
\ No newline at end of file
diff --git a/dist/pivot_spec.min.js b/dist/pivot_spec.min.js
index d2eaebb4..56e4931a 100644
--- a/dist/pivot_spec.min.js
+++ b/dist/pivot_spec.min.js
@@ -1,2 +1,2 @@
-(function(){var t,e;t=[["name","gender","colour","birthday","trials","successes"],["Nick","male","blue","1982-11-07",103,12],["Jane","female","red","1982-11-08",95,25],["John","male","blue","1982-12-08",112,30],["Carol","female","yellow","1983-12-08",102,14]],e=[{name:"Nick",colour:"red",age:34},{name:"Jane",gender:"female"},{name:"John",gender:"male",age:12},{name:"Jim",gender:null,age:12}],describe("$.pivotUI()",function(){return describe("with no rows/cols, default count aggregator, default TableRenderer",function(){var e;return e=null,beforeEach(function(r){return e=$("<div>").pivotUI(t,{onRefresh:r})}),it("has all the basic UI elements",function(t){return expect(e.find("td.pvtAxisContainer").length).toBe(3),expect(e.find("td.pvtRendererArea").length).toBe(1),expect(e.find("td.pvtVals").length).toBe(1),expect(e.find("select.pvtRenderer").length).toBe(1),expect(e.find("select.pvtAggregator").length).toBe(1),expect(e.find("span.pvtAttr").length).toBe(6),t()}),it("reflects its inputs",function(t){return expect(e.find("td.pvtUnused span.pvtAttr").length).toBe(6),expect(e.find("select.pvtRenderer").val()).toBe("Table"),expect(e.find("select.pvtAggregator").val()).toBe("Count"),t()}),it("renders a table",function(t){return expect(e.find("table.pvtTable").length).toBe(1),t()}),describe("its renderer output",function(){return it("has the correct type and number of cells",function(t){return expect(e.find("th.pvtTotalLabel").length).toBe(1),expect(e.find("td.pvtGrandTotal").length).toBe(1),t()}),it("has the correct textual representation",function(t){return expect(e.find("table.pvtTable").text()).toBe(["Totals","4"].join("")),t()}),it("has a correct grand total with data value",function(t){return expect(e.find("td.pvtGrandTotal").text()).toBe("4"),expect(e.find("td.pvtGrandTotal").data("value")).toBe(4),t()})})}),describe("with rows/cols, sum-over-sum aggregator, Heatmap renderer",function(){var e;return e=null,beforeEach(function(r){return e=$("<div>").pivotUI(t,{rows:["gender"],cols:["colour"],aggregatorName:"Sum over Sum",vals:["successes","trials"],rendererName:"Heatmap",onRefresh:r})}),it("has all the basic UI elements",function(t){return expect(e.find("td.pvtAxisContainer").length).toBe(3),expect(e.find("td.pvtRendererArea").length).toBe(1),expect(e.find("td.pvtVals").length).toBe(1),expect(e.find("select.pvtRenderer").length).toBe(1),expect(e.find("select.pvtAggregator").length).toBe(1),expect(e.find("span.pvtAttr").length).toBe(6),t()}),it("reflects its inputs",function(t){return expect(e.find("td.pvtUnused span.pvtAttr").length).toBe(4),expect(e.find("td.pvtRows span.pvtAttr").length).toBe(1),expect(e.find("td.pvtCols span.pvtAttr").length).toBe(1),expect(e.find("select.pvtRenderer").val()).toBe("Heatmap"),expect(e.find("select.pvtAggregator").val()).toBe("Sum over Sum"),t()}),it("renders a table",function(t){return expect(e.find("table.pvtTable").length).toBe(1),t()}),describe("its renderer output",function(){return it("has the correct type and number of cells",function(t){return expect(e.find("th.pvtAxisLabel").length).toBe(2),expect(e.find("th.pvtRowLabel").length).toBe(2),expect(e.find("th.pvtColLabel").length).toBe(3),expect(e.find("th.pvtTotalLabel").length).toBe(2),expect(e.find("td.pvtVal").length).toBe(6),expect(e.find("td.pvtTotal").length).toBe(5),expect(e.find("td.pvtGrandTotal").length).toBe(1),t()}),it("has the correct textual representation",function(t){return expect(e.find("table.pvtTable").text()).toBe(["colour","blue","red","yellow","Totals","gender","female","0.26","0.14","0.20","male","0.20","0.20","Totals","0.20","0.26","0.14","0.20"].join("")),t()}),it("has a correct spot-checked cell with data value",function(t){return expect(e.find("td.col0.row1").text()).toBe("0.20"),expect(e.find("td.col0.row1").data("value")).toBe(42/215),t()})})}),describe("with ragged input",function(){var t;return t=$("<div>").pivotUI(e,{rows:["gender"],cols:["age"]}),it("renders a table with the correct textual representation",function(){return expect(t.find("table.pvtTable").text()).toBe(["age","12","34","null","Totals","gender","female","1","1","male","1","1","null","1","1","2","Totals","2","1","1","4"].join(""))})})}),describe("$.pivot()",function(){return describe("with no rows/cols, default count aggregator, default TableRenderer",function(){var e;return e=$("<div>").pivot(t),it("renders a table",function(){return expect(e.find("table.pvtTable").length).toBe(1)}),describe("its renderer output",function(){return it("has the correct textual representation",function(){return expect(e.find("table.pvtTable").text()).toBe(["Totals","4"].join(""))}),it("has a correct grand total with data value",function(){return expect(e.find("td.pvtGrandTotal").text()).toBe("4"),expect(e.find("td.pvtGrandTotal").data("value")).toBe(4)})})}),describe("with rows/cols, sum aggregator, derivedAttributes, filter and sorters",function(){var e,r,n,a,o;return n=$.pivotUtilities,a=n.sortAs,r=n.derivers,e=n.aggregators,o=$("<div>").pivot(t,{rows:["gender"],cols:["birthyear"],aggregator:e.Sum(["trialbins"]),filter:function(t){return"Nick"!==t.name},derivedAttributes:{birthyear:r.dateFormat("birthday","%y"),trialbins:r.bin("trials",10)},sorters:function(t){if("gender"===t)return a(["male","female"])}}),it("renders a table with the correct textual representation",function(){return expect(o.find("table.pvtTable").text()).toBe(["birthyear","1982","1983","Totals","gender","male","110.00","110.00","female","90.00","100.00","190.00","Totals","200.00","100.00","300.00"].join(""))})}),describe("with rows/cols, fraction-of aggregator",function(){var e,r;return e=$.pivotUtilities.aggregators,r=$("<div>").pivot(t,{rows:["gender"],aggregator:e["Sum as Fraction of Total"](["trials"])}),it("renders a table with the correct textual representation",function(){return expect(r.find("table.pvtTable").text()).toBe(["gender","Totals","female","47.8%","male","52.2%","Totals","100.0%"].join(""))})}),describe("with rows/cols, custom aggregator, custom renderer with options",function(){var e,r,n;return e=null,r=null,n=$("<div>").pivot(t,{rows:["name","colour"],cols:["trials","successes"],aggregator:function(){return{count2x:0,push:function(){return this.count2x+=2},value:function(){return this.count2x},format:function(t){return"formatted "+t}}},renderer:function(t,n){return e=t,r=n,$("<div>").addClass(n.greeting).text("world")},rendererOptions:{greeting:"hithere"}}),it("renders the custom renderer as per options",function(){return expect(n.find("div.hithere").length).toBe(1)}),describe("its received PivotData object",function(){return it("has a correct grand total value and format for custom aggregator",function(){var t,r;return t=e.getAggregator([],[]),r=t.value(),expect(r).toBe(8),expect(t.format(r)).toBe("formatted 8")})})}),describe("with ragged input",function(){var t;return t=$("<div>").pivot(e,{rows:["gender"],cols:["age"]}),it("renders a table with the correct textual representation",function(){return expect(t.find("table.pvtTable").text()).toBe(["age","12","34","null","Totals","gender","female","1","1","male","1","1","null","1","1","2","Totals","2","1","1","4"].join(""))})})}),describe("$.pivotUtilities",function(){return describe(".PivotData()",function(){var e;return e={aggregator:$.pivotUtilities.aggregators["Sum over Sum"](["a","b"])},describe("with no options",function(){var t,e;return t=[["a","b"],[1,2],[3,4]],e=new $.pivotUtilities.PivotData(t),it("has the correct grand total value",function(){return expect(e.getAggregator([],[]).value()).toBe(2)})}),describe("with array-of-array input",function(){var t,r;return t=[["a","b"],[1,2],[3,4]],r=new $.pivotUtilities.PivotData(t,e),it("has the correct grand total value",function(){return expect(r.getAggregator([],[]).value()).toBe(4/6)})}),describe("with array-of-object input",function(){var t,r;return t=[{a:1,b:2},{a:3,b:4}],r=new $.pivotUtilities.PivotData(t,e),it("has the correct grand total value",function(){return expect(r.getAggregator([],[]).value()).toBe(4/6)})}),describe("with ragged array-of-object input",function(){var t,r;return r=[{a:1},{b:4},{a:3,b:2}],t=new $.pivotUtilities.PivotData(r,e),it("has the correct grand total value",function(){return expect(t.getAggregator([],[]).value()).toBe(4/6)})}),describe("with function input",function(){var t,r;return t=function(t){return t({a:1,b:2}),t({a:3,b:4})},r=new $.pivotUtilities.PivotData(t,e),it("has the correct grand total value",function(){return expect(r.getAggregator([],[]).value()).toBe(4/6)})}),describe("with jQuery table element input",function(){var t,r;return r=$("<table>\n    <thead>\n        <tr> <th>a</th><th>b</th> </tr>\n    </thead>\n    <tbody>\n        <tr> <td>1</td> <td>2</td> </tr>\n        <tr> <td>3</td> <td>4</td> </tr>\n    </tbody>\n</table>"),t=new $.pivotUtilities.PivotData(r,e),it("has the correct grand total value",function(){return expect(t.getAggregator([],[]).value()).toBe(4/6)})}),describe("with rows/cols",function(){var e;return e=new $.pivotUtilities.PivotData(t,{rows:["name","colour"],cols:["trials","successes"]}),it("has correctly-ordered row keys",function(){return expect(e.getRowKeys()).toEqual([["Carol","yellow"],["Jane","red"],["John","blue"],["Nick","blue"]])}),it("has correctly-ordered col keys",function(){return expect(e.getColKeys()).toEqual([[95,25],[102,14],[103,12],[112,30]])}),it("can be iterated over",function(){var t,r,n,a,o,i,c,u,s,l;for(i=0,c=0,s=e.getRowKeys(),r=0,a=s.length;r<a;r++)for(u=s[r],l=e.getColKeys(),n=0,o=l.length;n<o;n++)t=l[n],null!=e.getAggregator(u,t).value()?i++:c++;return expect(i).toBe(4),expect(c).toBe(12)}),it("returns matching records",function(){var t;return t=[],e.forEachMatchingRecord({gender:"male"},function(e){return t.push(e.name)}),expect(t).toEqual(["Nick","John"])}),it("has a correct spot-checked aggregator",function(){var t,r;return t=e.getAggregator(["Carol","yellow"],[102,14]),r=t.value(),expect(r).toBe(1),expect(t.format(r)).toBe("1")}),it("has a correct grand total aggregator",function(){var t,r;return t=e.getAggregator([],[]),r=t.value(),expect(r).toBe(4),expect(t.format(r)).toBe("4")})})}),describe(".aggregatorTemplates",function(){var e,r;return e=function(e){var r;return r=new $.pivotUtilities.PivotData(t,{aggregator:e}),r.getAggregator([],[]).value()},r=$.pivotUtilities.aggregatorTemplates,describe(".count",function(){return it("works",function(){return expect(e(r.count()())).toBe(4)})}),describe(".countUnique",function(){return it("works",function(){return expect(e(r.countUnique()(["gender"]))).toBe(2)})}),describe(".listUnique",function(){return it("works",function(){return expect(e(r.listUnique()(["gender"]))).toBe("female,male")})}),describe(".average",function(){return it("works",function(){return expect(e(r.average()(["trials"]))).toBe(103)})}),describe(".sum",function(){return it("works",function(){return expect(e(r.sum()(["trials"]))).toBe(412)})}),describe(".min",function(){return it("works",function(){return expect(e(r.min()(["trials"]))).toBe(95)})}),describe(".max",function(){return it("works",function(){return expect(e(r.max()(["trials"]))).toBe(112)})}),describe(".first",function(){return it("works",function(){return expect(e(r.first()(["name"]))).toBe("Carol")})}),describe(".last",function(){return it("works",function(){return expect(e(r.last()(["name"]))).toBe("Nick")})}),describe(".average",function(){return it("works",function(){return expect(e(r.average()(["trials"]))).toBe(103)})}),describe(".median",function(){return it("works",function(){return expect(e(r.median()(["trials"]))).toBe(102.5)})}),describe(".quantile",function(){return it("works",function(){return expect(e(r.quantile(0)(["trials"]))).toBe(95),expect(e(r.quantile(.1)(["trials"]))).toBe(98.5),expect(e(r.quantile(.25)(["trials"]))).toBe(98.5),expect(e(r.quantile(1/3)(["trials"]))).toBe(102),expect(e(r.quantile(1)(["trials"]))).toBe(112)})}),describe(".var",function(){return it("works",function(){return expect(e(r["var"]()(["trials"]))).toBe(48.666666666666686)})}),describe(".stdev",function(){return it("works",function(){return expect(e(r.stdev()(["trials"]))).toBe(6.976149845485451)})}),describe(".sumOverSum",function(){return it("works",function(){return expect(e(r.sumOverSum()(["successes","trials"]))).toBe(81/412)})})}),describe(".naturalSort()",function(){var t,e;return t=$.pivotUtilities.naturalSort,e=[null,NaN,-Infinity,"-Infinity",-3,"-3",-2,"-2",-1,"-1",0,"2e-1",1,"01","1",2,"002","002e0","02","2","2e-0",3,10,"10","11","12","1e2","112",Infinity,"Infinity","1a","2a","12a","20a","A","A","NaN","a","a","a01","a012","a02","a1","a2","a12","a12","a21","a21","b","c","d","null"],it("sorts naturally (null, NaN, numbers & numbery strings, Alphanum for text strings)",function(){return expect(e.slice().sort(t)).toEqual(e)})}),describe(".sortAs()",function(){var t;return t=$.pivotUtilities.sortAs,it("sorts with unknown values sorted at the end",function(){return expect([5,2,3,4,1].sort(t([4,3,2]))).toEqual([4,3,2,1,5])}),it("sorts lowercase after uppercase",function(){return expect(["Ab","aA","aa","ab"].sort(t(["Ab","Aa"]))).toEqual(["Ab","ab","aa","aA"])})}),describe(".numberFormat()",function(){var t;return t=$.pivotUtilities.numberFormat,it("formats numbers",function(){var e;return e=t(),expect(e(1234567.89123456)).toEqual("1,234,567.89")}),it("formats booleans",function(){var e;return e=t(),expect(e(!0)).toEqual("1.00")}),it("formats numbers in strings",function(){var e;return e=t(),expect(e("1234567.89123456")).toEqual("1,234,567.89")}),it("doesn't formats strings",function(){var e;return e=t(),expect(e("hi there")).toEqual("")}),it("doesn't formats objects",function(){var e;return e=t(),expect(e({a:1})).toEqual("")}),it("formats percentages",function(){var e;return e=t({scaler:100,suffix:"%"}),expect(e(.12345)).toEqual("12.35%")}),it("adds separators",function(){var e;return e=t({thousandsSep:"a",decimalSep:"b"}),expect(e(1234567.89123456)).toEqual("1a234a567b89")}),it("adds prefixes and suffixes",function(){var e;return e=t({prefix:"a",suffix:"b"}),expect(e(1234567.89123456)).toEqual("a1,234,567.89b")}),it("scales and rounds",function(){var e;return e=t({digitsAfterDecimal:3,scaler:1e3}),expect(e(1234567.89123456)).toEqual("1,234,567,891.235")})}),describe(".derivers",function(){return describe(".dateFormat()",function(){var t;return t=$.pivotUtilities.derivers.dateFormat("x","abc % %% %%% %a %y %m %n %d %w %x %H %M %S",!0),it("formats date objects",function(){return expect(t({x:new Date("2015-01-02T23:43:11Z")})).toBe("abc % %% %%% %a 2015 01 Jan 02 Fri 5 23 43 11")}),it("formats input parsed by Date.parse()",function(){return expect(t({x:"2015-01-02T23:43:11Z"})).toBe("abc % %% %%% %a 2015 01 Jan 02 Fri 5 23 43 11"),expect(t({x:"bla"})).toBe("")})}),describe(".bin()",function(){var t;return t=$.pivotUtilities.derivers.bin("x",10),it("bins numbers",function(){return expect(t({x:11})).toBe(10),expect(t({x:9})).toBe(0),expect(t({x:111})).toBe(110)}),it("bins booleans",function(){return expect(t({x:!0})).toBe(0)}),it("bins negative numbers",function(){return expect(t({x:-12})).toBe(-10)}),it("doesn't bin strings",function(){return expect(t({x:"a"})).toBeNaN()}),it("doesn't bin objects",function(){return expect(t({x:{a:1}})).toBeNaN()})})})})}).call(this);
+(function(){var t,e;t=[["name","gender","colour","birthday","trials","successes"],["Nick","male","blue","1982-11-07",103,12],["Jane","female","red","1982-11-08",95,25],["John","male","blue","1982-12-08",112,30],["Carol","female","yellow","1983-12-08",102,14]],e=[{name:"Nick",colour:"red",age:34},{name:"Jane",gender:"female"},{name:"John",gender:"male",age:12},{name:"Jim",gender:null,age:12}],describe("$.pivotUI()",function(){return describe("with no rows/cols, default count aggregator, default TableRenderer",function(){var e;return e=null,beforeEach(function(r){return e=$("<div>").pivotUI(t,{onRefresh:r})}),it("has all the basic UI elements",function(t){return expect(e.find("td.pvtAxisContainer").length).toBe(3),expect(e.find("td.pvtRendererArea").length).toBe(1),expect(e.find("td.pvtVals").length).toBe(1),expect(e.find("select.pvtRenderer").length).toBe(1),expect(e.find("select.pvtAggregator").length).toBe(1),expect(e.find("span.pvtAttr").length).toBe(6),t()}),it("reflects its inputs",function(t){return expect(e.find("td.pvtUnused span.pvtAttr").length).toBe(6),expect(e.find("select.pvtRenderer").val()).toBe("Table"),expect(e.find("select.pvtAggregator").val()).toBe("Count"),t()}),it("renders a table",function(t){return expect(e.find("table.pvtTable").length).toBe(1),t()}),describe("its renderer output",function(){return it("has the correct type and number of cells",function(t){return expect(e.find("th.pvtTotalLabel").length).toBe(1),expect(e.find("td.pvtGrandTotal").length).toBe(1),t()}),it("has the correct textual representation",function(t){return expect(e.find("table.pvtTable").text()).toBe(["Totals","4"].join("")),t()}),it("has a correct grand total with data value",function(t){return expect(e.find("td.pvtGrandTotal").text()).toBe("4"),expect(e.find("td.pvtGrandTotal").data("value")).toBe(4),t()})})}),describe("with rows/cols, sum-over-sum aggregator, Heatmap renderer",function(){var e;return e=null,beforeEach(function(r){return e=$("<div>").pivotUI(t,{rows:["gender"],cols:["colour"],aggregatorName:"Sum over Sum",vals:["successes","trials"],rendererName:"Heatmap",onRefresh:r})}),it("has all the basic UI elements",function(t){return expect(e.find("td.pvtAxisContainer").length).toBe(3),expect(e.find("td.pvtRendererArea").length).toBe(1),expect(e.find("td.pvtVals").length).toBe(1),expect(e.find("select.pvtRenderer").length).toBe(1),expect(e.find("select.pvtAggregator").length).toBe(1),expect(e.find("span.pvtAttr").length).toBe(6),t()}),it("reflects its inputs",function(t){return expect(e.find("td.pvtUnused span.pvtAttr").length).toBe(4),expect(e.find("td.pvtRows span.pvtAttr").length).toBe(1),expect(e.find("td.pvtCols span.pvtAttr").length).toBe(1),expect(e.find("select.pvtRenderer").val()).toBe("Heatmap"),expect(e.find("select.pvtAggregator").val()).toBe("Sum over Sum"),t()}),it("renders a table",function(t){return expect(e.find("table.pvtTable").length).toBe(1),t()}),describe("its renderer output",function(){return it("has the correct type and number of cells",function(t){return expect(e.find("th.pvtAxisLabel").length).toBe(2),expect(e.find("th.pvtRowLabel").length).toBe(2),expect(e.find("th.pvtColLabel").length).toBe(3),expect(e.find("th.pvtTotalLabel").length).toBe(2),expect(e.find("td.pvtVal").length).toBe(6),expect(e.find("td.pvtTotal").length).toBe(5),expect(e.find("td.pvtGrandTotal").length).toBe(1),t()}),it("has the correct textual representation",function(t){return expect(e.find("table.pvtTable").text()).toBe(["colour","blue","red","yellow","Totals","gender","female","0.26","0.14","0.20","male","0.20","0.20","Totals","0.20","0.26","0.14","0.20"].join("")),t()}),it("has a correct spot-checked cell with data value",function(t){return expect(e.find("td.col0.row1").text()).toBe("0.20"),expect(e.find("td.col0.row1").data("value")).toBe(42/215),t()})})}),describe("with ragged input",function(){var t;return t=$("<div>").pivotUI(e,{rows:["gender"],cols:["age"]}),it("renders a table with the correct textual representation",function(){return expect(t.find("table.pvtTable").text()).toBe(["age","12","34","null","Totals","gender","female","1","1","male","1","1","null","1","1","2","Totals","2","1","1","4"].join(""))})})}),describe("$.pivot()",function(){return describe("with no rows/cols, default count aggregator, default TableRenderer",function(){var e;return e=$("<div>").pivot(t),it("renders a table",function(){return expect(e.find("table.pvtTable").length).toBe(1)}),describe("its renderer output",function(){return it("has the correct textual representation",function(){return expect(e.find("table.pvtTable").text()).toBe(["Totals","4"].join(""))}),it("has a correct grand total with data value",function(){return expect(e.find("td.pvtGrandTotal").text()).toBe("4"),expect(e.find("td.pvtGrandTotal").data("value")).toBe(4)})})}),describe("with rows/cols, sum aggregator, derivedAttributes, filter and sorters",function(){var e,r,n,a,o;return n=$.pivotUtilities,a=n.sortAs,r=n.derivers,e=n.aggregators,o=$("<div>").pivot(t,{rows:["gender"],cols:["birthyear"],aggregator:e.Sum(["trialbins"]),filter:function(t){return"Nick"!==t.name},derivedAttributes:{birthyear:r.dateFormat("birthday","%y"),trialbins:r.bin("trials",10)},sorters:function(t){if("gender"===t)return a(["male","female"])}}),it("renders a table with the correct textual representation",function(){return expect(o.find("table.pvtTable").text()).toBe(["birthyear","1982","1983","Totals","gender","male","110.00","110.00","female","90.00","100.00","190.00","Totals","200.00","100.00","300.00"].join(""))})}),describe("with rows/cols, fraction-of aggregator",function(){var e,r;return e=$.pivotUtilities.aggregators,r=$("<div>").pivot(t,{rows:["gender"],aggregator:e["Sum as Fraction of Total"](["trials"])}),it("renders a table with the correct textual representation",function(){return expect(r.find("table.pvtTable").text()).toBe(["gender","Totals","female","47.8%","male","52.2%","Totals","100.0%"].join(""))})}),describe("with rows/cols, custom aggregator, custom renderer with options",function(){var e,r,n;return e=null,r=null,n=$("<div>").pivot(t,{rows:["name","colour"],cols:["trials","successes"],aggregator:function(){return{count2x:0,push:function(){return this.count2x+=2},value:function(){return this.count2x},format:function(t){return"formatted "+t}}},renderer:function(t,n){return e=t,r=n,$("<div>").addClass(n.greeting).text("world")},rendererOptions:{greeting:"hithere"}}),it("renders the custom renderer as per options",function(){return expect(n.find("div.hithere").length).toBe(1)}),describe("its received PivotData object",function(){return it("has a correct grand total value and format for custom aggregator",function(){var t,r;return t=e.getAggregator([],[]),r=t.value(),expect(r).toBe(8),expect(t.format(r)).toBe("formatted 8")})})}),describe("with ragged input",function(){var t;return t=$("<div>").pivot(e,{rows:["gender"],cols:["age"]}),it("renders a table with the correct textual representation",function(){return expect(t.find("table.pvtTable").text()).toBe(["age","12","34","null","Totals","gender","female","1","1","male","1","1","null","1","1","2","Totals","2","1","1","4"].join(""))})})}),describe("$.pivotUtilities",function(){return describe(".PivotData()",function(){var e;return e={aggregator:$.pivotUtilities.aggregators["Sum over Sum"](["a","b"])},describe("with no options",function(){var t,e;return t=[["a","b"],[1,2],[3,4]],e=new $.pivotUtilities.PivotData(t),it("has the correct grand total value",function(){return expect(e.getAggregator([],[]).value()).toBe(2)})}),describe("with array-of-array input",function(){var t,r;return t=[["a","b"],[1,2],[3,4]],r=new $.pivotUtilities.PivotData(t,e),it("has the correct grand total value",function(){return expect(r.getAggregator([],[]).value()).toBe(4/6)})}),describe("with array-of-object input",function(){var t,r;return t=[{a:1,b:2},{a:3,b:4}],r=new $.pivotUtilities.PivotData(t,e),it("has the correct grand total value",function(){return expect(r.getAggregator([],[]).value()).toBe(4/6)})}),describe("with ragged array-of-object input",function(){var t,r;return r=[{a:1},{b:4},{a:3,b:2}],t=new $.pivotUtilities.PivotData(r,e),it("has the correct grand total value",function(){return expect(t.getAggregator([],[]).value()).toBe(4/6)})}),describe("with function input",function(){var t,r;return t=function(t){return t({a:1,b:2}),t({a:3,b:4})},r=new $.pivotUtilities.PivotData(t,e),it("has the correct grand total value",function(){return expect(r.getAggregator([],[]).value()).toBe(4/6)})}),describe("with jQuery table element input",function(){var t,r;return r=$("<table>\n    <thead>\n        <tr> <th>a</th><th>b</th> </tr>\n    </thead>\n    <tbody>\n        <tr> <td>1</td> <td>2</td> </tr>\n        <tr> <td>3</td> <td>4</td> </tr>\n    </tbody>\n</table>"),t=new $.pivotUtilities.PivotData(r,e),it("has the correct grand total value",function(){return expect(t.getAggregator([],[]).value()).toBe(4/6)})}),describe("with a0-a00 input",function(){var t,e;return t=[{key:"a0",ym:"2020-01"},{key:"a0",ym:"2020-02"},{key:"a00",ym:"2020-01"},{key:"a00",ym:"2020-02"}],e=new $.pivotUtilities.PivotData(t,{rows:["key","ym"],cols:[]}),it("has correctly-ordered row keys",function(){return expect(e.getRowKeys()).toEqual([["a0","2020-01"],["a0","2020-02"],["a00","2020-01"],["a00","2020-02"]])})}),describe("with rows/cols",function(){var e;return e=new $.pivotUtilities.PivotData(t,{rows:["name","colour"],cols:["trials","successes"]}),it("has correctly-ordered row keys",function(){return expect(e.getRowKeys()).toEqual([["Carol","yellow"],["Jane","red"],["John","blue"],["Nick","blue"]])}),it("has correctly-ordered col keys",function(){return expect(e.getColKeys()).toEqual([[95,25],[102,14],[103,12],[112,30]])}),it("can be iterated over",function(){var t,r,n,a,o,i,c,u,s,l;for(i=0,c=0,s=e.getRowKeys(),r=0,a=s.length;r<a;r++)for(u=s[r],l=e.getColKeys(),n=0,o=l.length;n<o;n++)t=l[n],null!=e.getAggregator(u,t).value()?i++:c++;return expect(i).toBe(4),expect(c).toBe(12)}),it("returns matching records",function(){var t;return t=[],e.forEachMatchingRecord({gender:"male"},function(e){return t.push(e.name)}),expect(t).toEqual(["Nick","John"])}),it("has a correct spot-checked aggregator",function(){var t,r;return t=e.getAggregator(["Carol","yellow"],[102,14]),r=t.value(),expect(r).toBe(1),expect(t.format(r)).toBe("1")}),it("has a correct grand total aggregator",function(){var t,r;return t=e.getAggregator([],[]),r=t.value(),expect(r).toBe(4),expect(t.format(r)).toBe("4")})})}),describe(".aggregatorTemplates",function(){var e,r;return e=function(e){var r;return r=new $.pivotUtilities.PivotData(t,{aggregator:e}),r.getAggregator([],[]).value()},r=$.pivotUtilities.aggregatorTemplates,describe(".count",function(){return it("works",function(){return expect(e(r.count()())).toBe(4)})}),describe(".countUnique",function(){return it("works",function(){return expect(e(r.countUnique()(["gender"]))).toBe(2)})}),describe(".listUnique",function(){return it("works",function(){return expect(e(r.listUnique()(["gender"]))).toBe("female,male")})}),describe(".average",function(){return it("works",function(){return expect(e(r.average()(["trials"]))).toBe(103)})}),describe(".sum",function(){return it("works",function(){return expect(e(r.sum()(["trials"]))).toBe(412)})}),describe(".min",function(){return it("works",function(){return expect(e(r.min()(["trials"]))).toBe(95)})}),describe(".max",function(){return it("works",function(){return expect(e(r.max()(["trials"]))).toBe(112)})}),describe(".first",function(){return it("works",function(){return expect(e(r.first()(["name"]))).toBe("Carol")})}),describe(".last",function(){return it("works",function(){return expect(e(r.last()(["name"]))).toBe("Nick")})}),describe(".average",function(){return it("works",function(){return expect(e(r.average()(["trials"]))).toBe(103)})}),describe(".median",function(){return it("works",function(){return expect(e(r.median()(["trials"]))).toBe(102.5)})}),describe(".quantile",function(){return it("works",function(){return expect(e(r.quantile(0)(["trials"]))).toBe(95),expect(e(r.quantile(.1)(["trials"]))).toBe(98.5),expect(e(r.quantile(.25)(["trials"]))).toBe(98.5),expect(e(r.quantile(1/3)(["trials"]))).toBe(102),expect(e(r.quantile(1)(["trials"]))).toBe(112)})}),describe(".var",function(){return it("works",function(){return expect(e(r["var"]()(["trials"]))).toBe(48.666666666666686)})}),describe(".stdev",function(){return it("works",function(){return expect(e(r.stdev()(["trials"]))).toBe(6.976149845485451)})}),describe(".sumOverSum",function(){return it("works",function(){return expect(e(r.sumOverSum()(["successes","trials"]))).toBe(81/412)})})}),describe(".naturalSort()",function(){var t,e;return t=$.pivotUtilities.naturalSort,e=[null,NaN,-Infinity,"-Infinity",-3,"-3",-2,"-2",-1,"-1",0,"2e-1",1,"01","1",2,"002","002e0","02","2","2e-0",3,10,"10","11","12","1e2","112",Infinity,"Infinity","1a","2a","12a","20a","A","A","NaN","a","a","a01","a012","a02","a1","a2","a12","a12","a21","a21","b","c","d","null"],it("sorts naturally (null, NaN, numbers & numbery strings, Alphanum for text strings)",function(){return expect(e.slice().sort(t)).toEqual(e)})}),describe(".sortAs()",function(){var t;return t=$.pivotUtilities.sortAs,it("sorts with unknown values sorted at the end",function(){return expect([5,2,3,4,1].sort(t([4,3,2]))).toEqual([4,3,2,1,5])}),it("sorts lowercase after uppercase",function(){return expect(["Ab","aA","aa","ab"].sort(t(["Ab","Aa"]))).toEqual(["Ab","ab","aa","aA"])})}),describe(".numberFormat()",function(){var t;return t=$.pivotUtilities.numberFormat,it("formats numbers",function(){var e;return e=t(),expect(e(1234567.89123456)).toEqual("1,234,567.89")}),it("formats booleans",function(){var e;return e=t(),expect(e(!0)).toEqual("1.00")}),it("formats numbers in strings",function(){var e;return e=t(),expect(e("1234567.89123456")).toEqual("1,234,567.89")}),it("doesn't formats strings",function(){var e;return e=t(),expect(e("hi there")).toEqual("")}),it("doesn't formats objects",function(){var e;return e=t(),expect(e({a:1})).toEqual("")}),it("formats percentages",function(){var e;return e=t({scaler:100,suffix:"%"}),expect(e(.12345)).toEqual("12.35%")}),it("adds separators",function(){var e;return e=t({thousandsSep:"a",decimalSep:"b"}),expect(e(1234567.89123456)).toEqual("1a234a567b89")}),it("adds prefixes and suffixes",function(){var e;return e=t({prefix:"a",suffix:"b"}),expect(e(1234567.89123456)).toEqual("a1,234,567.89b")}),it("scales and rounds",function(){var e;return e=t({digitsAfterDecimal:3,scaler:1e3}),expect(e(1234567.89123456)).toEqual("1,234,567,891.235")})}),describe(".derivers",function(){return describe(".dateFormat()",function(){var t;return t=$.pivotUtilities.derivers.dateFormat("x","abc % %% %%% %a %y %m %n %d %w %x %H %M %S",!0),it("formats date objects",function(){return expect(t({x:new Date("2015-01-02T23:43:11Z")})).toBe("abc % %% %%% %a 2015 01 Jan 02 Fri 5 23 43 11")}),it("formats input parsed by Date.parse()",function(){return expect(t({x:"2015-01-02T23:43:11Z"})).toBe("abc % %% %%% %a 2015 01 Jan 02 Fri 5 23 43 11"),expect(t({x:"bla"})).toBe("")})}),describe(".bin()",function(){var t;return t=$.pivotUtilities.derivers.bin("x",10),it("bins numbers",function(){return expect(t({x:11})).toBe(10),expect(t({x:9})).toBe(0),expect(t({x:111})).toBe(110)}),it("bins booleans",function(){return expect(t({x:!0})).toBe(0)}),it("bins negative numbers",function(){return expect(t({x:-12})).toBe(-10)}),it("doesn't bin strings",function(){return expect(t({x:"a"})).toBeNaN()}),it("doesn't bin objects",function(){return expect(t({x:{a:1}})).toBeNaN()})})})})}).call(this);
 //# sourceMappingURL=pivot_spec.min.js.map
diff --git a/dist/pivot_spec.min.js.map b/dist/pivot_spec.min.js.map
index b410bc30..73cf03bc 100644
--- a/dist/pivot_spec.min.js.map
+++ b/dist/pivot_spec.min.js.map
@@ -1 +1 @@
-{"version":3,"sources":["pivot_spec.coffee","pivot_spec.min.js"],"names":["fixtureData","raggedFixtureData","name","colour","age","gender","describe","table","beforeEach","done","$","pivotUI","onRefresh","it","expect","find","length","toBe","val","text","join","data","rows","cols","aggregatorName","vals","rendererName","pivot","aggregators","derivers","ref","sortAs","pivotUtilities","aggregator","filter","record","derivedAttributes","birthyear","dateFormat","trialbins","bin","sorters","attr","received_PivotData","received_rendererOptions","count2x","push","this","value","format","x","renderer","a","b","addClass","greeting","rendererOptions","agg","getAggregator","sumOverSumOpts","aoaInput","pd","PivotData","aosInput","raggedAosInput","functionInput","tableInput","getRowKeys","toEqual","getColKeys","c","i","j","len","len1","numNotNull","numNull","r","ref1","records","forEachMatchingRecord","getVal","tpl","aggregatorTemplates","count","countUnique","listUnique","average","sum","min","max","first","last","median","quantile","stdev","sumOverSum","naturalSort","sortedArr","slice","sort","numberFormat","nf","scaler","suffix","thousandsSep","decimalSep","prefix","digitsAfterDecimal","df","Date","binner","toBeNaN","call"],"mappings":"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","file":"pivot_spec.min.js","sourcesContent":["fixtureData = [\n    [\"name\",    \"gender\",   \"colour\",    \"birthday\",     \"trials\",   \"successes\"],\n    [\"Nick\",    \"male\",     \"blue\",      \"1982-11-07\",   103,        12],\n    [\"Jane\",    \"female\",   \"red\",       \"1982-11-08\",   95,         25],\n    [\"John\",    \"male\",     \"blue\",      \"1982-12-08\",   112,        30],\n    [\"Carol\",   \"female\",   \"yellow\",    \"1983-12-08\",   102,        14]\n]\n\nraggedFixtureData = [\n    {name: \"Nick\", \"colour\": \"red\", \"age\": 34}\n    {name: \"Jane\", \"gender\": \"female\"}\n    {name: \"John\", \"gender\": \"male\", \"age\": 12}\n    {name: \"Jim\", \"gender\": null, \"age\": 12}\n]\n\ndescribe \"$.pivotUI()\", ->\n    describe \"with no rows/cols, default count aggregator, default TableRenderer\",  ->\n        table = null\n\n        beforeEach (done) ->\n            table = $(\"<div>\").pivotUI fixtureData, onRefresh: done\n        it \"has all the basic UI elements\", (done) ->\n            expect table.find(\"td.pvtAxisContainer\").length\n            .toBe  3\n            expect table.find(\"td.pvtRendererArea\").length\n            .toBe  1\n            expect table.find(\"td.pvtVals\").length\n            .toBe  1\n            expect table.find(\"select.pvtRenderer\").length\n            .toBe  1\n            expect table.find(\"select.pvtAggregator\").length\n            .toBe  1\n            expect table.find(\"span.pvtAttr\").length\n            .toBe  6\n            done()\n\n        it \"reflects its inputs\", (done) ->\n            expect table.find(\"td.pvtUnused span.pvtAttr\").length\n            .toBe  6\n            expect table.find(\"select.pvtRenderer\").val()\n            .toBe  \"Table\"\n            expect table.find(\"select.pvtAggregator\").val()\n            .toBe  \"Count\"\n            done()\n\n        it \"renders a table\", (done) ->\n            expect table.find(\"table.pvtTable\").length\n            .toBe  1\n            done()\n\n\n        describe \"its renderer output\", ->\n            it \"has the correct type and number of cells\", (done) ->\n                expect table.find(\"th.pvtTotalLabel\").length\n                .toBe  1\n                expect table.find(\"td.pvtGrandTotal\").length\n                .toBe  1\n                done()\n\n            it \"has the correct textual representation\", (done) ->\n                expect table.find(\"table.pvtTable\").text()\n                .toBe [\"Totals\", \"4\"].join(\"\")\n                done()\n\n            it \"has a correct grand total with data value\", (done) ->\n                expect table.find(\"td.pvtGrandTotal\").text()\n                .toBe  \"4\"\n                expect table.find(\"td.pvtGrandTotal\").data(\"value\")\n                .toBe  4\n                done()\n\n    describe \"with rows/cols, sum-over-sum aggregator, Heatmap renderer\",  ->\n        table = null\n\n        beforeEach (done) ->\n            table = $(\"<div>\").pivotUI fixtureData,\n                rows: [\"gender\"], cols: [\"colour\"]\n                aggregatorName: \"Sum over Sum\"\n                vals: [\"successes\", \"trials\"]\n                rendererName: \"Heatmap\"\n                onRefresh: done\n\n        it \"has all the basic UI elements\", (done) ->\n            expect table.find(\"td.pvtAxisContainer\").length\n            .toBe  3\n            expect table.find(\"td.pvtRendererArea\").length\n            .toBe  1\n            expect table.find(\"td.pvtVals\").length\n            .toBe  1\n            expect table.find(\"select.pvtRenderer\").length\n            .toBe  1\n            expect table.find(\"select.pvtAggregator\").length\n            .toBe  1\n            expect table.find(\"span.pvtAttr\").length\n            .toBe  6\n            done()\n\n        it \"reflects its inputs\", (done) ->\n            expect table.find(\"td.pvtUnused span.pvtAttr\").length\n            .toBe  4\n            expect table.find(\"td.pvtRows span.pvtAttr\").length\n            .toBe  1\n            expect table.find(\"td.pvtCols span.pvtAttr\").length\n            .toBe  1\n            expect table.find(\"select.pvtRenderer\").val()\n            .toBe  \"Heatmap\"\n            expect table.find(\"select.pvtAggregator\").val()\n            .toBe  \"Sum over Sum\"\n            done()\n\n        it \"renders a table\", (done) ->\n            expect table.find(\"table.pvtTable\").length\n            .toBe  1\n            done()\n\n        describe \"its renderer output\", ->\n            it \"has the correct type and number of cells\", (done) ->\n                expect table.find(\"th.pvtAxisLabel\").length\n                .toBe  2\n                expect table.find(\"th.pvtRowLabel\").length\n                .toBe  2\n                expect table.find(\"th.pvtColLabel\").length\n                .toBe  3\n                expect table.find(\"th.pvtTotalLabel\").length\n                .toBe  2\n                expect table.find(\"td.pvtVal\").length\n                .toBe  6\n                expect table.find(\"td.pvtTotal\").length\n                .toBe  5\n                expect table.find(\"td.pvtGrandTotal\").length\n                .toBe  1\n                done()\n\n            it \"has the correct textual representation\", (done) ->\n                expect table.find(\"table.pvtTable\").text()\n                .toBe [\n                    \"colour\",   \"blue\", \"red\",  \"yellow\",   \"Totals\",\n                    \"gender\",\n                    \"female\",           \"0.26\", \"0.14\",     \"0.20\",\n                    \"male\",     \"0.20\",                     \"0.20\",\n                    \"Totals\",   \"0.20\", \"0.26\", \"0.14\",     \"0.20\"\n                    ].join(\"\")\n                done()\n\n            it \"has a correct spot-checked cell with data value\", (done) ->\n                expect table.find(\"td.col0.row1\").text()\n                .toBe  \"0.20\"\n                expect table.find(\"td.col0.row1\").data(\"value\")\n                .toBe  (12+30)/(103+112)\n                done()\n\n    describe \"with ragged input\",  ->\n        table = $(\"<div>\").pivotUI raggedFixtureData, rows: [\"gender\"], cols: [\"age\"]\n\n        it \"renders a table with the correct textual representation\", ->\n            expect table.find(\"table.pvtTable\").text()\n            .toBe [\n                \"age\",     \"12\",  \"34\",  \"null\",  \"Totals\"\n                \"gender\",\n                \"female\",                 \"1\",    \"1\"\n                \"male\",    \"1\",                   \"1\"\n                \"null\",    \"1\",    \"1\",           \"2\"\n                \"Totals\",  \"2\",    \"1\",   \"1\",    \"4\"\n                ].join(\"\")\n\ndescribe \"$.pivot()\", ->\n\n    describe \"with no rows/cols, default count aggregator, default TableRenderer\",  ->\n        table = $(\"<div>\").pivot fixtureData\n\n        it \"renders a table\", ->\n            expect table.find(\"table.pvtTable\").length\n            .toBe  1\n\n        describe \"its renderer output\", ->\n\n            it \"has the correct textual representation\", ->\n                expect table.find(\"table.pvtTable\").text()\n                .toBe [\"Totals\", \"4\"].join(\"\")\n\n            it \"has a correct grand total with data value\", ->\n                expect table.find(\"td.pvtGrandTotal\").text()\n                .toBe  \"4\"\n                expect table.find(\"td.pvtGrandTotal\").data(\"value\")\n                .toBe  4\n\n    describe \"with rows/cols, sum aggregator, derivedAttributes, filter and sorters\",  ->\n        {sortAs, derivers, aggregators} = $.pivotUtilities\n        table = $(\"<div>\").pivot fixtureData,\n            rows: [\"gender\"], cols: [\"birthyear\"], aggregator: aggregators[\"Sum\"]([\"trialbins\"])\n            filter: (record) -> record.name != \"Nick\"\n            derivedAttributes:\n                birthyear: derivers.dateFormat \"birthday\", \"%y\"\n                trialbins: derivers.bin \"trials\", 10\n            sorters: (attr) ->\n                if attr == \"gender\" then return sortAs([\"male\", \"female\"])\n\n        it \"renders a table with the correct textual representation\", ->\n            expect table.find(\"table.pvtTable\").text()\n            .toBe [\n                \"birthyear\",    \"1982\",     \"1983\",     \"Totals\"\n                \"gender\",\n                \"male\",         \"110.00\",               \"110.00\"\n                \"female\",       \"90.00\",    \"100.00\",   \"190.00\"\n                \"Totals\",       \"200.00\",   \"100.00\",   \"300.00\"\n                ].join(\"\")\n\n    describe \"with rows/cols, fraction-of aggregator\",  ->\n        {aggregators} = $.pivotUtilities\n        table = $(\"<div>\").pivot fixtureData,\n            rows: [\"gender\"]\n            aggregator: aggregators[\"Sum as Fraction of Total\"]([\"trials\"])\n\n        it \"renders a table with the correct textual representation\", ->\n            expect table.find(\"table.pvtTable\").text()\n            .toBe [\n                \"gender\",  \"Totals\"\n                \"female\",  \"47.8%\"\n                \"male\",    \"52.2%\"\n                \"Totals\",  \"100.0%\"\n                ].join(\"\")\n\n    describe \"with rows/cols, custom aggregator, custom renderer with options\",  ->\n        received_PivotData = null\n        received_rendererOptions = null\n\n        table = $(\"<div>\").pivot fixtureData,\n            rows: [\"name\", \"colour\"], cols: [\"trials\", \"successes\"]\n            aggregator: ->\n                count2x: 0\n                push: -> @count2x +=2\n                value: -> @count2x\n                format: (x) -> \"formatted \" + x\n            renderer: (a,b) ->\n                received_PivotData = a\n                received_rendererOptions = b\n                return $(\"<div>\").addClass(b.greeting).text(\"world\")\n            rendererOptions: {greeting:\"hithere\"}\n\n        it \"renders the custom renderer as per options\", ->\n            expect table.find(\"div.hithere\").length\n            .toBe  1\n\n        describe \"its received PivotData object\", ->\n            it \"has a correct grand total value and format for custom aggregator\", ->\n                agg = received_PivotData.getAggregator([],[])\n                val = agg.value()\n                expect(val).toBe 8\n                expect(agg.format(val)).toBe \"formatted 8\"\n\n\n    describe \"with ragged input\",  ->\n        table = $(\"<div>\").pivot raggedFixtureData, rows: [\"gender\"], cols: [\"age\"]\n\n        it \"renders a table with the correct textual representation\", ->\n            expect table.find(\"table.pvtTable\").text()\n            .toBe [\n                \"age\",     \"12\",  \"34\",  \"null\",  \"Totals\"\n                \"gender\",\n                \"female\",                 \"1\",    \"1\"\n                \"male\",    \"1\",                   \"1\"\n                \"null\",    \"1\",    \"1\",           \"2\"\n                \"Totals\",  \"2\",    \"1\",   \"1\",    \"4\"\n                ].join(\"\")\n\ndescribe \"$.pivotUtilities\", ->\n\n    describe \".PivotData()\", ->\n        sumOverSumOpts =\n            aggregator: $.pivotUtilities.aggregators[\"Sum over Sum\"]([\"a\",\"b\"])\n\n        describe \"with no options\", ->\n            aoaInput =  [ [\"a\",\"b\"], [1,2], [3,4] ]\n            pd = new $.pivotUtilities.PivotData aoaInput\n\n            it \"has the correct grand total value\", ->\n                expect pd.getAggregator([],[]).value()\n                .toBe 2\n\n        describe \"with array-of-array input\", ->\n            aoaInput =  [ [\"a\",\"b\"], [1,2], [3,4] ]\n            pd = new $.pivotUtilities.PivotData aoaInput, sumOverSumOpts\n\n            it \"has the correct grand total value\", ->\n                expect pd.getAggregator([],[]).value()\n                .toBe (1+3)/(2+4)\n\n        describe \"with array-of-object input\", ->\n            aosInput =  [ {a:1, b:2}, {a:3, b:4} ]\n            pd = new $.pivotUtilities.PivotData aosInput, sumOverSumOpts\n\n            it \"has the correct grand total value\", ->\n                expect pd.getAggregator([],[]).value()\n                .toBe (1+3)/(2+4)\n\n        describe \"with ragged array-of-object input\", ->\n            raggedAosInput =  [ {a:1}, {b:4}, {a: 3, b: 2} ]\n            pd = new $.pivotUtilities.PivotData raggedAosInput, sumOverSumOpts\n\n            it \"has the correct grand total value\", ->\n                expect pd.getAggregator([],[]).value()\n                .toBe (1+3)/(2+4)\n\n        describe \"with function input\", ->\n            functionInput = (record) ->\n                record a:1, b:2\n                record a:3, b:4\n            pd = new $.pivotUtilities.PivotData functionInput, sumOverSumOpts\n\n            it \"has the correct grand total value\", ->\n                expect pd.getAggregator([],[]).value()\n                .toBe (1+3)/(2+4)\n\n        describe \"with jQuery table element input\", ->\n            tableInput = $ \"\"\"\n                <table>\n                    <thead>\n                        <tr> <th>a</th><th>b</th> </tr>\n                    </thead>\n                    <tbody>\n                        <tr> <td>1</td> <td>2</td> </tr>\n                        <tr> <td>3</td> <td>4</td> </tr>\n                    </tbody>\n                </table>\n                \"\"\"\n            pd = new $.pivotUtilities.PivotData tableInput, sumOverSumOpts\n\n            it \"has the correct grand total value\", ->\n                expect pd.getAggregator([],[]).value()\n                .toBe (1+3)/(2+4)\n\n\n        describe \"with rows/cols\", ->\n            pd = new $.pivotUtilities.PivotData fixtureData,\n                rows: [\"name\", \"colour\"],\n                cols: [\"trials\", \"successes\"]\n\n            it \"has correctly-ordered row keys\", ->\n                expect pd.getRowKeys()\n                .toEqual [ [ 'Carol', 'yellow' ], [ 'Jane', 'red' ], [ 'John', 'blue' ], [ 'Nick', 'blue' ] ]\n\n            it \"has correctly-ordered col keys\", ->\n                expect pd.getColKeys()\n                .toEqual [ [ 95, 25 ], [ 102, 14 ], [ 103, 12 ], [ 112, 30 ] ]\n\n            it \"can be iterated over\", ->\n                numNotNull = 0\n                numNull = 0\n                for r in pd.getRowKeys()\n                    for c in pd.getColKeys()\n                        if pd.getAggregator(r, c).value()?\n                            numNotNull++\n                        else\n                            numNull++\n                expect numNotNull\n                .toBe 4\n                expect numNull\n                .toBe 12\n\n            it \"returns matching records\", ->\n                records = []\n                pd.forEachMatchingRecord gender: \"male\", (x) -> records.push(x.name)\n                expect records\n                .toEqual [\"Nick\", \"John\"]\n\n            it \"has a correct spot-checked aggregator\", ->\n                agg = pd.getAggregator([ 'Carol', 'yellow' ],[ 102, 14 ])\n                val = agg.value()\n                expect(val).toBe 1\n                expect(agg.format(val)).toBe \"1\"\n\n            it \"has a correct grand total aggregator\", ->\n                agg = pd.getAggregator([],[])\n                val = agg.value()\n                expect(val).toBe 4\n                expect(agg.format(val)).toBe \"4\"\n\n    describe \".aggregatorTemplates\", ->\n\n        getVal = (aggregator) ->\n            pd = new $.pivotUtilities.PivotData(fixtureData, {aggregator})\n            return pd.getAggregator([],[]).value()\n        tpl = $.pivotUtilities.aggregatorTemplates\n\n        describe \".count\", ->\n            it \"works\", ->\n                expect getVal(tpl.count()())\n                .toBe 4\n\n        describe \".countUnique\", ->\n            it \"works\", ->\n                expect getVal(tpl.countUnique()(['gender']))\n                .toBe 2\n\n        describe \".listUnique\", ->\n            it \"works\", ->\n                expect getVal(tpl.listUnique()(['gender']))\n                .toBe 'female,male'\n\n        describe \".average\", ->\n            it \"works\", ->\n                expect getVal(tpl.average()(['trials']))\n                .toBe 103\n\n        describe \".sum\", ->\n            it \"works\", ->\n                expect getVal(tpl.sum()(['trials']))\n                .toBe 412\n\n        describe \".min\", ->\n            it \"works\", ->\n                expect getVal(tpl.min()(['trials']))\n                .toBe 95\n\n        describe \".max\", ->\n            it \"works\", ->\n                expect getVal(tpl.max()(['trials']))\n                .toBe 112\n\n        describe \".first\", ->\n            it \"works\", ->\n                expect getVal(tpl.first()(['name']))\n                .toBe 'Carol'\n\n        describe \".last\", ->\n            it \"works\", ->\n                expect getVal(tpl.last()(['name']))\n                .toBe 'Nick'\n\n        describe \".average\", ->\n            it \"works\", ->\n                expect getVal(tpl.average()(['trials']))\n                .toBe 103\n\n        describe \".median\", ->\n            it \"works\", ->\n                expect getVal(tpl.median()(['trials']))\n                .toBe 102.5\n\n        describe \".quantile\", ->\n            it \"works\", ->\n                expect getVal(tpl.quantile(0)(['trials']))\n                .toBe 95\n                expect getVal(tpl.quantile(0.1)(['trials']))\n                .toBe 98.5\n                expect getVal(tpl.quantile(0.25)(['trials']))\n                .toBe 98.5\n                expect getVal(tpl.quantile(1/3)(['trials']))\n                .toBe 102\n                expect getVal(tpl.quantile(1)(['trials']))\n                .toBe 112\n\n        describe \".var\", ->\n            it \"works\", ->\n                expect getVal(tpl.var()(['trials']))\n                .toBe 48.666666666666686\n\n        describe \".stdev\", ->\n            it \"works\", ->\n                expect getVal(tpl.stdev()(['trials']))\n                .toBe 6.976149845485451\n\n        describe \".sumOverSum\", ->\n            it \"works\", ->\n                expect getVal(tpl.sumOverSum()(['successes', 'trials']))\n                .toBe (12+25+30+14)/(95+102+103+112)\n\n    describe \".naturalSort()\", ->\n        naturalSort = $.pivotUtilities.naturalSort\n\n        sortedArr = [\n            null, NaN,\n            -Infinity, '-Infinity', -3, '-3', -2, '-2', -1, '-1',\n            0, '2e-1', 1, '01', '1', 2, '002', '002e0', '02', '2', '2e-0',\n            3, 10, '10', '11', '12', '1e2', '112', Infinity, 'Infinity',\n            '1a', '2a','12a','20a',\n            'A', 'A', 'NaN', 'a', 'a',\n            'a01', 'a012', 'a02', 'a1', 'a2', 'a12', 'a12', 'a21', 'a21',\n            'b', 'c', 'd', 'null'\n        ]\n\n        it \"sorts naturally (null, NaN, numbers & numbery strings, Alphanum for text strings)\", ->\n            expect sortedArr.slice().sort(naturalSort)\n            .toEqual sortedArr\n\n    describe \".sortAs()\", ->\n        sortAs = $.pivotUtilities.sortAs\n\n        it \"sorts with unknown values sorted at the end\", ->\n            expect [5,2,3,4,1].sort sortAs([4,3,2])\n            .toEqual [4,3,2,1,5]\n\n        it \"sorts lowercase after uppercase\", ->\n            expect [\"Ab\",\"aA\",\"aa\",\"ab\"].sort sortAs([\"Ab\",\"Aa\"])\n            .toEqual [\"Ab\",\"ab\",\"aa\",\"aA\"]\n\n    describe \".numberFormat()\", ->\n        numberFormat = $.pivotUtilities.numberFormat\n\n        it \"formats numbers\", ->\n            nf = numberFormat()\n            expect nf 1234567.89123456\n            .toEqual \"1,234,567.89\"\n\n        it \"formats booleans\", ->\n            nf = numberFormat()\n            expect nf true\n            .toEqual \"1.00\"\n\n        it \"formats numbers in strings\", ->\n            nf = numberFormat()\n            expect nf \"1234567.89123456\"\n            .toEqual \"1,234,567.89\"\n\n        it \"doesn't formats strings\", ->\n            nf = numberFormat()\n            expect nf \"hi there\"\n            .toEqual \"\"\n\n        it \"doesn't formats objects\", ->\n            nf = numberFormat()\n            expect nf {a:1}\n            .toEqual \"\"\n\n        it \"formats percentages\", ->\n            nf = numberFormat(scaler: 100, suffix: \"%\")\n            expect nf 0.12345\n            .toEqual \"12.35%\"\n\n        it \"adds separators\", ->\n            nf = numberFormat(thousandsSep: \"a\", decimalSep: \"b\")\n            expect nf 1234567.89123456\n            .toEqual \"1a234a567b89\"\n\n        it \"adds prefixes and suffixes\", ->\n            nf = numberFormat(prefix: \"a\", suffix: \"b\")\n            expect nf 1234567.89123456\n            .toEqual \"a1,234,567.89b\"\n\n        it \"scales and rounds\", ->\n            nf = numberFormat(digitsAfterDecimal: 3, scaler: 1000)\n            expect nf 1234567.89123456\n            .toEqual \"1,234,567,891.235\"\n\n    describe \".derivers\", ->\n        describe \".dateFormat()\", ->\n            df = $.pivotUtilities.derivers.dateFormat \"x\", \"abc % %% %%% %a %y %m %n %d %w %x %H %M %S\", true\n\n            it \"formats date objects\", ->\n                expect df {x: new Date(\"2015-01-02T23:43:11Z\")}\n                .toBe 'abc % %% %%% %a 2015 01 Jan 02 Fri 5 23 43 11'\n\n            it \"formats input parsed by Date.parse()\", ->\n                expect df {x: \"2015-01-02T23:43:11Z\"}\n                .toBe 'abc % %% %%% %a 2015 01 Jan 02 Fri 5 23 43 11'\n\n                expect df {x: \"bla\"}\n                .toBe ''\n\n        describe \".bin()\", ->\n            binner = $.pivotUtilities.derivers.bin \"x\", 10\n\n            it \"bins numbers\", ->\n                expect binner {x: 11}\n                .toBe 10\n\n                expect binner {x: 9}\n                .toBe 0\n\n                expect binner {x: 111}\n                .toBe 110\n\n            it \"bins booleans\", ->\n                expect binner {x: true}\n                .toBe 0\n\n            it \"bins negative numbers\", ->\n                expect binner {x: -12}\n                .toBe -10\n\n            it \"doesn't bin strings\", ->\n                expect binner {x: \"a\"}\n                .toBeNaN()\n\n            it \"doesn't bin objects\", ->\n                expect binner {x: {a:1}}\n                .toBeNaN()\n","(function() {\n  var fixtureData, raggedFixtureData;\n\n  fixtureData = [[\"name\", \"gender\", \"colour\", \"birthday\", \"trials\", \"successes\"], [\"Nick\", \"male\", \"blue\", \"1982-11-07\", 103, 12], [\"Jane\", \"female\", \"red\", \"1982-11-08\", 95, 25], [\"John\", \"male\", \"blue\", \"1982-12-08\", 112, 30], [\"Carol\", \"female\", \"yellow\", \"1983-12-08\", 102, 14]];\n\n  raggedFixtureData = [\n    {\n      name: \"Nick\",\n      \"colour\": \"red\",\n      \"age\": 34\n    }, {\n      name: \"Jane\",\n      \"gender\": \"female\"\n    }, {\n      name: \"John\",\n      \"gender\": \"male\",\n      \"age\": 12\n    }, {\n      name: \"Jim\",\n      \"gender\": null,\n      \"age\": 12\n    }\n  ];\n\n  describe(\"$.pivotUI()\", function() {\n    describe(\"with no rows/cols, default count aggregator, default TableRenderer\", function() {\n      var table;\n      table = null;\n      beforeEach(function(done) {\n        return table = $(\"<div>\").pivotUI(fixtureData, {\n          onRefresh: done\n        });\n      });\n      it(\"has all the basic UI elements\", function(done) {\n        expect(table.find(\"td.pvtAxisContainer\").length).toBe(3);\n        expect(table.find(\"td.pvtRendererArea\").length).toBe(1);\n        expect(table.find(\"td.pvtVals\").length).toBe(1);\n        expect(table.find(\"select.pvtRenderer\").length).toBe(1);\n        expect(table.find(\"select.pvtAggregator\").length).toBe(1);\n        expect(table.find(\"span.pvtAttr\").length).toBe(6);\n        return done();\n      });\n      it(\"reflects its inputs\", function(done) {\n        expect(table.find(\"td.pvtUnused span.pvtAttr\").length).toBe(6);\n        expect(table.find(\"select.pvtRenderer\").val()).toBe(\"Table\");\n        expect(table.find(\"select.pvtAggregator\").val()).toBe(\"Count\");\n        return done();\n      });\n      it(\"renders a table\", function(done) {\n        expect(table.find(\"table.pvtTable\").length).toBe(1);\n        return done();\n      });\n      return describe(\"its renderer output\", function() {\n        it(\"has the correct type and number of cells\", function(done) {\n          expect(table.find(\"th.pvtTotalLabel\").length).toBe(1);\n          expect(table.find(\"td.pvtGrandTotal\").length).toBe(1);\n          return done();\n        });\n        it(\"has the correct textual representation\", function(done) {\n          expect(table.find(\"table.pvtTable\").text()).toBe([\"Totals\", \"4\"].join(\"\"));\n          return done();\n        });\n        return it(\"has a correct grand total with data value\", function(done) {\n          expect(table.find(\"td.pvtGrandTotal\").text()).toBe(\"4\");\n          expect(table.find(\"td.pvtGrandTotal\").data(\"value\")).toBe(4);\n          return done();\n        });\n      });\n    });\n    describe(\"with rows/cols, sum-over-sum aggregator, Heatmap renderer\", function() {\n      var table;\n      table = null;\n      beforeEach(function(done) {\n        return table = $(\"<div>\").pivotUI(fixtureData, {\n          rows: [\"gender\"],\n          cols: [\"colour\"],\n          aggregatorName: \"Sum over Sum\",\n          vals: [\"successes\", \"trials\"],\n          rendererName: \"Heatmap\",\n          onRefresh: done\n        });\n      });\n      it(\"has all the basic UI elements\", function(done) {\n        expect(table.find(\"td.pvtAxisContainer\").length).toBe(3);\n        expect(table.find(\"td.pvtRendererArea\").length).toBe(1);\n        expect(table.find(\"td.pvtVals\").length).toBe(1);\n        expect(table.find(\"select.pvtRenderer\").length).toBe(1);\n        expect(table.find(\"select.pvtAggregator\").length).toBe(1);\n        expect(table.find(\"span.pvtAttr\").length).toBe(6);\n        return done();\n      });\n      it(\"reflects its inputs\", function(done) {\n        expect(table.find(\"td.pvtUnused span.pvtAttr\").length).toBe(4);\n        expect(table.find(\"td.pvtRows span.pvtAttr\").length).toBe(1);\n        expect(table.find(\"td.pvtCols span.pvtAttr\").length).toBe(1);\n        expect(table.find(\"select.pvtRenderer\").val()).toBe(\"Heatmap\");\n        expect(table.find(\"select.pvtAggregator\").val()).toBe(\"Sum over Sum\");\n        return done();\n      });\n      it(\"renders a table\", function(done) {\n        expect(table.find(\"table.pvtTable\").length).toBe(1);\n        return done();\n      });\n      return describe(\"its renderer output\", function() {\n        it(\"has the correct type and number of cells\", function(done) {\n          expect(table.find(\"th.pvtAxisLabel\").length).toBe(2);\n          expect(table.find(\"th.pvtRowLabel\").length).toBe(2);\n          expect(table.find(\"th.pvtColLabel\").length).toBe(3);\n          expect(table.find(\"th.pvtTotalLabel\").length).toBe(2);\n          expect(table.find(\"td.pvtVal\").length).toBe(6);\n          expect(table.find(\"td.pvtTotal\").length).toBe(5);\n          expect(table.find(\"td.pvtGrandTotal\").length).toBe(1);\n          return done();\n        });\n        it(\"has the correct textual representation\", function(done) {\n          expect(table.find(\"table.pvtTable\").text()).toBe([\"colour\", \"blue\", \"red\", \"yellow\", \"Totals\", \"gender\", \"female\", \"0.26\", \"0.14\", \"0.20\", \"male\", \"0.20\", \"0.20\", \"Totals\", \"0.20\", \"0.26\", \"0.14\", \"0.20\"].join(\"\"));\n          return done();\n        });\n        return it(\"has a correct spot-checked cell with data value\", function(done) {\n          expect(table.find(\"td.col0.row1\").text()).toBe(\"0.20\");\n          expect(table.find(\"td.col0.row1\").data(\"value\")).toBe((12 + 30) / (103 + 112));\n          return done();\n        });\n      });\n    });\n    return describe(\"with ragged input\", function() {\n      var table;\n      table = $(\"<div>\").pivotUI(raggedFixtureData, {\n        rows: [\"gender\"],\n        cols: [\"age\"]\n      });\n      return it(\"renders a table with the correct textual representation\", function() {\n        return expect(table.find(\"table.pvtTable\").text()).toBe([\"age\", \"12\", \"34\", \"null\", \"Totals\", \"gender\", \"female\", \"1\", \"1\", \"male\", \"1\", \"1\", \"null\", \"1\", \"1\", \"2\", \"Totals\", \"2\", \"1\", \"1\", \"4\"].join(\"\"));\n      });\n    });\n  });\n\n  describe(\"$.pivot()\", function() {\n    describe(\"with no rows/cols, default count aggregator, default TableRenderer\", function() {\n      var table;\n      table = $(\"<div>\").pivot(fixtureData);\n      it(\"renders a table\", function() {\n        return expect(table.find(\"table.pvtTable\").length).toBe(1);\n      });\n      return describe(\"its renderer output\", function() {\n        it(\"has the correct textual representation\", function() {\n          return expect(table.find(\"table.pvtTable\").text()).toBe([\"Totals\", \"4\"].join(\"\"));\n        });\n        return it(\"has a correct grand total with data value\", function() {\n          expect(table.find(\"td.pvtGrandTotal\").text()).toBe(\"4\");\n          return expect(table.find(\"td.pvtGrandTotal\").data(\"value\")).toBe(4);\n        });\n      });\n    });\n    describe(\"with rows/cols, sum aggregator, derivedAttributes, filter and sorters\", function() {\n      var aggregators, derivers, ref, sortAs, table;\n      ref = $.pivotUtilities, sortAs = ref.sortAs, derivers = ref.derivers, aggregators = ref.aggregators;\n      table = $(\"<div>\").pivot(fixtureData, {\n        rows: [\"gender\"],\n        cols: [\"birthyear\"],\n        aggregator: aggregators[\"Sum\"]([\"trialbins\"]),\n        filter: function(record) {\n          return record.name !== \"Nick\";\n        },\n        derivedAttributes: {\n          birthyear: derivers.dateFormat(\"birthday\", \"%y\"),\n          trialbins: derivers.bin(\"trials\", 10)\n        },\n        sorters: function(attr) {\n          if (attr === \"gender\") {\n            return sortAs([\"male\", \"female\"]);\n          }\n        }\n      });\n      return it(\"renders a table with the correct textual representation\", function() {\n        return expect(table.find(\"table.pvtTable\").text()).toBe([\"birthyear\", \"1982\", \"1983\", \"Totals\", \"gender\", \"male\", \"110.00\", \"110.00\", \"female\", \"90.00\", \"100.00\", \"190.00\", \"Totals\", \"200.00\", \"100.00\", \"300.00\"].join(\"\"));\n      });\n    });\n    describe(\"with rows/cols, fraction-of aggregator\", function() {\n      var aggregators, table;\n      aggregators = $.pivotUtilities.aggregators;\n      table = $(\"<div>\").pivot(fixtureData, {\n        rows: [\"gender\"],\n        aggregator: aggregators[\"Sum as Fraction of Total\"]([\"trials\"])\n      });\n      return it(\"renders a table with the correct textual representation\", function() {\n        return expect(table.find(\"table.pvtTable\").text()).toBe([\"gender\", \"Totals\", \"female\", \"47.8%\", \"male\", \"52.2%\", \"Totals\", \"100.0%\"].join(\"\"));\n      });\n    });\n    describe(\"with rows/cols, custom aggregator, custom renderer with options\", function() {\n      var received_PivotData, received_rendererOptions, table;\n      received_PivotData = null;\n      received_rendererOptions = null;\n      table = $(\"<div>\").pivot(fixtureData, {\n        rows: [\"name\", \"colour\"],\n        cols: [\"trials\", \"successes\"],\n        aggregator: function() {\n          return {\n            count2x: 0,\n            push: function() {\n              return this.count2x += 2;\n            },\n            value: function() {\n              return this.count2x;\n            },\n            format: function(x) {\n              return \"formatted \" + x;\n            }\n          };\n        },\n        renderer: function(a, b) {\n          received_PivotData = a;\n          received_rendererOptions = b;\n          return $(\"<div>\").addClass(b.greeting).text(\"world\");\n        },\n        rendererOptions: {\n          greeting: \"hithere\"\n        }\n      });\n      it(\"renders the custom renderer as per options\", function() {\n        return expect(table.find(\"div.hithere\").length).toBe(1);\n      });\n      return describe(\"its received PivotData object\", function() {\n        return it(\"has a correct grand total value and format for custom aggregator\", function() {\n          var agg, val;\n          agg = received_PivotData.getAggregator([], []);\n          val = agg.value();\n          expect(val).toBe(8);\n          return expect(agg.format(val)).toBe(\"formatted 8\");\n        });\n      });\n    });\n    return describe(\"with ragged input\", function() {\n      var table;\n      table = $(\"<div>\").pivot(raggedFixtureData, {\n        rows: [\"gender\"],\n        cols: [\"age\"]\n      });\n      return it(\"renders a table with the correct textual representation\", function() {\n        return expect(table.find(\"table.pvtTable\").text()).toBe([\"age\", \"12\", \"34\", \"null\", \"Totals\", \"gender\", \"female\", \"1\", \"1\", \"male\", \"1\", \"1\", \"null\", \"1\", \"1\", \"2\", \"Totals\", \"2\", \"1\", \"1\", \"4\"].join(\"\"));\n      });\n    });\n  });\n\n  describe(\"$.pivotUtilities\", function() {\n    describe(\".PivotData()\", function() {\n      var sumOverSumOpts;\n      sumOverSumOpts = {\n        aggregator: $.pivotUtilities.aggregators[\"Sum over Sum\"]([\"a\", \"b\"])\n      };\n      describe(\"with no options\", function() {\n        var aoaInput, pd;\n        aoaInput = [[\"a\", \"b\"], [1, 2], [3, 4]];\n        pd = new $.pivotUtilities.PivotData(aoaInput);\n        return it(\"has the correct grand total value\", function() {\n          return expect(pd.getAggregator([], []).value()).toBe(2);\n        });\n      });\n      describe(\"with array-of-array input\", function() {\n        var aoaInput, pd;\n        aoaInput = [[\"a\", \"b\"], [1, 2], [3, 4]];\n        pd = new $.pivotUtilities.PivotData(aoaInput, sumOverSumOpts);\n        return it(\"has the correct grand total value\", function() {\n          return expect(pd.getAggregator([], []).value()).toBe((1 + 3) / (2 + 4));\n        });\n      });\n      describe(\"with array-of-object input\", function() {\n        var aosInput, pd;\n        aosInput = [\n          {\n            a: 1,\n            b: 2\n          }, {\n            a: 3,\n            b: 4\n          }\n        ];\n        pd = new $.pivotUtilities.PivotData(aosInput, sumOverSumOpts);\n        return it(\"has the correct grand total value\", function() {\n          return expect(pd.getAggregator([], []).value()).toBe((1 + 3) / (2 + 4));\n        });\n      });\n      describe(\"with ragged array-of-object input\", function() {\n        var pd, raggedAosInput;\n        raggedAosInput = [\n          {\n            a: 1\n          }, {\n            b: 4\n          }, {\n            a: 3,\n            b: 2\n          }\n        ];\n        pd = new $.pivotUtilities.PivotData(raggedAosInput, sumOverSumOpts);\n        return it(\"has the correct grand total value\", function() {\n          return expect(pd.getAggregator([], []).value()).toBe((1 + 3) / (2 + 4));\n        });\n      });\n      describe(\"with function input\", function() {\n        var functionInput, pd;\n        functionInput = function(record) {\n          record({\n            a: 1,\n            b: 2\n          });\n          return record({\n            a: 3,\n            b: 4\n          });\n        };\n        pd = new $.pivotUtilities.PivotData(functionInput, sumOverSumOpts);\n        return it(\"has the correct grand total value\", function() {\n          return expect(pd.getAggregator([], []).value()).toBe((1 + 3) / (2 + 4));\n        });\n      });\n      describe(\"with jQuery table element input\", function() {\n        var pd, tableInput;\n        tableInput = $(\"<table>\\n    <thead>\\n        <tr> <th>a</th><th>b</th> </tr>\\n    </thead>\\n    <tbody>\\n        <tr> <td>1</td> <td>2</td> </tr>\\n        <tr> <td>3</td> <td>4</td> </tr>\\n    </tbody>\\n</table>\");\n        pd = new $.pivotUtilities.PivotData(tableInput, sumOverSumOpts);\n        return it(\"has the correct grand total value\", function() {\n          return expect(pd.getAggregator([], []).value()).toBe((1 + 3) / (2 + 4));\n        });\n      });\n      return describe(\"with rows/cols\", function() {\n        var pd;\n        pd = new $.pivotUtilities.PivotData(fixtureData, {\n          rows: [\"name\", \"colour\"],\n          cols: [\"trials\", \"successes\"]\n        });\n        it(\"has correctly-ordered row keys\", function() {\n          return expect(pd.getRowKeys()).toEqual([['Carol', 'yellow'], ['Jane', 'red'], ['John', 'blue'], ['Nick', 'blue']]);\n        });\n        it(\"has correctly-ordered col keys\", function() {\n          return expect(pd.getColKeys()).toEqual([[95, 25], [102, 14], [103, 12], [112, 30]]);\n        });\n        it(\"can be iterated over\", function() {\n          var c, i, j, len, len1, numNotNull, numNull, r, ref, ref1;\n          numNotNull = 0;\n          numNull = 0;\n          ref = pd.getRowKeys();\n          for (i = 0, len = ref.length; i < len; i++) {\n            r = ref[i];\n            ref1 = pd.getColKeys();\n            for (j = 0, len1 = ref1.length; j < len1; j++) {\n              c = ref1[j];\n              if (pd.getAggregator(r, c).value() != null) {\n                numNotNull++;\n              } else {\n                numNull++;\n              }\n            }\n          }\n          expect(numNotNull).toBe(4);\n          return expect(numNull).toBe(12);\n        });\n        it(\"returns matching records\", function() {\n          var records;\n          records = [];\n          pd.forEachMatchingRecord({\n            gender: \"male\"\n          }, function(x) {\n            return records.push(x.name);\n          });\n          return expect(records).toEqual([\"Nick\", \"John\"]);\n        });\n        it(\"has a correct spot-checked aggregator\", function() {\n          var agg, val;\n          agg = pd.getAggregator(['Carol', 'yellow'], [102, 14]);\n          val = agg.value();\n          expect(val).toBe(1);\n          return expect(agg.format(val)).toBe(\"1\");\n        });\n        return it(\"has a correct grand total aggregator\", function() {\n          var agg, val;\n          agg = pd.getAggregator([], []);\n          val = agg.value();\n          expect(val).toBe(4);\n          return expect(agg.format(val)).toBe(\"4\");\n        });\n      });\n    });\n    describe(\".aggregatorTemplates\", function() {\n      var getVal, tpl;\n      getVal = function(aggregator) {\n        var pd;\n        pd = new $.pivotUtilities.PivotData(fixtureData, {\n          aggregator: aggregator\n        });\n        return pd.getAggregator([], []).value();\n      };\n      tpl = $.pivotUtilities.aggregatorTemplates;\n      describe(\".count\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl.count()())).toBe(4);\n        });\n      });\n      describe(\".countUnique\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl.countUnique()(['gender']))).toBe(2);\n        });\n      });\n      describe(\".listUnique\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl.listUnique()(['gender']))).toBe('female,male');\n        });\n      });\n      describe(\".average\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl.average()(['trials']))).toBe(103);\n        });\n      });\n      describe(\".sum\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl.sum()(['trials']))).toBe(412);\n        });\n      });\n      describe(\".min\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl.min()(['trials']))).toBe(95);\n        });\n      });\n      describe(\".max\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl.max()(['trials']))).toBe(112);\n        });\n      });\n      describe(\".first\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl.first()(['name']))).toBe('Carol');\n        });\n      });\n      describe(\".last\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl.last()(['name']))).toBe('Nick');\n        });\n      });\n      describe(\".average\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl.average()(['trials']))).toBe(103);\n        });\n      });\n      describe(\".median\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl.median()(['trials']))).toBe(102.5);\n        });\n      });\n      describe(\".quantile\", function() {\n        return it(\"works\", function() {\n          expect(getVal(tpl.quantile(0)(['trials']))).toBe(95);\n          expect(getVal(tpl.quantile(0.1)(['trials']))).toBe(98.5);\n          expect(getVal(tpl.quantile(0.25)(['trials']))).toBe(98.5);\n          expect(getVal(tpl.quantile(1 / 3)(['trials']))).toBe(102);\n          return expect(getVal(tpl.quantile(1)(['trials']))).toBe(112);\n        });\n      });\n      describe(\".var\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl[\"var\"]()(['trials']))).toBe(48.666666666666686);\n        });\n      });\n      describe(\".stdev\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl.stdev()(['trials']))).toBe(6.976149845485451);\n        });\n      });\n      return describe(\".sumOverSum\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl.sumOverSum()(['successes', 'trials']))).toBe((12 + 25 + 30 + 14) / (95 + 102 + 103 + 112));\n        });\n      });\n    });\n    describe(\".naturalSort()\", function() {\n      var naturalSort, sortedArr;\n      naturalSort = $.pivotUtilities.naturalSort;\n      sortedArr = [null, 0/0, -2e308, '-Infinity', -3, '-3', -2, '-2', -1, '-1', 0, '2e-1', 1, '01', '1', 2, '002', '002e0', '02', '2', '2e-0', 3, 10, '10', '11', '12', '1e2', '112', 2e308, 'Infinity', '1a', '2a', '12a', '20a', 'A', 'A', 'NaN', 'a', 'a', 'a01', 'a012', 'a02', 'a1', 'a2', 'a12', 'a12', 'a21', 'a21', 'b', 'c', 'd', 'null'];\n      return it(\"sorts naturally (null, NaN, numbers & numbery strings, Alphanum for text strings)\", function() {\n        return expect(sortedArr.slice().sort(naturalSort)).toEqual(sortedArr);\n      });\n    });\n    describe(\".sortAs()\", function() {\n      var sortAs;\n      sortAs = $.pivotUtilities.sortAs;\n      it(\"sorts with unknown values sorted at the end\", function() {\n        return expect([5, 2, 3, 4, 1].sort(sortAs([4, 3, 2]))).toEqual([4, 3, 2, 1, 5]);\n      });\n      return it(\"sorts lowercase after uppercase\", function() {\n        return expect([\"Ab\", \"aA\", \"aa\", \"ab\"].sort(sortAs([\"Ab\", \"Aa\"]))).toEqual([\"Ab\", \"ab\", \"aa\", \"aA\"]);\n      });\n    });\n    describe(\".numberFormat()\", function() {\n      var numberFormat;\n      numberFormat = $.pivotUtilities.numberFormat;\n      it(\"formats numbers\", function() {\n        var nf;\n        nf = numberFormat();\n        return expect(nf(1234567.89123456)).toEqual(\"1,234,567.89\");\n      });\n      it(\"formats booleans\", function() {\n        var nf;\n        nf = numberFormat();\n        return expect(nf(true)).toEqual(\"1.00\");\n      });\n      it(\"formats numbers in strings\", function() {\n        var nf;\n        nf = numberFormat();\n        return expect(nf(\"1234567.89123456\")).toEqual(\"1,234,567.89\");\n      });\n      it(\"doesn't formats strings\", function() {\n        var nf;\n        nf = numberFormat();\n        return expect(nf(\"hi there\")).toEqual(\"\");\n      });\n      it(\"doesn't formats objects\", function() {\n        var nf;\n        nf = numberFormat();\n        return expect(nf({\n          a: 1\n        })).toEqual(\"\");\n      });\n      it(\"formats percentages\", function() {\n        var nf;\n        nf = numberFormat({\n          scaler: 100,\n          suffix: \"%\"\n        });\n        return expect(nf(0.12345)).toEqual(\"12.35%\");\n      });\n      it(\"adds separators\", function() {\n        var nf;\n        nf = numberFormat({\n          thousandsSep: \"a\",\n          decimalSep: \"b\"\n        });\n        return expect(nf(1234567.89123456)).toEqual(\"1a234a567b89\");\n      });\n      it(\"adds prefixes and suffixes\", function() {\n        var nf;\n        nf = numberFormat({\n          prefix: \"a\",\n          suffix: \"b\"\n        });\n        return expect(nf(1234567.89123456)).toEqual(\"a1,234,567.89b\");\n      });\n      return it(\"scales and rounds\", function() {\n        var nf;\n        nf = numberFormat({\n          digitsAfterDecimal: 3,\n          scaler: 1000\n        });\n        return expect(nf(1234567.89123456)).toEqual(\"1,234,567,891.235\");\n      });\n    });\n    return describe(\".derivers\", function() {\n      describe(\".dateFormat()\", function() {\n        var df;\n        df = $.pivotUtilities.derivers.dateFormat(\"x\", \"abc % %% %%% %a %y %m %n %d %w %x %H %M %S\", true);\n        it(\"formats date objects\", function() {\n          return expect(df({\n            x: new Date(\"2015-01-02T23:43:11Z\")\n          })).toBe('abc % %% %%% %a 2015 01 Jan 02 Fri 5 23 43 11');\n        });\n        return it(\"formats input parsed by Date.parse()\", function() {\n          expect(df({\n            x: \"2015-01-02T23:43:11Z\"\n          })).toBe('abc % %% %%% %a 2015 01 Jan 02 Fri 5 23 43 11');\n          return expect(df({\n            x: \"bla\"\n          })).toBe('');\n        });\n      });\n      return describe(\".bin()\", function() {\n        var binner;\n        binner = $.pivotUtilities.derivers.bin(\"x\", 10);\n        it(\"bins numbers\", function() {\n          expect(binner({\n            x: 11\n          })).toBe(10);\n          expect(binner({\n            x: 9\n          })).toBe(0);\n          return expect(binner({\n            x: 111\n          })).toBe(110);\n        });\n        it(\"bins booleans\", function() {\n          return expect(binner({\n            x: true\n          })).toBe(0);\n        });\n        it(\"bins negative numbers\", function() {\n          return expect(binner({\n            x: -12\n          })).toBe(-10);\n        });\n        it(\"doesn't bin strings\", function() {\n          return expect(binner({\n            x: \"a\"\n          })).toBeNaN();\n        });\n        return it(\"doesn't bin objects\", function() {\n          return expect(binner({\n            x: {\n              a: 1\n            }\n          })).toBeNaN();\n        });\n      });\n    });\n  });\n\n}).call(this);\n\n//# sourceMappingURL=pivot_spec.js.map\n"]}
\ No newline at end of file
+{"version":3,"sources":["pivot_spec.coffee","pivot_spec.min.js"],"names":["fixtureData","raggedFixtureData","name","colour","age","gender","describe","table","beforeEach","done","$","pivotUI","onRefresh","it","expect","find","length","toBe","val","text","join","data","rows","cols","aggregatorName","vals","rendererName","pivot","aggregators","derivers","ref","sortAs","pivotUtilities","aggregator","filter","record","derivedAttributes","birthyear","dateFormat","trialbins","bin","sorters","attr","received_PivotData","received_rendererOptions","count2x","push","this","value","format","x","renderer","a","b","addClass","greeting","rendererOptions","agg","getAggregator","sumOverSumOpts","aoaInput","pd","PivotData","aosInput","raggedAosInput","functionInput","tableInput","key","ym","getRowKeys","toEqual","getColKeys","c","i","j","len","len1","numNotNull","numNull","r","ref1","records","forEachMatchingRecord","getVal","tpl","aggregatorTemplates","count","countUnique","listUnique","average","sum","min","max","first","last","median","quantile","stdev","sumOverSum","naturalSort","sortedArr","slice","sort","numberFormat","nf","scaler","suffix","thousandsSep","decimalSep","prefix","digitsAfterDecimal","df","Date","binner","toBeNaN","call"],"mappings":"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","file":"pivot_spec.min.js","sourcesContent":["fixtureData = [\n    [\"name\",    \"gender\",   \"colour\",    \"birthday\",     \"trials\",   \"successes\"],\n    [\"Nick\",    \"male\",     \"blue\",      \"1982-11-07\",   103,        12],\n    [\"Jane\",    \"female\",   \"red\",       \"1982-11-08\",   95,         25],\n    [\"John\",    \"male\",     \"blue\",      \"1982-12-08\",   112,        30],\n    [\"Carol\",   \"female\",   \"yellow\",    \"1983-12-08\",   102,        14]\n]\n\nraggedFixtureData = [\n    {name: \"Nick\", \"colour\": \"red\", \"age\": 34}\n    {name: \"Jane\", \"gender\": \"female\"}\n    {name: \"John\", \"gender\": \"male\", \"age\": 12}\n    {name: \"Jim\", \"gender\": null, \"age\": 12}\n]\n\ndescribe \"$.pivotUI()\", ->\n    describe \"with no rows/cols, default count aggregator, default TableRenderer\",  ->\n        table = null\n\n        beforeEach (done) ->\n            table = $(\"<div>\").pivotUI fixtureData, onRefresh: done\n        it \"has all the basic UI elements\", (done) ->\n            expect table.find(\"td.pvtAxisContainer\").length\n            .toBe  3\n            expect table.find(\"td.pvtRendererArea\").length\n            .toBe  1\n            expect table.find(\"td.pvtVals\").length\n            .toBe  1\n            expect table.find(\"select.pvtRenderer\").length\n            .toBe  1\n            expect table.find(\"select.pvtAggregator\").length\n            .toBe  1\n            expect table.find(\"span.pvtAttr\").length\n            .toBe  6\n            done()\n\n        it \"reflects its inputs\", (done) ->\n            expect table.find(\"td.pvtUnused span.pvtAttr\").length\n            .toBe  6\n            expect table.find(\"select.pvtRenderer\").val()\n            .toBe  \"Table\"\n            expect table.find(\"select.pvtAggregator\").val()\n            .toBe  \"Count\"\n            done()\n\n        it \"renders a table\", (done) ->\n            expect table.find(\"table.pvtTable\").length\n            .toBe  1\n            done()\n\n\n        describe \"its renderer output\", ->\n            it \"has the correct type and number of cells\", (done) ->\n                expect table.find(\"th.pvtTotalLabel\").length\n                .toBe  1\n                expect table.find(\"td.pvtGrandTotal\").length\n                .toBe  1\n                done()\n\n            it \"has the correct textual representation\", (done) ->\n                expect table.find(\"table.pvtTable\").text()\n                .toBe [\"Totals\", \"4\"].join(\"\")\n                done()\n\n            it \"has a correct grand total with data value\", (done) ->\n                expect table.find(\"td.pvtGrandTotal\").text()\n                .toBe  \"4\"\n                expect table.find(\"td.pvtGrandTotal\").data(\"value\")\n                .toBe  4\n                done()\n\n    describe \"with rows/cols, sum-over-sum aggregator, Heatmap renderer\",  ->\n        table = null\n\n        beforeEach (done) ->\n            table = $(\"<div>\").pivotUI fixtureData,\n                rows: [\"gender\"], cols: [\"colour\"]\n                aggregatorName: \"Sum over Sum\"\n                vals: [\"successes\", \"trials\"]\n                rendererName: \"Heatmap\"\n                onRefresh: done\n\n        it \"has all the basic UI elements\", (done) ->\n            expect table.find(\"td.pvtAxisContainer\").length\n            .toBe  3\n            expect table.find(\"td.pvtRendererArea\").length\n            .toBe  1\n            expect table.find(\"td.pvtVals\").length\n            .toBe  1\n            expect table.find(\"select.pvtRenderer\").length\n            .toBe  1\n            expect table.find(\"select.pvtAggregator\").length\n            .toBe  1\n            expect table.find(\"span.pvtAttr\").length\n            .toBe  6\n            done()\n\n        it \"reflects its inputs\", (done) ->\n            expect table.find(\"td.pvtUnused span.pvtAttr\").length\n            .toBe  4\n            expect table.find(\"td.pvtRows span.pvtAttr\").length\n            .toBe  1\n            expect table.find(\"td.pvtCols span.pvtAttr\").length\n            .toBe  1\n            expect table.find(\"select.pvtRenderer\").val()\n            .toBe  \"Heatmap\"\n            expect table.find(\"select.pvtAggregator\").val()\n            .toBe  \"Sum over Sum\"\n            done()\n\n        it \"renders a table\", (done) ->\n            expect table.find(\"table.pvtTable\").length\n            .toBe  1\n            done()\n\n        describe \"its renderer output\", ->\n            it \"has the correct type and number of cells\", (done) ->\n                expect table.find(\"th.pvtAxisLabel\").length\n                .toBe  2\n                expect table.find(\"th.pvtRowLabel\").length\n                .toBe  2\n                expect table.find(\"th.pvtColLabel\").length\n                .toBe  3\n                expect table.find(\"th.pvtTotalLabel\").length\n                .toBe  2\n                expect table.find(\"td.pvtVal\").length\n                .toBe  6\n                expect table.find(\"td.pvtTotal\").length\n                .toBe  5\n                expect table.find(\"td.pvtGrandTotal\").length\n                .toBe  1\n                done()\n\n            it \"has the correct textual representation\", (done) ->\n                expect table.find(\"table.pvtTable\").text()\n                .toBe [\n                    \"colour\",   \"blue\", \"red\",  \"yellow\",   \"Totals\",\n                    \"gender\",\n                    \"female\",           \"0.26\", \"0.14\",     \"0.20\",\n                    \"male\",     \"0.20\",                     \"0.20\",\n                    \"Totals\",   \"0.20\", \"0.26\", \"0.14\",     \"0.20\"\n                    ].join(\"\")\n                done()\n\n            it \"has a correct spot-checked cell with data value\", (done) ->\n                expect table.find(\"td.col0.row1\").text()\n                .toBe  \"0.20\"\n                expect table.find(\"td.col0.row1\").data(\"value\")\n                .toBe  (12+30)/(103+112)\n                done()\n\n    describe \"with ragged input\",  ->\n        table = $(\"<div>\").pivotUI raggedFixtureData, rows: [\"gender\"], cols: [\"age\"]\n\n        it \"renders a table with the correct textual representation\", ->\n            expect table.find(\"table.pvtTable\").text()\n            .toBe [\n                \"age\",     \"12\",  \"34\",  \"null\",  \"Totals\"\n                \"gender\",\n                \"female\",                 \"1\",    \"1\"\n                \"male\",    \"1\",                   \"1\"\n                \"null\",    \"1\",    \"1\",           \"2\"\n                \"Totals\",  \"2\",    \"1\",   \"1\",    \"4\"\n                ].join(\"\")\n\ndescribe \"$.pivot()\", ->\n\n    describe \"with no rows/cols, default count aggregator, default TableRenderer\",  ->\n        table = $(\"<div>\").pivot fixtureData\n\n        it \"renders a table\", ->\n            expect table.find(\"table.pvtTable\").length\n            .toBe  1\n\n        describe \"its renderer output\", ->\n\n            it \"has the correct textual representation\", ->\n                expect table.find(\"table.pvtTable\").text()\n                .toBe [\"Totals\", \"4\"].join(\"\")\n\n            it \"has a correct grand total with data value\", ->\n                expect table.find(\"td.pvtGrandTotal\").text()\n                .toBe  \"4\"\n                expect table.find(\"td.pvtGrandTotal\").data(\"value\")\n                .toBe  4\n\n    describe \"with rows/cols, sum aggregator, derivedAttributes, filter and sorters\",  ->\n        {sortAs, derivers, aggregators} = $.pivotUtilities\n        table = $(\"<div>\").pivot fixtureData,\n            rows: [\"gender\"], cols: [\"birthyear\"], aggregator: aggregators[\"Sum\"]([\"trialbins\"])\n            filter: (record) -> record.name != \"Nick\"\n            derivedAttributes:\n                birthyear: derivers.dateFormat \"birthday\", \"%y\"\n                trialbins: derivers.bin \"trials\", 10\n            sorters: (attr) ->\n                if attr == \"gender\" then return sortAs([\"male\", \"female\"])\n\n        it \"renders a table with the correct textual representation\", ->\n            expect table.find(\"table.pvtTable\").text()\n            .toBe [\n                \"birthyear\",    \"1982\",     \"1983\",     \"Totals\"\n                \"gender\",\n                \"male\",         \"110.00\",               \"110.00\"\n                \"female\",       \"90.00\",    \"100.00\",   \"190.00\"\n                \"Totals\",       \"200.00\",   \"100.00\",   \"300.00\"\n                ].join(\"\")\n\n    describe \"with rows/cols, fraction-of aggregator\",  ->\n        {aggregators} = $.pivotUtilities\n        table = $(\"<div>\").pivot fixtureData,\n            rows: [\"gender\"]\n            aggregator: aggregators[\"Sum as Fraction of Total\"]([\"trials\"])\n\n        it \"renders a table with the correct textual representation\", ->\n            expect table.find(\"table.pvtTable\").text()\n            .toBe [\n                \"gender\",  \"Totals\"\n                \"female\",  \"47.8%\"\n                \"male\",    \"52.2%\"\n                \"Totals\",  \"100.0%\"\n                ].join(\"\")\n\n    describe \"with rows/cols, custom aggregator, custom renderer with options\",  ->\n        received_PivotData = null\n        received_rendererOptions = null\n\n        table = $(\"<div>\").pivot fixtureData,\n            rows: [\"name\", \"colour\"], cols: [\"trials\", \"successes\"]\n            aggregator: ->\n                count2x: 0\n                push: -> @count2x +=2\n                value: -> @count2x\n                format: (x) -> \"formatted \" + x\n            renderer: (a,b) ->\n                received_PivotData = a\n                received_rendererOptions = b\n                return $(\"<div>\").addClass(b.greeting).text(\"world\")\n            rendererOptions: {greeting:\"hithere\"}\n\n        it \"renders the custom renderer as per options\", ->\n            expect table.find(\"div.hithere\").length\n            .toBe  1\n\n        describe \"its received PivotData object\", ->\n            it \"has a correct grand total value and format for custom aggregator\", ->\n                agg = received_PivotData.getAggregator([],[])\n                val = agg.value()\n                expect(val).toBe 8\n                expect(agg.format(val)).toBe \"formatted 8\"\n\n\n    describe \"with ragged input\",  ->\n        table = $(\"<div>\").pivot raggedFixtureData, rows: [\"gender\"], cols: [\"age\"]\n\n        it \"renders a table with the correct textual representation\", ->\n            expect table.find(\"table.pvtTable\").text()\n            .toBe [\n                \"age\",     \"12\",  \"34\",  \"null\",  \"Totals\"\n                \"gender\",\n                \"female\",                 \"1\",    \"1\"\n                \"male\",    \"1\",                   \"1\"\n                \"null\",    \"1\",    \"1\",           \"2\"\n                \"Totals\",  \"2\",    \"1\",   \"1\",    \"4\"\n                ].join(\"\")\n\ndescribe \"$.pivotUtilities\", ->\n\n    describe \".PivotData()\", ->\n        sumOverSumOpts =\n            aggregator: $.pivotUtilities.aggregators[\"Sum over Sum\"]([\"a\",\"b\"])\n\n        describe \"with no options\", ->\n            aoaInput =  [ [\"a\",\"b\"], [1,2], [3,4] ]\n            pd = new $.pivotUtilities.PivotData aoaInput\n\n            it \"has the correct grand total value\", ->\n                expect pd.getAggregator([],[]).value()\n                .toBe 2\n\n        describe \"with array-of-array input\", ->\n            aoaInput =  [ [\"a\",\"b\"], [1,2], [3,4] ]\n            pd = new $.pivotUtilities.PivotData aoaInput, sumOverSumOpts\n\n            it \"has the correct grand total value\", ->\n                expect pd.getAggregator([],[]).value()\n                .toBe (1+3)/(2+4)\n\n        describe \"with array-of-object input\", ->\n            aosInput =  [ {a:1, b:2}, {a:3, b:4} ]\n            pd = new $.pivotUtilities.PivotData aosInput, sumOverSumOpts\n\n            it \"has the correct grand total value\", ->\n                expect pd.getAggregator([],[]).value()\n                .toBe (1+3)/(2+4)\n\n        describe \"with ragged array-of-object input\", ->\n            raggedAosInput =  [ {a:1}, {b:4}, {a: 3, b: 2} ]\n            pd = new $.pivotUtilities.PivotData raggedAosInput, sumOverSumOpts\n\n            it \"has the correct grand total value\", ->\n                expect pd.getAggregator([],[]).value()\n                .toBe (1+3)/(2+4)\n\n        describe \"with function input\", ->\n            functionInput = (record) ->\n                record a:1, b:2\n                record a:3, b:4\n            pd = new $.pivotUtilities.PivotData functionInput, sumOverSumOpts\n\n            it \"has the correct grand total value\", ->\n                expect pd.getAggregator([],[]).value()\n                .toBe (1+3)/(2+4)\n\n        describe \"with jQuery table element input\", ->\n            tableInput = $ \"\"\"\n                <table>\n                    <thead>\n                        <tr> <th>a</th><th>b</th> </tr>\n                    </thead>\n                    <tbody>\n                        <tr> <td>1</td> <td>2</td> </tr>\n                        <tr> <td>3</td> <td>4</td> </tr>\n                    </tbody>\n                </table>\n                \"\"\"\n            pd = new $.pivotUtilities.PivotData tableInput, sumOverSumOpts\n\n            it \"has the correct grand total value\", ->\n                expect pd.getAggregator([],[]).value()\n                .toBe (1+3)/(2+4)\n\n        describe \"with a0-a00 input\", ->\n            aoaInput =  [\n                {key: 'a0', ym: '2020-01'},\n                {key: 'a0', ym: '2020-02'},\n                {key: 'a00', ym: '2020-01'},\n                {key: 'a00', ym: '2020-02'}\n            ]\n            pd = new $.pivotUtilities.PivotData aoaInput, rows: [\"key\", \"ym\"], cols: []\n\n            it \"has correctly-ordered row keys\", ->\n                expect pd.getRowKeys()\n                .toEqual [[\"a0\",\"2020-01\"],[\"a0\",\"2020-02\"],[\"a00\",\"2020-01\"],[\"a00\",\"2020-02\"]]\n\n        describe \"with rows/cols\", ->\n            pd = new $.pivotUtilities.PivotData fixtureData,\n                rows: [\"name\", \"colour\"],\n                cols: [\"trials\", \"successes\"]\n\n            it \"has correctly-ordered row keys\", ->\n                expect pd.getRowKeys()\n                .toEqual [ [ 'Carol', 'yellow' ], [ 'Jane', 'red' ], [ 'John', 'blue' ], [ 'Nick', 'blue' ] ]\n\n            it \"has correctly-ordered col keys\", ->\n                expect pd.getColKeys()\n                .toEqual [ [ 95, 25 ], [ 102, 14 ], [ 103, 12 ], [ 112, 30 ] ]\n\n            it \"can be iterated over\", ->\n                numNotNull = 0\n                numNull = 0\n                for r in pd.getRowKeys()\n                    for c in pd.getColKeys()\n                        if pd.getAggregator(r, c).value()?\n                            numNotNull++\n                        else\n                            numNull++\n                expect numNotNull\n                .toBe 4\n                expect numNull\n                .toBe 12\n\n            it \"returns matching records\", ->\n                records = []\n                pd.forEachMatchingRecord gender: \"male\", (x) -> records.push(x.name)\n                expect records\n                .toEqual [\"Nick\", \"John\"]\n\n            it \"has a correct spot-checked aggregator\", ->\n                agg = pd.getAggregator([ 'Carol', 'yellow' ],[ 102, 14 ])\n                val = agg.value()\n                expect(val).toBe 1\n                expect(agg.format(val)).toBe \"1\"\n\n            it \"has a correct grand total aggregator\", ->\n                agg = pd.getAggregator([],[])\n                val = agg.value()\n                expect(val).toBe 4\n                expect(agg.format(val)).toBe \"4\"\n\n    describe \".aggregatorTemplates\", ->\n\n        getVal = (aggregator) ->\n            pd = new $.pivotUtilities.PivotData(fixtureData, {aggregator})\n            return pd.getAggregator([],[]).value()\n        tpl = $.pivotUtilities.aggregatorTemplates\n\n        describe \".count\", ->\n            it \"works\", ->\n                expect getVal(tpl.count()())\n                .toBe 4\n\n        describe \".countUnique\", ->\n            it \"works\", ->\n                expect getVal(tpl.countUnique()(['gender']))\n                .toBe 2\n\n        describe \".listUnique\", ->\n            it \"works\", ->\n                expect getVal(tpl.listUnique()(['gender']))\n                .toBe 'female,male'\n\n        describe \".average\", ->\n            it \"works\", ->\n                expect getVal(tpl.average()(['trials']))\n                .toBe 103\n\n        describe \".sum\", ->\n            it \"works\", ->\n                expect getVal(tpl.sum()(['trials']))\n                .toBe 412\n\n        describe \".min\", ->\n            it \"works\", ->\n                expect getVal(tpl.min()(['trials']))\n                .toBe 95\n\n        describe \".max\", ->\n            it \"works\", ->\n                expect getVal(tpl.max()(['trials']))\n                .toBe 112\n\n        describe \".first\", ->\n            it \"works\", ->\n                expect getVal(tpl.first()(['name']))\n                .toBe 'Carol'\n\n        describe \".last\", ->\n            it \"works\", ->\n                expect getVal(tpl.last()(['name']))\n                .toBe 'Nick'\n\n        describe \".average\", ->\n            it \"works\", ->\n                expect getVal(tpl.average()(['trials']))\n                .toBe 103\n\n        describe \".median\", ->\n            it \"works\", ->\n                expect getVal(tpl.median()(['trials']))\n                .toBe 102.5\n\n        describe \".quantile\", ->\n            it \"works\", ->\n                expect getVal(tpl.quantile(0)(['trials']))\n                .toBe 95\n                expect getVal(tpl.quantile(0.1)(['trials']))\n                .toBe 98.5\n                expect getVal(tpl.quantile(0.25)(['trials']))\n                .toBe 98.5\n                expect getVal(tpl.quantile(1/3)(['trials']))\n                .toBe 102\n                expect getVal(tpl.quantile(1)(['trials']))\n                .toBe 112\n\n        describe \".var\", ->\n            it \"works\", ->\n                expect getVal(tpl.var()(['trials']))\n                .toBe 48.666666666666686\n\n        describe \".stdev\", ->\n            it \"works\", ->\n                expect getVal(tpl.stdev()(['trials']))\n                .toBe 6.976149845485451\n\n        describe \".sumOverSum\", ->\n            it \"works\", ->\n                expect getVal(tpl.sumOverSum()(['successes', 'trials']))\n                .toBe (12+25+30+14)/(95+102+103+112)\n\n    describe \".naturalSort()\", ->\n        naturalSort = $.pivotUtilities.naturalSort\n\n        sortedArr = [\n            null, NaN,\n            -Infinity, '-Infinity', -3, '-3', -2, '-2', -1, '-1',\n            0, '2e-1', 1, '01', '1', 2, '002', '002e0', '02', '2', '2e-0',\n            3, 10, '10', '11', '12', '1e2', '112', Infinity, 'Infinity',\n            '1a', '2a','12a','20a',\n            'A', 'A', 'NaN', 'a', 'a',\n            'a01', 'a012', 'a02', 'a1', 'a2', 'a12', 'a12', 'a21', 'a21',\n            'b', 'c', 'd', 'null'\n        ]\n\n        it \"sorts naturally (null, NaN, numbers & numbery strings, Alphanum for text strings)\", ->\n            expect sortedArr.slice().sort(naturalSort)\n            .toEqual sortedArr\n\n    describe \".sortAs()\", ->\n        sortAs = $.pivotUtilities.sortAs\n\n        it \"sorts with unknown values sorted at the end\", ->\n            expect [5,2,3,4,1].sort sortAs([4,3,2])\n            .toEqual [4,3,2,1,5]\n\n        it \"sorts lowercase after uppercase\", ->\n            expect [\"Ab\",\"aA\",\"aa\",\"ab\"].sort sortAs([\"Ab\",\"Aa\"])\n            .toEqual [\"Ab\",\"ab\",\"aa\",\"aA\"]\n\n    describe \".numberFormat()\", ->\n        numberFormat = $.pivotUtilities.numberFormat\n\n        it \"formats numbers\", ->\n            nf = numberFormat()\n            expect nf 1234567.89123456\n            .toEqual \"1,234,567.89\"\n\n        it \"formats booleans\", ->\n            nf = numberFormat()\n            expect nf true\n            .toEqual \"1.00\"\n\n        it \"formats numbers in strings\", ->\n            nf = numberFormat()\n            expect nf \"1234567.89123456\"\n            .toEqual \"1,234,567.89\"\n\n        it \"doesn't formats strings\", ->\n            nf = numberFormat()\n            expect nf \"hi there\"\n            .toEqual \"\"\n\n        it \"doesn't formats objects\", ->\n            nf = numberFormat()\n            expect nf {a:1}\n            .toEqual \"\"\n\n        it \"formats percentages\", ->\n            nf = numberFormat(scaler: 100, suffix: \"%\")\n            expect nf 0.12345\n            .toEqual \"12.35%\"\n\n        it \"adds separators\", ->\n            nf = numberFormat(thousandsSep: \"a\", decimalSep: \"b\")\n            expect nf 1234567.89123456\n            .toEqual \"1a234a567b89\"\n\n        it \"adds prefixes and suffixes\", ->\n            nf = numberFormat(prefix: \"a\", suffix: \"b\")\n            expect nf 1234567.89123456\n            .toEqual \"a1,234,567.89b\"\n\n        it \"scales and rounds\", ->\n            nf = numberFormat(digitsAfterDecimal: 3, scaler: 1000)\n            expect nf 1234567.89123456\n            .toEqual \"1,234,567,891.235\"\n\n    describe \".derivers\", ->\n        describe \".dateFormat()\", ->\n            df = $.pivotUtilities.derivers.dateFormat \"x\", \"abc % %% %%% %a %y %m %n %d %w %x %H %M %S\", true\n\n            it \"formats date objects\", ->\n                expect df {x: new Date(\"2015-01-02T23:43:11Z\")}\n                .toBe 'abc % %% %%% %a 2015 01 Jan 02 Fri 5 23 43 11'\n\n            it \"formats input parsed by Date.parse()\", ->\n                expect df {x: \"2015-01-02T23:43:11Z\"}\n                .toBe 'abc % %% %%% %a 2015 01 Jan 02 Fri 5 23 43 11'\n\n                expect df {x: \"bla\"}\n                .toBe ''\n\n        describe \".bin()\", ->\n            binner = $.pivotUtilities.derivers.bin \"x\", 10\n\n            it \"bins numbers\", ->\n                expect binner {x: 11}\n                .toBe 10\n\n                expect binner {x: 9}\n                .toBe 0\n\n                expect binner {x: 111}\n                .toBe 110\n\n            it \"bins booleans\", ->\n                expect binner {x: true}\n                .toBe 0\n\n            it \"bins negative numbers\", ->\n                expect binner {x: -12}\n                .toBe -10\n\n            it \"doesn't bin strings\", ->\n                expect binner {x: \"a\"}\n                .toBeNaN()\n\n            it \"doesn't bin objects\", ->\n                expect binner {x: {a:1}}\n                .toBeNaN()\n","(function() {\n  var fixtureData, raggedFixtureData;\n\n  fixtureData = [[\"name\", \"gender\", \"colour\", \"birthday\", \"trials\", \"successes\"], [\"Nick\", \"male\", \"blue\", \"1982-11-07\", 103, 12], [\"Jane\", \"female\", \"red\", \"1982-11-08\", 95, 25], [\"John\", \"male\", \"blue\", \"1982-12-08\", 112, 30], [\"Carol\", \"female\", \"yellow\", \"1983-12-08\", 102, 14]];\n\n  raggedFixtureData = [\n    {\n      name: \"Nick\",\n      \"colour\": \"red\",\n      \"age\": 34\n    }, {\n      name: \"Jane\",\n      \"gender\": \"female\"\n    }, {\n      name: \"John\",\n      \"gender\": \"male\",\n      \"age\": 12\n    }, {\n      name: \"Jim\",\n      \"gender\": null,\n      \"age\": 12\n    }\n  ];\n\n  describe(\"$.pivotUI()\", function() {\n    describe(\"with no rows/cols, default count aggregator, default TableRenderer\", function() {\n      var table;\n      table = null;\n      beforeEach(function(done) {\n        return table = $(\"<div>\").pivotUI(fixtureData, {\n          onRefresh: done\n        });\n      });\n      it(\"has all the basic UI elements\", function(done) {\n        expect(table.find(\"td.pvtAxisContainer\").length).toBe(3);\n        expect(table.find(\"td.pvtRendererArea\").length).toBe(1);\n        expect(table.find(\"td.pvtVals\").length).toBe(1);\n        expect(table.find(\"select.pvtRenderer\").length).toBe(1);\n        expect(table.find(\"select.pvtAggregator\").length).toBe(1);\n        expect(table.find(\"span.pvtAttr\").length).toBe(6);\n        return done();\n      });\n      it(\"reflects its inputs\", function(done) {\n        expect(table.find(\"td.pvtUnused span.pvtAttr\").length).toBe(6);\n        expect(table.find(\"select.pvtRenderer\").val()).toBe(\"Table\");\n        expect(table.find(\"select.pvtAggregator\").val()).toBe(\"Count\");\n        return done();\n      });\n      it(\"renders a table\", function(done) {\n        expect(table.find(\"table.pvtTable\").length).toBe(1);\n        return done();\n      });\n      return describe(\"its renderer output\", function() {\n        it(\"has the correct type and number of cells\", function(done) {\n          expect(table.find(\"th.pvtTotalLabel\").length).toBe(1);\n          expect(table.find(\"td.pvtGrandTotal\").length).toBe(1);\n          return done();\n        });\n        it(\"has the correct textual representation\", function(done) {\n          expect(table.find(\"table.pvtTable\").text()).toBe([\"Totals\", \"4\"].join(\"\"));\n          return done();\n        });\n        return it(\"has a correct grand total with data value\", function(done) {\n          expect(table.find(\"td.pvtGrandTotal\").text()).toBe(\"4\");\n          expect(table.find(\"td.pvtGrandTotal\").data(\"value\")).toBe(4);\n          return done();\n        });\n      });\n    });\n    describe(\"with rows/cols, sum-over-sum aggregator, Heatmap renderer\", function() {\n      var table;\n      table = null;\n      beforeEach(function(done) {\n        return table = $(\"<div>\").pivotUI(fixtureData, {\n          rows: [\"gender\"],\n          cols: [\"colour\"],\n          aggregatorName: \"Sum over Sum\",\n          vals: [\"successes\", \"trials\"],\n          rendererName: \"Heatmap\",\n          onRefresh: done\n        });\n      });\n      it(\"has all the basic UI elements\", function(done) {\n        expect(table.find(\"td.pvtAxisContainer\").length).toBe(3);\n        expect(table.find(\"td.pvtRendererArea\").length).toBe(1);\n        expect(table.find(\"td.pvtVals\").length).toBe(1);\n        expect(table.find(\"select.pvtRenderer\").length).toBe(1);\n        expect(table.find(\"select.pvtAggregator\").length).toBe(1);\n        expect(table.find(\"span.pvtAttr\").length).toBe(6);\n        return done();\n      });\n      it(\"reflects its inputs\", function(done) {\n        expect(table.find(\"td.pvtUnused span.pvtAttr\").length).toBe(4);\n        expect(table.find(\"td.pvtRows span.pvtAttr\").length).toBe(1);\n        expect(table.find(\"td.pvtCols span.pvtAttr\").length).toBe(1);\n        expect(table.find(\"select.pvtRenderer\").val()).toBe(\"Heatmap\");\n        expect(table.find(\"select.pvtAggregator\").val()).toBe(\"Sum over Sum\");\n        return done();\n      });\n      it(\"renders a table\", function(done) {\n        expect(table.find(\"table.pvtTable\").length).toBe(1);\n        return done();\n      });\n      return describe(\"its renderer output\", function() {\n        it(\"has the correct type and number of cells\", function(done) {\n          expect(table.find(\"th.pvtAxisLabel\").length).toBe(2);\n          expect(table.find(\"th.pvtRowLabel\").length).toBe(2);\n          expect(table.find(\"th.pvtColLabel\").length).toBe(3);\n          expect(table.find(\"th.pvtTotalLabel\").length).toBe(2);\n          expect(table.find(\"td.pvtVal\").length).toBe(6);\n          expect(table.find(\"td.pvtTotal\").length).toBe(5);\n          expect(table.find(\"td.pvtGrandTotal\").length).toBe(1);\n          return done();\n        });\n        it(\"has the correct textual representation\", function(done) {\n          expect(table.find(\"table.pvtTable\").text()).toBe([\"colour\", \"blue\", \"red\", \"yellow\", \"Totals\", \"gender\", \"female\", \"0.26\", \"0.14\", \"0.20\", \"male\", \"0.20\", \"0.20\", \"Totals\", \"0.20\", \"0.26\", \"0.14\", \"0.20\"].join(\"\"));\n          return done();\n        });\n        return it(\"has a correct spot-checked cell with data value\", function(done) {\n          expect(table.find(\"td.col0.row1\").text()).toBe(\"0.20\");\n          expect(table.find(\"td.col0.row1\").data(\"value\")).toBe((12 + 30) / (103 + 112));\n          return done();\n        });\n      });\n    });\n    return describe(\"with ragged input\", function() {\n      var table;\n      table = $(\"<div>\").pivotUI(raggedFixtureData, {\n        rows: [\"gender\"],\n        cols: [\"age\"]\n      });\n      return it(\"renders a table with the correct textual representation\", function() {\n        return expect(table.find(\"table.pvtTable\").text()).toBe([\"age\", \"12\", \"34\", \"null\", \"Totals\", \"gender\", \"female\", \"1\", \"1\", \"male\", \"1\", \"1\", \"null\", \"1\", \"1\", \"2\", \"Totals\", \"2\", \"1\", \"1\", \"4\"].join(\"\"));\n      });\n    });\n  });\n\n  describe(\"$.pivot()\", function() {\n    describe(\"with no rows/cols, default count aggregator, default TableRenderer\", function() {\n      var table;\n      table = $(\"<div>\").pivot(fixtureData);\n      it(\"renders a table\", function() {\n        return expect(table.find(\"table.pvtTable\").length).toBe(1);\n      });\n      return describe(\"its renderer output\", function() {\n        it(\"has the correct textual representation\", function() {\n          return expect(table.find(\"table.pvtTable\").text()).toBe([\"Totals\", \"4\"].join(\"\"));\n        });\n        return it(\"has a correct grand total with data value\", function() {\n          expect(table.find(\"td.pvtGrandTotal\").text()).toBe(\"4\");\n          return expect(table.find(\"td.pvtGrandTotal\").data(\"value\")).toBe(4);\n        });\n      });\n    });\n    describe(\"with rows/cols, sum aggregator, derivedAttributes, filter and sorters\", function() {\n      var aggregators, derivers, ref, sortAs, table;\n      ref = $.pivotUtilities, sortAs = ref.sortAs, derivers = ref.derivers, aggregators = ref.aggregators;\n      table = $(\"<div>\").pivot(fixtureData, {\n        rows: [\"gender\"],\n        cols: [\"birthyear\"],\n        aggregator: aggregators[\"Sum\"]([\"trialbins\"]),\n        filter: function(record) {\n          return record.name !== \"Nick\";\n        },\n        derivedAttributes: {\n          birthyear: derivers.dateFormat(\"birthday\", \"%y\"),\n          trialbins: derivers.bin(\"trials\", 10)\n        },\n        sorters: function(attr) {\n          if (attr === \"gender\") {\n            return sortAs([\"male\", \"female\"]);\n          }\n        }\n      });\n      return it(\"renders a table with the correct textual representation\", function() {\n        return expect(table.find(\"table.pvtTable\").text()).toBe([\"birthyear\", \"1982\", \"1983\", \"Totals\", \"gender\", \"male\", \"110.00\", \"110.00\", \"female\", \"90.00\", \"100.00\", \"190.00\", \"Totals\", \"200.00\", \"100.00\", \"300.00\"].join(\"\"));\n      });\n    });\n    describe(\"with rows/cols, fraction-of aggregator\", function() {\n      var aggregators, table;\n      aggregators = $.pivotUtilities.aggregators;\n      table = $(\"<div>\").pivot(fixtureData, {\n        rows: [\"gender\"],\n        aggregator: aggregators[\"Sum as Fraction of Total\"]([\"trials\"])\n      });\n      return it(\"renders a table with the correct textual representation\", function() {\n        return expect(table.find(\"table.pvtTable\").text()).toBe([\"gender\", \"Totals\", \"female\", \"47.8%\", \"male\", \"52.2%\", \"Totals\", \"100.0%\"].join(\"\"));\n      });\n    });\n    describe(\"with rows/cols, custom aggregator, custom renderer with options\", function() {\n      var received_PivotData, received_rendererOptions, table;\n      received_PivotData = null;\n      received_rendererOptions = null;\n      table = $(\"<div>\").pivot(fixtureData, {\n        rows: [\"name\", \"colour\"],\n        cols: [\"trials\", \"successes\"],\n        aggregator: function() {\n          return {\n            count2x: 0,\n            push: function() {\n              return this.count2x += 2;\n            },\n            value: function() {\n              return this.count2x;\n            },\n            format: function(x) {\n              return \"formatted \" + x;\n            }\n          };\n        },\n        renderer: function(a, b) {\n          received_PivotData = a;\n          received_rendererOptions = b;\n          return $(\"<div>\").addClass(b.greeting).text(\"world\");\n        },\n        rendererOptions: {\n          greeting: \"hithere\"\n        }\n      });\n      it(\"renders the custom renderer as per options\", function() {\n        return expect(table.find(\"div.hithere\").length).toBe(1);\n      });\n      return describe(\"its received PivotData object\", function() {\n        return it(\"has a correct grand total value and format for custom aggregator\", function() {\n          var agg, val;\n          agg = received_PivotData.getAggregator([], []);\n          val = agg.value();\n          expect(val).toBe(8);\n          return expect(agg.format(val)).toBe(\"formatted 8\");\n        });\n      });\n    });\n    return describe(\"with ragged input\", function() {\n      var table;\n      table = $(\"<div>\").pivot(raggedFixtureData, {\n        rows: [\"gender\"],\n        cols: [\"age\"]\n      });\n      return it(\"renders a table with the correct textual representation\", function() {\n        return expect(table.find(\"table.pvtTable\").text()).toBe([\"age\", \"12\", \"34\", \"null\", \"Totals\", \"gender\", \"female\", \"1\", \"1\", \"male\", \"1\", \"1\", \"null\", \"1\", \"1\", \"2\", \"Totals\", \"2\", \"1\", \"1\", \"4\"].join(\"\"));\n      });\n    });\n  });\n\n  describe(\"$.pivotUtilities\", function() {\n    describe(\".PivotData()\", function() {\n      var sumOverSumOpts;\n      sumOverSumOpts = {\n        aggregator: $.pivotUtilities.aggregators[\"Sum over Sum\"]([\"a\", \"b\"])\n      };\n      describe(\"with no options\", function() {\n        var aoaInput, pd;\n        aoaInput = [[\"a\", \"b\"], [1, 2], [3, 4]];\n        pd = new $.pivotUtilities.PivotData(aoaInput);\n        return it(\"has the correct grand total value\", function() {\n          return expect(pd.getAggregator([], []).value()).toBe(2);\n        });\n      });\n      describe(\"with array-of-array input\", function() {\n        var aoaInput, pd;\n        aoaInput = [[\"a\", \"b\"], [1, 2], [3, 4]];\n        pd = new $.pivotUtilities.PivotData(aoaInput, sumOverSumOpts);\n        return it(\"has the correct grand total value\", function() {\n          return expect(pd.getAggregator([], []).value()).toBe((1 + 3) / (2 + 4));\n        });\n      });\n      describe(\"with array-of-object input\", function() {\n        var aosInput, pd;\n        aosInput = [\n          {\n            a: 1,\n            b: 2\n          }, {\n            a: 3,\n            b: 4\n          }\n        ];\n        pd = new $.pivotUtilities.PivotData(aosInput, sumOverSumOpts);\n        return it(\"has the correct grand total value\", function() {\n          return expect(pd.getAggregator([], []).value()).toBe((1 + 3) / (2 + 4));\n        });\n      });\n      describe(\"with ragged array-of-object input\", function() {\n        var pd, raggedAosInput;\n        raggedAosInput = [\n          {\n            a: 1\n          }, {\n            b: 4\n          }, {\n            a: 3,\n            b: 2\n          }\n        ];\n        pd = new $.pivotUtilities.PivotData(raggedAosInput, sumOverSumOpts);\n        return it(\"has the correct grand total value\", function() {\n          return expect(pd.getAggregator([], []).value()).toBe((1 + 3) / (2 + 4));\n        });\n      });\n      describe(\"with function input\", function() {\n        var functionInput, pd;\n        functionInput = function(record) {\n          record({\n            a: 1,\n            b: 2\n          });\n          return record({\n            a: 3,\n            b: 4\n          });\n        };\n        pd = new $.pivotUtilities.PivotData(functionInput, sumOverSumOpts);\n        return it(\"has the correct grand total value\", function() {\n          return expect(pd.getAggregator([], []).value()).toBe((1 + 3) / (2 + 4));\n        });\n      });\n      describe(\"with jQuery table element input\", function() {\n        var pd, tableInput;\n        tableInput = $(\"<table>\\n    <thead>\\n        <tr> <th>a</th><th>b</th> </tr>\\n    </thead>\\n    <tbody>\\n        <tr> <td>1</td> <td>2</td> </tr>\\n        <tr> <td>3</td> <td>4</td> </tr>\\n    </tbody>\\n</table>\");\n        pd = new $.pivotUtilities.PivotData(tableInput, sumOverSumOpts);\n        return it(\"has the correct grand total value\", function() {\n          return expect(pd.getAggregator([], []).value()).toBe((1 + 3) / (2 + 4));\n        });\n      });\n      describe(\"with a0-a00 input\", function() {\n        var aoaInput, pd;\n        aoaInput = [\n          {\n            key: 'a0',\n            ym: '2020-01'\n          }, {\n            key: 'a0',\n            ym: '2020-02'\n          }, {\n            key: 'a00',\n            ym: '2020-01'\n          }, {\n            key: 'a00',\n            ym: '2020-02'\n          }\n        ];\n        pd = new $.pivotUtilities.PivotData(aoaInput, {\n          rows: [\"key\", \"ym\"],\n          cols: []\n        });\n        return it(\"has correctly-ordered row keys\", function() {\n          return expect(pd.getRowKeys()).toEqual([[\"a0\", \"2020-01\"], [\"a0\", \"2020-02\"], [\"a00\", \"2020-01\"], [\"a00\", \"2020-02\"]]);\n        });\n      });\n      return describe(\"with rows/cols\", function() {\n        var pd;\n        pd = new $.pivotUtilities.PivotData(fixtureData, {\n          rows: [\"name\", \"colour\"],\n          cols: [\"trials\", \"successes\"]\n        });\n        it(\"has correctly-ordered row keys\", function() {\n          return expect(pd.getRowKeys()).toEqual([['Carol', 'yellow'], ['Jane', 'red'], ['John', 'blue'], ['Nick', 'blue']]);\n        });\n        it(\"has correctly-ordered col keys\", function() {\n          return expect(pd.getColKeys()).toEqual([[95, 25], [102, 14], [103, 12], [112, 30]]);\n        });\n        it(\"can be iterated over\", function() {\n          var c, i, j, len, len1, numNotNull, numNull, r, ref, ref1;\n          numNotNull = 0;\n          numNull = 0;\n          ref = pd.getRowKeys();\n          for (i = 0, len = ref.length; i < len; i++) {\n            r = ref[i];\n            ref1 = pd.getColKeys();\n            for (j = 0, len1 = ref1.length; j < len1; j++) {\n              c = ref1[j];\n              if (pd.getAggregator(r, c).value() != null) {\n                numNotNull++;\n              } else {\n                numNull++;\n              }\n            }\n          }\n          expect(numNotNull).toBe(4);\n          return expect(numNull).toBe(12);\n        });\n        it(\"returns matching records\", function() {\n          var records;\n          records = [];\n          pd.forEachMatchingRecord({\n            gender: \"male\"\n          }, function(x) {\n            return records.push(x.name);\n          });\n          return expect(records).toEqual([\"Nick\", \"John\"]);\n        });\n        it(\"has a correct spot-checked aggregator\", function() {\n          var agg, val;\n          agg = pd.getAggregator(['Carol', 'yellow'], [102, 14]);\n          val = agg.value();\n          expect(val).toBe(1);\n          return expect(agg.format(val)).toBe(\"1\");\n        });\n        return it(\"has a correct grand total aggregator\", function() {\n          var agg, val;\n          agg = pd.getAggregator([], []);\n          val = agg.value();\n          expect(val).toBe(4);\n          return expect(agg.format(val)).toBe(\"4\");\n        });\n      });\n    });\n    describe(\".aggregatorTemplates\", function() {\n      var getVal, tpl;\n      getVal = function(aggregator) {\n        var pd;\n        pd = new $.pivotUtilities.PivotData(fixtureData, {\n          aggregator: aggregator\n        });\n        return pd.getAggregator([], []).value();\n      };\n      tpl = $.pivotUtilities.aggregatorTemplates;\n      describe(\".count\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl.count()())).toBe(4);\n        });\n      });\n      describe(\".countUnique\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl.countUnique()(['gender']))).toBe(2);\n        });\n      });\n      describe(\".listUnique\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl.listUnique()(['gender']))).toBe('female,male');\n        });\n      });\n      describe(\".average\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl.average()(['trials']))).toBe(103);\n        });\n      });\n      describe(\".sum\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl.sum()(['trials']))).toBe(412);\n        });\n      });\n      describe(\".min\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl.min()(['trials']))).toBe(95);\n        });\n      });\n      describe(\".max\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl.max()(['trials']))).toBe(112);\n        });\n      });\n      describe(\".first\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl.first()(['name']))).toBe('Carol');\n        });\n      });\n      describe(\".last\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl.last()(['name']))).toBe('Nick');\n        });\n      });\n      describe(\".average\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl.average()(['trials']))).toBe(103);\n        });\n      });\n      describe(\".median\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl.median()(['trials']))).toBe(102.5);\n        });\n      });\n      describe(\".quantile\", function() {\n        return it(\"works\", function() {\n          expect(getVal(tpl.quantile(0)(['trials']))).toBe(95);\n          expect(getVal(tpl.quantile(0.1)(['trials']))).toBe(98.5);\n          expect(getVal(tpl.quantile(0.25)(['trials']))).toBe(98.5);\n          expect(getVal(tpl.quantile(1 / 3)(['trials']))).toBe(102);\n          return expect(getVal(tpl.quantile(1)(['trials']))).toBe(112);\n        });\n      });\n      describe(\".var\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl[\"var\"]()(['trials']))).toBe(48.666666666666686);\n        });\n      });\n      describe(\".stdev\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl.stdev()(['trials']))).toBe(6.976149845485451);\n        });\n      });\n      return describe(\".sumOverSum\", function() {\n        return it(\"works\", function() {\n          return expect(getVal(tpl.sumOverSum()(['successes', 'trials']))).toBe((12 + 25 + 30 + 14) / (95 + 102 + 103 + 112));\n        });\n      });\n    });\n    describe(\".naturalSort()\", function() {\n      var naturalSort, sortedArr;\n      naturalSort = $.pivotUtilities.naturalSort;\n      sortedArr = [null, 0/0, -2e308, '-Infinity', -3, '-3', -2, '-2', -1, '-1', 0, '2e-1', 1, '01', '1', 2, '002', '002e0', '02', '2', '2e-0', 3, 10, '10', '11', '12', '1e2', '112', 2e308, 'Infinity', '1a', '2a', '12a', '20a', 'A', 'A', 'NaN', 'a', 'a', 'a01', 'a012', 'a02', 'a1', 'a2', 'a12', 'a12', 'a21', 'a21', 'b', 'c', 'd', 'null'];\n      return it(\"sorts naturally (null, NaN, numbers & numbery strings, Alphanum for text strings)\", function() {\n        return expect(sortedArr.slice().sort(naturalSort)).toEqual(sortedArr);\n      });\n    });\n    describe(\".sortAs()\", function() {\n      var sortAs;\n      sortAs = $.pivotUtilities.sortAs;\n      it(\"sorts with unknown values sorted at the end\", function() {\n        return expect([5, 2, 3, 4, 1].sort(sortAs([4, 3, 2]))).toEqual([4, 3, 2, 1, 5]);\n      });\n      return it(\"sorts lowercase after uppercase\", function() {\n        return expect([\"Ab\", \"aA\", \"aa\", \"ab\"].sort(sortAs([\"Ab\", \"Aa\"]))).toEqual([\"Ab\", \"ab\", \"aa\", \"aA\"]);\n      });\n    });\n    describe(\".numberFormat()\", function() {\n      var numberFormat;\n      numberFormat = $.pivotUtilities.numberFormat;\n      it(\"formats numbers\", function() {\n        var nf;\n        nf = numberFormat();\n        return expect(nf(1234567.89123456)).toEqual(\"1,234,567.89\");\n      });\n      it(\"formats booleans\", function() {\n        var nf;\n        nf = numberFormat();\n        return expect(nf(true)).toEqual(\"1.00\");\n      });\n      it(\"formats numbers in strings\", function() {\n        var nf;\n        nf = numberFormat();\n        return expect(nf(\"1234567.89123456\")).toEqual(\"1,234,567.89\");\n      });\n      it(\"doesn't formats strings\", function() {\n        var nf;\n        nf = numberFormat();\n        return expect(nf(\"hi there\")).toEqual(\"\");\n      });\n      it(\"doesn't formats objects\", function() {\n        var nf;\n        nf = numberFormat();\n        return expect(nf({\n          a: 1\n        })).toEqual(\"\");\n      });\n      it(\"formats percentages\", function() {\n        var nf;\n        nf = numberFormat({\n          scaler: 100,\n          suffix: \"%\"\n        });\n        return expect(nf(0.12345)).toEqual(\"12.35%\");\n      });\n      it(\"adds separators\", function() {\n        var nf;\n        nf = numberFormat({\n          thousandsSep: \"a\",\n          decimalSep: \"b\"\n        });\n        return expect(nf(1234567.89123456)).toEqual(\"1a234a567b89\");\n      });\n      it(\"adds prefixes and suffixes\", function() {\n        var nf;\n        nf = numberFormat({\n          prefix: \"a\",\n          suffix: \"b\"\n        });\n        return expect(nf(1234567.89123456)).toEqual(\"a1,234,567.89b\");\n      });\n      return it(\"scales and rounds\", function() {\n        var nf;\n        nf = numberFormat({\n          digitsAfterDecimal: 3,\n          scaler: 1000\n        });\n        return expect(nf(1234567.89123456)).toEqual(\"1,234,567,891.235\");\n      });\n    });\n    return describe(\".derivers\", function() {\n      describe(\".dateFormat()\", function() {\n        var df;\n        df = $.pivotUtilities.derivers.dateFormat(\"x\", \"abc % %% %%% %a %y %m %n %d %w %x %H %M %S\", true);\n        it(\"formats date objects\", function() {\n          return expect(df({\n            x: new Date(\"2015-01-02T23:43:11Z\")\n          })).toBe('abc % %% %%% %a 2015 01 Jan 02 Fri 5 23 43 11');\n        });\n        return it(\"formats input parsed by Date.parse()\", function() {\n          expect(df({\n            x: \"2015-01-02T23:43:11Z\"\n          })).toBe('abc % %% %%% %a 2015 01 Jan 02 Fri 5 23 43 11');\n          return expect(df({\n            x: \"bla\"\n          })).toBe('');\n        });\n      });\n      return describe(\".bin()\", function() {\n        var binner;\n        binner = $.pivotUtilities.derivers.bin(\"x\", 10);\n        it(\"bins numbers\", function() {\n          expect(binner({\n            x: 11\n          })).toBe(10);\n          expect(binner({\n            x: 9\n          })).toBe(0);\n          return expect(binner({\n            x: 111\n          })).toBe(110);\n        });\n        it(\"bins booleans\", function() {\n          return expect(binner({\n            x: true\n          })).toBe(0);\n        });\n        it(\"bins negative numbers\", function() {\n          return expect(binner({\n            x: -12\n          })).toBe(-10);\n        });\n        it(\"doesn't bin strings\", function() {\n          return expect(binner({\n            x: \"a\"\n          })).toBeNaN();\n        });\n        return it(\"doesn't bin objects\", function() {\n          return expect(binner({\n            x: {\n              a: 1\n            }\n          })).toBeNaN();\n        });\n      });\n    });\n  });\n\n}).call(this);\n\n//# sourceMappingURL=pivot_spec.js.map\n"]}
\ No newline at end of file
diff --git a/src/pivot.coffee b/src/pivot.coffee
index 45c28261..ae2a048c 100644
--- a/src/pivot.coffee
+++ b/src/pivot.coffee
@@ -267,7 +267,8 @@ callWithJQuery ($) ->
             b1 = b.shift()
             if a1 != b1
                 if rd.test(a1) and rd.test(b1) #both are digit chunks
-                    return a1.replace(rz, ".0") - b1.replace(rz, ".0")
+                    numDiff = a1.replace(rz, ".0") - b1.replace(rz, ".0")
+                    return if numDiff != 0 then numDiff else a1.length - b1.length
                 else
                     return (if a1 > b1 then 1 else -1)
         return a.length - b.length
diff --git a/tests/pivot_spec.coffee b/tests/pivot_spec.coffee
index 3028f86c..c458e9f7 100644
--- a/tests/pivot_spec.coffee
+++ b/tests/pivot_spec.coffee
@@ -329,6 +329,18 @@ describe "$.pivotUtilities", ->
                 expect pd.getAggregator([],[]).value()
                 .toBe (1+3)/(2+4)
 
+        describe "with a0-a00 input", ->
+            aoaInput =  [
+                {key: 'a0', ym: '2020-01'},
+                {key: 'a0', ym: '2020-02'},
+                {key: 'a00', ym: '2020-01'},
+                {key: 'a00', ym: '2020-02'}
+            ]
+            pd = new $.pivotUtilities.PivotData aoaInput, rows: ["key", "ym"], cols: []
+
+            it "has correctly-ordered row keys", ->
+                expect pd.getRowKeys()
+                .toEqual [["a0","2020-01"],["a0","2020-02"],["a00","2020-01"],["a00","2020-02"]]
 
         describe "with rows/cols", ->
             pd = new $.pivotUtilities.PivotData fixtureData,