text: 
    (function() {
  
      Polymer('core-layout-grid', {
  
        nodes: null,
        layout: null,
        auto: false,
  
        created: function() {
          this.layout = [];
        },
  
        nodesChanged: function() {
          this.invalidate();
        },
  
        layoutChanged: function() {
          this.invalidate();
        },
  
        autoNodes: function() {
          this.nodes = this.parentNode.children.array().filter(
            function(node) {
              switch(node.localName) {
                case 'core-layout-grid':
                case 'style':
                  return false;
              }
              return true;
            }
          );
        },
  
        invalidate: function() {
          if (this.layout && this.layout.length) {
            // job debounces layout, only letting it occur every N ms
            this.layoutJob = this.job(this.layoutJob, this.relayout);
          }
        },
  
        relayout: function() {
          if (!this.nodes || this.auto) {
            this.autoNodes();
          }
          layout(this.layout, this.nodes);
          this.asyncFire('core-layout');
        }
  
      });
  
      //
  
      var lineParent;
  
      function line(axis, p, d) {
        var l = document.createElement('line');
        var extent = (axis === 'left' ? 'width' : 
          (axis === 'top' ? 'height' : axis));
        l.setAttribute('extent', extent);
        if (d < 0) {
          axis = (axis === 'left' ? 'right' : 
            (axis === 'top' ? 'bottom' : axis));
        }
        p = Math.abs(p);
        l.style[axis] = p + 'px';
        l.style[extent] = '0px';
        lineParent.appendChild(l);
      }
  
      var colCount, colOwners, rowCount, rowOwners;
  
      function matrixillate(matrix) {
        // mesaure the matrix, must be rectangular
        rowCount = matrix.length;
        colCount = rowCount && matrix[0].length || 0;
        // transpose matrix
        var transpose = [];
        for (var i=0; i<colCount; i++) {
          var c = [];
          for (var j=0; j<rowCount; j++) {
            c.push(matrix[j][i]);
          }
          transpose.push(c);
        }
        // assign sizing control
        colOwners = findOwners(matrix);
        rowOwners = findOwners(transpose);
        //console.log('colOwners', colOwners);
        //console.log('rowOwners', rowOwners);
      }
  
      function findOwners(matrix) {
        var majCount = matrix.length;
        var minCount = majCount && matrix[0].length || 0;
        var owners = [];
        // for each column (e.g.)
        for (var i=0; i<minCount; i++) {
          // array of contained areas
          var contained = {};
          // look at each row to find a containing area
          for (var j=0; j<majCount; j++) {
            // get the row vector
            var vector = matrix[j]
            // node index at [i,j]
            var nodei = vector[i];
            // if a node is there
            if (nodei) {
              // determine if it bounds this column
              var owns = false;
              if (i === 0) {
                owns = (i === minCount-1) || (nodei !== vector[i+1]);
              } else if (i === minCount - 1) {
                owns = (i === 0) || (nodei !== vector[i-1]);
              } else {
                owns = nodei !== vector[i-1] && nodei !== vector[i+1];
              }
              if (owns) {
                contained[nodei] = 1;
              }
            }
            // store the owners for this column
            owners[i] = contained;
          }
        }
        return owners;
      }
  
      var nodes;
  
      function colWidth(i) {
        for (var col in colOwners[i]) {
          col = Number(col);
          if (col === 0) {
            return 96;
          }
          var node = nodes[col - 1];
          if (node.hasAttribute('h-flex') || node.hasAttribute('flex')) {
            return -1;
          }
          var w = node.offsetWidth;
          //console.log('colWidth(' + i + ') ==', w);
          return w;
        }
        return -1;
      }
  
      function rowHeight(i) {
        for (var row in rowOwners[i]) {
          row = Number(row);
          if (row === 0) {
            return 96;
          }
          var node = nodes[row - 1];
          if (node.hasAttribute('v-flex') || node.hasAttribute('flex')) {
            return -1;
          }
          var h = node.offsetHeight;
          //console.log('rowHeight(' + i + ') ==', h);
          return h;
        }
        return -1;
      }
  
      var m = 0;
  
      function railize(count, sizeFn) {
        //
        // create rails for `count` tracks using 
        // sizing function `sizeFn(trackNo)`
        //
        // for n tracks there are (n+1) rails
        //
        //   |track|track|track|
        //  0|->sz0|->sz1|<-sz2|0
        //
        //   |track|track|track|
        //  0|->sz0|     |<-sz2|0
        //
        // there can be one elastic track per set
        //
        //   |track|track|track|track|
        //  0|-->s0|-->s1|<--s1|<--s2|0
        //
        // sz1 spans multiple  tracks which makes
        // it elastic (it's underconstrained)
        //
        var rails = [];
        var a = 0;
        for (var i=0, x; i<count; i++) {
          rails[i] = {p: a, s: 1};
          x = sizeFn(i) + m + m;
          if (x == -1) {
            break;
          }
          a += x;
        }
        if (i === count) {
          rails[i] = {p: 0, s: -1};
        }
        var b = 0;
        for (var ii=count, x; ii>i; ii--) {
          rails[ii] = {p: b, s: -1};
          x = sizeFn(ii - 1) + m + m;
          if (x !== -1) {
            b += x;
          }
        }
        return rails;
      }
  
      // TODO(sjmiles): this code tries to preserve actual position,
      // so 'unposition' is really 'naturalize' or something
      function unposition(box) {
        var style = box.style;
        //style.right = style.bottom = style.width = style.height = '';
        style.position = 'absolute';
        style.display = 'inline-block';
        style.boxSizing = style.mozBoxSizing = 'border-box';
      }
  
      function _position(style, maj, min, ext, a, b) {
        style[maj] = style[min] = '';
        style[ext] = 'auto';
        if (a.s < 0 && b.s < 0) {
          var siz = a.p - b.p - m - m;
          style[ext] = siz + 'px';
          var c = 'calc(100% - ' + (b.p + siz + m) + 'px' + ')';
          style[maj] = '-webkit-' + c;
          style[maj] = c;
        } else if (b.s < 0) {
          style[maj] = a.p + m + 'px';
          style[min] = b.p + m + 'px';
        } else {
          style[maj] = a.p + m + 'px';
          style[ext] = b.p - a.p - m - m + 'px';
        }
      }
  
      function position(elt, left, right, top, bottom) {
        _position(elt.style, 'top', 'bottom', 'height', rows[top], 
            rows[bottom]);
        _position(elt.style, 'left', 'right', 'width', columns[left], 
            columns[right]);
      }
  
      function layout(matrix, anodes, alineParent) {
        //console.group('layout');
  
        lineParent = alineParent;
        nodes = anodes;
        matrixillate(matrix);
  
        nodes.forEach(unposition);
  
        columns = railize(colCount, colWidth);
        rows = railize(rowCount, rowHeight);
  
        if (alineParent) {
          //console.group('column rails');
          columns.forEach(function(c) {
            //console.log(c.p, c.s);
            line('left', c.p, c.s);
          });
          //console.groupEnd();
  
          //console.group('row rails');
          rows.forEach(function(r) {
            //console.log(r.p, r.s);
            line('top', r.p, r.s);
          });
          //console.groupEnd();
        }
  
        //console.group('rail boundaries');
        nodes.forEach(function(node, i) {
          // node indices are 1-based
          var n = i + 1;
          // boundary rails
          var l, r, t = 1e10, b = -1e10;
          matrix.forEach(function(vector, i) {
            var f = vector.indexOf(n);
            if (f > -1) {
              l = f;
              r = vector.lastIndexOf(n) + 1;
              t = Math.min(t, i);
              b = Math.max(b, i) + 1;
            }
          });
          if (l == undefined) {
            //console.log('unused');
            node.style.position = 'absolute';
            var offscreen = node.getAttribute('offscreen');
            switch (offscreen) {
              case 'basement':
                node.style.zIndex = 0;
                break;
              case 'left':
              case 'top':
                node.style[offscreen] = node.offsetWidth * -2 + 'px';
                break;
              case 'right':
                node.style.left = node.offsetParent.offsetWidth 
                    + node.offsetWidth + 'px';
                break;
              case 'bottom':
                node.style.top = node.parentNode.offsetHeight 
                    + node.offsetHeight + 'px';
                break;
              default:
                node.style[Math.random() >= 0.5 ? 'left' : 'top'] = '-110%';
            }
            //node.style.opacity = 0;
            node.style.pointerEvents = 'none';
          } else {
            node.style.pointerEvents = '';
            //node.style.opacity = '';
            //console.log(l, r, t, b);
            position(node, l, r, t, b);
          }
        });
        //console.groupEnd();
        //console.groupEnd();
      }
  
    })();
  