'use strict';

const LINE_SEPARATOR = require('os').EOL; // Was '\n' before

const BLANK_FILE = [
    // Maybe get rid of this line if always intended to be consumed as ES6 modules?
    "'use strict';", 
    "",
    "const Table = {",
    "    __proto__: Array.prototype,",
    "    _eval() {",
    "        const t = this, iterator_pairs = [];",
    "        const defProp = Object.defineProperty;",
    "        for (let [h, iterable] of Object.entries(t)) {",
    "            iterator_pairs.push([h, iterable[Symbol.iterator]()]);",
    // TODO memoise get?
    // TODO delete old h prop before reassigning?
    "            defProp(t, h, {get: () => t.map(r => r[h])});",
    "        };",
    "        defProp(t, '_evaled', {value: true, writable: true});",
    "        defProp(t, 'length', {value: 0, writable: true});",
    "        if (iterator_pairs.length === 0) { return }",
    "        let row, done = false;",
    "        for (;;) {",
    "            t.push(row = {});",
    "            for (let [h, iterator] of iterator_pairs) {",
    "                defProp(row, h, {",
    "                    configurable: true, // We delete the prop later",
    "                    get() {",
    "                        const item = iterator.next();",
    "                        if (item.done) {done = true; return}",
    "                        delete this[h]; return this[h] = item.value;",
    "                    }",
    "                });",
    "            }",
    "            for (let [h, _] of iterator_pairs) { row[h] }",
    "            if (done) {t.pop(); return t}",
    "        }",
    "    }",
    "}",
    "",
    "const Sheet = {",
    "    get _getCache() {",
    "        return this.hasOwnProperty('_cache')",
    "            ? this._cache",
    "            : this._cache = {};",
    "    },",
    "    defineMemoProperty(k, fn) {",
    "        return Object.defineProperty(this, k, {",
    "            get() {",
    "                const c = this._getCache;",
    "                if (k in c) return c[k];",
    "                const v = c[k] = fn(this);",
    "                if (Table.isPrototypeOf(v) && !(v._evaled)) v._eval();",
    "                return v",
    "            },",
    "        });",
    "   }",
    "}",
    "",
    "const DATA = [];",
    "",
    "// Transform data into a spreadsheet object",
    "const $ = {__proto__: Sheet};",
    "for (let [k, _, fn] of DATA) {",
    "   $.defineMemoProperty(k, fn);",
    "}",
    // TODO Add ES6 export line?
].join(LINE_SEPARATOR);

module.exports = { LINE_SEPARATOR, BLANK_FILE }
@@ -734,24 +734,8 @@
 lue:
- true, writable:
  tru
@@ -1659,22 +1659,32 @@
     
-get _getCache(
+defineMemoProperty(k, fn
 ) %7B%22
@@ -1709,37 +1709,40 @@
 urn 
-this.hasOwnProperty('_cache')
+Object.defineProperty(this, k, %7B
 %22,%0A 
@@ -1761,21 +1761,15 @@
     
-? this._cache
+get() %7B
 %22,%0A 
@@ -1788,210 +1788,140 @@
     
-: this._cache = %7B%7D;%22,%0A    %22    %7D,%22,%0A    %22    defineMemoProperty(k, fn) %7B%22,%0A    %22        return Object.defineProperty(this, k, %7B%22,%0A    %22            get() %7B%22,%0A    %22                const c = this._getCache
+    const c = this.hasOwnProperty('_cache')%22,%0A    %22                     ? this._cache%22,%0A    %22                     : this._cache = %7B%7D
 ;%22,%0A

Remove pointless getter