{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap f721da4fa38b5f30797c","webpack:///./lib/defaults.js","webpack:///./lib/main.js","webpack:///./lib/component.js","webpack:///./lib/draw.js","webpack:///./lib/events.js","webpack:///./lib/touch.js","webpack:///./lib/intf.js","webpack:///./lib/contextMenu.js","webpack:///./lib/dom.js","webpack:///./lib/publicMethods.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,O;QCVA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;;QAEA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;;;QAGA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA,KAAK;QACL;QACA;;QAEA;QACA;QACA;QACA,2BAA2B,0BAA0B,EAAE;QACvD,iCAAiC,eAAe;QAChD;QACA;QACA;;QAEA;QACA,sDAAsD,+DAA+D;;QAErH;QACA;;QAEA;QACA;;;;;;;;;;;;AC7DA;AACA;AACA,iCAAO,EAAE,mCAAE;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD,MAAM,MAAM;AAChE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD;AACtD,oDAAoD;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AAAA,oGAAC;;;;;;;;;;;;ACrTF;AACA;AACA,iCAAO;AACP,IAAI,yCAAa;AACjB,IAAI,wCAAY;AAChB,IAAI,oCAAQ;AACZ,IAAI,sCAAU;AACd,IAAI,qCAAS;AACb,IAAI,oCAAQ;AACZ,IAAI,2CAAe;AACnB,IAAI,mCAAO;AACX,IAAI,6CAAiB;AACrB,CAAC,mCAAE;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT,sDAAsD,aAAa;AACnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,uBAAuB;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,QAAQ;AAChD,8CAA8C,QAAQ;AACtD;AACA;AACA;AACA,0EAA0E,QAAQ;AAClF;AACA;AACA;AACA;AACA,iCAAiC;AACjC;AACA,yBAAyB;AACzB;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AAAA,oGAAC;;;;;;;;;;;;AChHF;AACA;AACA,iCAAO,CAAC,wCAAY,CAAC,mCAAE;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,oCAAoC,QAAQ;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,mDAAmD,mBAAmB,EAAE;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,2CAA2C,QAAQ;AACnD,oDAAoD,4CAA4C,eAAe;AAC/G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,oCAAoC,wEAAwE;AAC5G;AACA,sCAAsC,wEAAwE;AAC9G,aAAa;AACb;AACA;AACA;AACA,CAAC;AAAA,oGAAC;;;;;;;;;;;;AC1MF;AACA;AACA,iCAAO,EAAE,mCAAE;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,WAAW;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,6CAA6C;AAC7C;AACA;AACA;AACA;AACA,0CAA0C;AAC1C;AACA;AACA,gFAAgF,UAAU;AAC1F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,wBAAwB,UAAU,oBAAoB;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,uBAAuB,kBAAkB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C,OAAO;AACpD;AACA;AACA,sFAAsF,OAAO;AAC7F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,4BAA4B;AACnD;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA,8EAA8E,SAAS,gCAAgC,EAAE;AACzH;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,IAAI,QAAQ;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,UAAU;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qEAAqE,QAAQ;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qFAAqF,QAAQ;AAC7F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,SAAS;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,WAAW;AAC7C;AACA;AACA;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,OAAO;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,uBAAuB;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,QAAQ;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8DAA8D,OAAO;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,OAAO;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,0CAA0C,QAAQ;AAClD;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB,qBAAqB;AACrB;AACA;AACA;AACA,6BAA6B,QAAQ;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD,QAAQ;AAC/D;AACA;AACA;AACA;AACA,uDAAuD,oEAAoE,eAAe,EAAE,EAAE;AAC9I,oDAAoD,iEAAiE,eAAe,EAAE,EAAE;AACxI,+CAA+C,kDAAkD;AACjG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD,mDAAmD;AACvG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,kEAAkE,eAAe,kDAAkD,YAAY;AAC/I,kEAAkE,eAAe,kDAAkD,YAAY;AAC/I;AACA;AACA;AACA;AACA;AACA,6DAA6D,KAAK,yCAAyC,KAAK;AAChH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,IAAI,QAAQ;AAC9D;AACA;AACA;AACA,CAAC;AAAA,oGAAC;;;;;;;;;;;;ACl4CF;AACA;AACA,iCAAO,EAAE,mCAAE;AACX;AACA;AACA;AACA,6CAA6C,qBAAqB;AAClE;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,SAAS;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,SAAS;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B;AACA;AACA,uCAAuC;AACvC;AACA;AACA;AACA;AACA;AACA,mCAAmC,QAAQ;AAC3C;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,QAAQ;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,uBAAuB,OAAO;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,+DAA+D;AACzG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,oCAAoC;AAC1D;AACA;AACA,gCAAgC,WAAW;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,qBAAqB;AACtE;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C,uCAAuC,IAAI,QAAQ;AAChG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD,4CAA4C,IAAI,cAAc;AAClH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,iBAAiB;AACjB;AACA;AACA,iDAAiD,OAAO;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,uCAAuC,IAAI,QAAQ;AACjG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,uCAAuC;AACtF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD,uCAAuC,IAAI,QAAQ;AACvG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD,uCAAuC;AAC5F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,uCAAuC,IAAI,QAAQ;AACpG;AACA;AACA;AACA,+CAA+C,QAAQ;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD,uCAAuC,IAAI,QAAQ;AACxG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2DAA2D,eAAe,IAAI,QAAQ;AACtF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,uCAAuC,IAAI,QAAQ;AAClG;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,QAAQ;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,cAAc;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,uCAAuC,IAAI,QAAQ;AAClG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,kCAAkC;AACxF;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C,uCAAuC,IAAI,QAAQ;AAChG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,uCAAuC,IAAI,QAAQ;AACnG;AACA;AACA,gDAAgD,uCAAuC,IAAI,QAAQ;AACnG;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C,eAAe;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,uBAAuB,cAAc;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,cAAc;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,aAAa;AACb;AACA,aAAa;AACb;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,4CAA4C,eAAe,IAAI,QAAQ;AACvE,qDAAqD,QAAQ;AAC7D;AACA;AACA;AACA;AACA;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA,4CAA4C,sBAAsB;AAClE;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,WAAW;AACjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC;AAClC;AACA;AACA;;AAEA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AAAA,oGAAC;;;;;;;;;;;;ACrzCF;AACA;AACA,iCAAO,EAAE,mCAAE;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,UAAU,EAAE;AAC9C,sCAAsC,cAAc,EAAE;AACtD,uCAAuC,oBAAoB,EAAE;AAC7D,yCAAyC,mDAAmD,EAAE;AAC9F,uCAAuC,kBAAkB,EAAE;AAC3D,wCAAwC,0BAA0B,EAAE;AACpE,0CAA0C,0EAA0E,EAAE;AACtH,uCAAuC,sBAAsB,EAAE;AAC/D,wCAAwC,8BAA8B,EAAE;AACxE,0CAA0C,kEAAkE,EAAE;AAC9G,uCAAuC,0BAA0B,EAAE;AACnE,wCAAwC,mCAAmC,EAAE;AAC7E,0CAA0C,0EAA0E;AACpH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2DAA2D,sDAAsD;AACjH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,QAAQ;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,wCAAwC,IAAI,QAAQ;AACtG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA,qBAAqB;AACrB;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,QAAQ;AAC3C,yEAAyE,eAAe;AACxF;AACA;AACA;AACA;AACA;AACA,gFAAgF,QAAQ;AACxF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD,eAAe,IAAI,QAAQ;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,QAAQ;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C,uCAAuC;AACpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4EAA4E,eAAe;AAC3F;AACA;AACA;AACA;AACA,gDAAgD,uCAAuC,IAAI,QAAQ;AACnG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,uCAAuC,IAAI,QAAQ;AACtG;AACA;AACA;AACA,CAAC;AAAA,oGAAC;;;;;;;;;;;;AClYF;AACA;AACA,iCAAO,EAAE,mCAAE;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,iBAAiB;AACjB,aAAa;AACb;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA,oBAAoB;AACpB,uBAAuB;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA,0BAA0B,WAAW;AACrC;AACA,2BAA2B,QAAQ;AACnC,kCAAkC,QAAQ;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,QAAQ;AACxD;AACA,iEAAiE,QAAQ;AACzE;AACA;AACA;AACA,iBAAiB;AACjB,aAAa;AACb;AACA;AACA;AACA,qDAAqD,UAAU;AAC/D;AACA;AACA;AACA,kDAAkD,UAAU;AAC5D;AACA;AACA;AACA,2EAA2E,QAAQ;AACnF;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,WAAW;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,OAAO;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,uCAAuC,0BAA0B,EAAE;AACnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,kEAAkE;AAClE,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,wBAAwB,EAAE;AACjE;AACA;AACA;AACA,uCAAuC,QAAQ;AAC/C;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD,4BAA4B;AAChF;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA,mCAAmC,QAAQ;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,OAAO;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6EAA6E,gBAAgB,UAAU,EAAE,IAAI;AAC7G,qFAAqF,gBAAgB,UAAU,EAAE,IAAI;AACrH;AACA;AACA,aAAa;AACb;AACA,6CAA6C,yCAAyC,EAAE;AACxF,6CAA6C,wCAAwC,EAAE;AACvF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,aAAa;AACb;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,qBAAqB;AACrB;AACA,wDAAwD,kCAAkC;AAC1F;AACA,aAAa;AACb,4DAA4D,WAAW;AACvE;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,gEAAgE,6BAA6B;AAC7F;AACA,iBAAiB;AACjB,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,aAAa;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,mBAAmB,EAAE;AACxE,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,aAAa;AACb;AACA,uCAAuC,mBAAmB;AAC1D;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,iCAAiC,QAAQ;AACzC;AACA;AACA,aAAa;AACb,SAAS;AACT;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,SAAS;AACT;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,yDAAyD,kBAAkB;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA,qDAAqD,oBAAoB;AACzE;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,IAAI;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,SAAS;AACjD;AACA;AACA;AACA;AACA,yDAAyD,wBAAwB;AACjF;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD,gBAAgB;AACvE;AACA,iBAAiB;AACjB;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA,yFAAyF;AACzF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,iBAAiB;AACjB;AACA,aAAa;AACb;AACA;AACA;AACA,iBAAiB;AACjB;AACA,aAAa;AACb;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,CAAC;AAAA,oGAAC;;;;;;;;;;;;ACrvCF;AACA;AACA,iCAAO,EAAE,mCAAE;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA,wCAAwC,wDAAwD;AAChG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,QAAQ;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,QAAQ;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qEAAqE,QAAQ;AAC7E,4FAA4F,QAAQ;AACpG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,4CAA4C;AAChF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,4CAA4C;AAC5E,gCAAgC,4CAA4C;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,wCAAwC,+BAA+B;AACvE,iBAAiB;AACjB;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mGAAmG,QAAQ;AAC3G;AACA;AACA,gFAAgF,QAAQ,gBAAgB;AACxG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,iBAAiB;AACjB;AACA;AACA,uEAAuE,QAAQ;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,sBAAsB,oBAAoB;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oEAAoE,sCAAsC;AAC1G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B,yBAAyB;AACzB;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD,mBAAmB,EAAE;AACzE;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4DAA4D,kCAAkC;AAC9F,yDAAyD,kCAAkC;AAC3F;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AAAA,oGAAC;;;;;;;;;;;;ACrjBF;AACA;AACA,iCAAO,EAAE,mCAAE;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,gBAAgB;AACjD,iCAAiC,gBAAgB;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+EAA+E;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,IAAI,cAAc;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,IAAI,cAAc;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B;AACA;AACA,4CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,QAAQ;AACjD;AACA;AACA,uDAAuD,qCAAqC,IAAI,cAAc;AAC9G;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA,uDAAuD,WAAW;AAClE,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,6CAA6C,oBAAoB;AACjE;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,wDAAwD,6BAA6B,I;AACrF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,6CAA6C,8BAA8B;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AAAA,oGAAC;;;;;;;;;;;;ACziBF;AACA;AACA,iCAAO,EAAE,mCAAE;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA,6DAA6D,iDAAiD;AAC9G;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA,sDAAsD,+CAA+C;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,QAAQ;AACxC;AACA;AACA;AACA,iBAAiB;AACjB,aAAa;AACb;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B;AACA;AACA,wBAAwB,OAAO;AAC/B,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,2BAA2B,QAAQ;AACnC;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,2BAA2B,QAAQ;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA,kCAAkC,QAAQ;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,QAAQ;AACxD;AACA,iBAAiB;AACjB,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,uCAAuC,QAAQ;AAC/C;AACA;AACA,2BAA2B,OAAO;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,+BAA+B,QAAQ;AACvC;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA,mCAAmC,QAAQ;AAC3C;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,QAAQ;AACnD;AACA;AACA,gCAAgC,SAAS;AACzC;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA,2DAA2D;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,yCAAyC;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,6CAA6C,8BAA8B;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA,uBAAuB,cAAc;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA,+BAA+B,QAAQ;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,uBAAuB,OAAO;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,SAAS;AAC5B,mBAAmB,KAAK;AACxB;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,wDAAwD,uCAAuC,IAAI,QAAQ;AAC3G;AACA;AACA,uDAAuD,QAAQ;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,uCAAuC;AACrF;AACA,qCAAqC,QAAQ;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,MAAM;AACzB,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,QAAQ;AAC1C,uCAAuC,QAAQ;AAC/C;AACA;AACA;AACA;AACA;AACA,uCAAuC,QAAQ;AAC/C,4CAA4C,uBAAuB;AACnE;AACA,iBAAiB;AACjB,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,QAAQ;AAChD,yCAAyC,oBAAoB;AAC7D;AACA,iBAAiB;AACjB,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,KAAK;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,KAAK;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,QAAQ;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kEAAkE,QAAQ;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,OAAO;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,KAAK;AAC1B;AACA;AACA;AACA;AACA;AACA,uBAAuB,yBAAyB;AAChD,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA,wCAAwC,QAAQ;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,KAAK;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,kCAAkC;AAChF;AACA,mDAAmD,iCAAiC;AACpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,QAAQ;AAChD;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD,UAAU;AACjE;AACA;AACA,mDAAmD,UAAU;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AAAA,oGAAC","file":"canvas-datagrid.debug.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"canvasDatagrid\"] = factory();\n\telse\n\t\troot[\"canvasDatagrid\"] = factory();\n})(typeof self !== 'undefined' ? self : this, function() {\nreturn \n\n\n// WEBPACK FOOTER //\n// webpack/universalModuleDefinition"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 1);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap f721da4fa38b5f30797c","/*jslint browser: true, unparam: true, todo: true*/\n/*globals define: true, MutationObserver: false, requestAnimationFrame: false, performance: false, btoa: false*/\ndefine([], function () {\n    'use strict';\n    return function (self) {\n        self.defaults = {\n            attributes: [\n                ['allowColumnReordering', true],\n                ['allowColumnResize', true],\n                ['allowColumnResizeFromCell', false],\n                ['allowFreezingRows', false],\n                ['allowFreezingColumns', false],\n                ['allowMovingSelection', true],\n                ['allowRowHeaderResize', true],\n                ['allowRowReordering', false],\n                ['allowRowResize', true],\n                ['allowRowResizeFromCell', false],\n                ['allowSorting', true],\n                ['autoGenerateSchema', false],\n                ['autoResizeColumns', false],\n                ['borderDragBehavior', 'none'],\n                ['borderResizeZone', 10],\n                ['clearSettingsOptionText', 'Clear saved settings'],\n                ['columnHeaderClickBehavior', 'sort'],\n                ['columnSelectorHiddenText', '&nbsp;&nbsp;&nbsp;'],\n                ['columnSelectorText', 'Add/Remove columns'],\n                ['columnSelectorVisibleText', '\\u2713'],\n                ['contextHoverScrollAmount', 2],\n                ['contextHoverScrollRateMs', 5],\n                ['copyHeadersOnSelectAll', true],\n                ['copyText', 'Copy'],\n                ['debug', false],\n                ['editable', true],\n                ['ellipsisText', '...'],\n                ['filterOptionText', 'Filter %s'],\n                ['filterTextPrefix', '(filtered) '],\n                ['globalRowResize', false],\n                ['hideColumnText', 'Hide %s'],\n                ['maxAutoCompleteItems', 200],\n                ['multiLine', false],\n                ['name', ''],\n                ['pageUpDownOverlap', 1],\n                ['pasteText', 'Paste'],\n                ['persistantSelectionMode', false],\n                ['removeFilterOptionText', 'Remove filter on %s'],\n                ['reorderDeadZone', 3],\n                ['resizeScrollZone', 20],\n                ['rowGrabZoneSize', 5],\n                ['saveAppearance', true],\n                ['scrollAnimationPPSThreshold', 0.75],\n                ['scrollPointerLock', false],\n                ['scrollRepeatRate', 75],\n                ['selectionFollowsActiveCell', false],\n                ['selectionHandleBehavior', 'none'],\n                ['selectionMode', 'cell'],\n                ['selectionScrollIncrement', 20],\n                ['selectionScrollZone', 20],\n                ['showClearSettingsOption', true],\n                ['showColumnHeaders', true],\n                ['showColumnSelector', true],\n                ['showCopy', false],\n                ['showFilter', true],\n                ['showNewRow', false],\n                ['showOrderByOption', true],\n                ['showOrderByOptionTextAsc', 'Order by %s ascending'],\n                ['showOrderByOptionTextDesc', 'Order by %s descending'],\n                ['showPaste', false],\n                ['showPerformance', false],\n                ['showRowHeaders', true],\n                ['showRowNumbers', true],\n                ['singleSelectionMode', false],\n                ['snapToRow', false],\n                ['touchContextMenuTimeMs', 800],\n                ['touchDeadZone', 3],\n                ['touchEasingMethod', 'easeOutQuad'],\n                ['touchReleaseAcceleration', 1000],\n                ['touchReleaseAnimationDurationMs', 2000],\n                ['touchScrollZone', 20],\n                ['touchSelectHandleZone', 20],\n                ['touchZoomSensitivity', 0.005],\n                ['touchZoomMin', 0.5],\n                ['touchZoomMax', 1.75],\n                ['maxPixelRatio', 2],\n                ['tree', false],\n                ['treeHorizontalScroll', false]\n            ],\n            styles: [\n                ['activeCellBackgroundColor', 'rgba(255, 255, 255, 1)'],\n                ['activeCellBorderColor', 'rgba(110, 168, 255, 1)'],\n                ['activeCellBorderWidth', 1],\n                ['activeCellColor', 'rgba(0, 0, 0, 1)'],\n                ['activeCellFont', '16px sans-serif'],\n                ['activeCellHoverBackgroundColor', 'rgba(255, 255, 255, 1)'],\n                ['activeCellHorizontalAlignment', 'left'],\n                ['activeCellHoverColor', 'rgba(0, 0, 0, 1)'],\n                ['activeCellOverlayBorderColor', 'rgba(66, 133, 244, 1)'],\n                ['activeCellOverlayBorderWidth', 1],\n                ['activeCellPaddingBottom', 5],\n                ['activeCellPaddingLeft', 5],\n                ['activeCellPaddingRight', 5],\n                ['activeCellPaddingTop', 5],\n                ['activeCellSelectedBackgroundColor', 'rgba(236, 243, 255, 1)'],\n                ['activeCellSelectedColor', 'rgba(0, 0, 0, 1)'],\n                ['activeCellVerticalAlignment', 'center'],\n                ['activeColumnHeaderCellBackgroundColor', 'rgba(225, 225, 225, 1)'],\n                ['activeColumnHeaderCellColor', 'rgba(0, 0, 0, 1)'],\n                ['activeRowHeaderCellBackgroundColor', 'rgba(225, 225, 225, 1)'],\n                ['activeRowHeaderCellColor', 'rgba(0, 0, 0, 1)'],\n                ['autocompleteBottomMargin', 60],\n                ['autosizeHeaderCellPadding', 8],\n                ['autosizePadding', 5],\n                ['cellAutoResizePadding', 13],\n                ['cellBackgroundColor', 'rgba(255, 255, 255, 1)'],\n                ['cellBorderColor', 'rgba(195, 199, 202, 1)'],\n                ['cellBorderWidth', 1],\n                ['cellColor', 'rgba(0, 0, 0, 1)'],\n                ['cellFont', '16px sans-serif'],\n                ['cellGridHeight', 250],\n                ['cellHeight', 24],\n                ['cellHeightWithChildGrid', 150],\n                ['cellHorizontalAlignment', 'left'],\n                ['cellHoverBackgroundColor', 'rgba(255, 255, 255, 1)'],\n                ['cellHoverColor', 'rgba(0, 0, 0, 1)'],\n                ['cellPaddingBottom', 5],\n                ['cellPaddingLeft', 5],\n                ['cellPaddingRight', 5],\n                ['cellPaddingTop', 5],\n                ['cellSelectedBackgroundColor', 'rgba(236, 243, 255, 1)'],\n                ['cellSelectedColor', 'rgba(0, 0, 0, 1)'],\n                ['cellVerticalAlignment', 'center'],\n                ['cellWidth', 250],\n                ['cellWidthWithChildGrid', 250],\n                ['cellWhiteSpace', 'nowrap'],\n                ['cellLineHeight', 1],\n                ['cellLineSpacing', 3],\n                ['childContextMenuArrowColor', 'rgba(43, 48, 43, 1)'],\n                ['childContextMenuArrowHTML', '&#x25BA;'],\n                ['childContextMenuMarginLeft', -11],\n                ['childContextMenuMarginTop', -6],\n                ['columnHeaderCellBackgroundColor', 'rgba(240, 240, 240, 1)'],\n                ['columnHeaderCellBorderColor', 'rgba(172, 172, 172, 1)'],\n                ['columnHeaderCellBorderWidth', 1],\n                ['columnHeaderCellCapBackgroundColor', 'rgba(240, 240, 240, 1)'],\n                ['columnHeaderCellCapBorderColor', 'rgba(172, 172, 172, 1)'],\n                ['columnHeaderCellCapBorderWidth', 1],\n                ['columnHeaderCellColor', 'rgba(50, 50, 50, 1)'],\n                ['columnHeaderCellFont', '16px sans-serif'],\n                ['columnHeaderCellHeight', 25],\n                ['columnHeaderCellHorizontalAlignment', 'left'],\n                ['columnHeaderCellHoverBackgroundColor', 'rgba(235, 235, 235, 1)'],\n                ['columnHeaderCellHoverColor', 'rgba(0, 0, 0, 1)'],\n                ['columnHeaderCellPaddingBottom', 5],\n                ['columnHeaderCellPaddingLeft', 5],\n                ['columnHeaderCellPaddingRight', 5],\n                ['columnHeaderCellPaddingTop', 5],\n                ['columnHeaderCellVerticalAlignment', 'center'],\n                ['columnHeaderOrderByArrowBorderColor', 'rgba(195, 199, 202, 1)'],\n                ['columnHeaderOrderByArrowBorderWidth', 1],\n                ['columnHeaderOrderByArrowColor', 'rgba(155, 155, 155, 1)'],\n                ['columnHeaderOrderByArrowHeight', 8],\n                ['columnHeaderOrderByArrowMarginLeft', 0],\n                ['columnHeaderOrderByArrowMarginRight', 5],\n                ['columnHeaderOrderByArrowMarginTop', 6],\n                ['columnHeaderOrderByArrowWidth', 13],\n                ['contextFilterButtonBorder', 'solid 1px rgba(158, 163, 169, 1)'],\n                ['contextFilterButtonBorderRadius', '3px'],\n                ['contextFilterButtonHTML', '&#x25BC;'],\n                ['contextFilterInputBackground', 'rgba(255,255,255,1)'],\n                ['contextFilterInputBorder', 'solid 1px rgba(158, 163, 169, 1)'],\n                ['contextFilterInputBorderRadius', '0'],\n                ['contextFilterInputColor', 'rgba(0,0,0,1)'],\n                ['contextFilterInputFontFamily', 'sans-serif'],\n                ['contextFilterInputFontSize', '14px'],\n                ['contextFilterInvalidRegExpBackground', 'rgba(180, 6, 1, 1)'],\n                ['contextFilterInvalidRegExpColor', 'rgba(255, 255, 255, 1)'],\n                ['contextMenuArrowColor', 'rgba(43, 48, 43, 1)'],\n                ['contextMenuArrowDownHTML', '&#x25BC;'],\n                ['contextMenuArrowUpHTML', '&#x25B2;'],\n                ['contextMenuBackground', 'rgba(240, 240, 240, 1)'],\n                ['contextMenuBorder', 'solid 1px rgba(158, 163, 169, 1)'],\n                ['contextMenuBorderRadius', '3px'],\n                ['contextMenuChildArrowFontSize', '12px'],\n                ['contextMenuColor', 'rgba(43, 48, 43, 1)'],\n                ['contextMenuCursor', 'default'],\n                ['contextMenuFilterButtonFontFamily', 'sans-serif'],\n                ['contextMenuFilterButtonFontSize', '10px'],\n                ['contextMenuFilterInvalidExpresion', 'rgba(237, 155, 156, 1)'],\n                ['contextMenuFontFamily', 'sans-serif'],\n                ['contextMenuFontSize', '16px'],\n                ['contextMenuHoverBackground', 'rgba(182, 205, 250, 1)'],\n                ['contextMenuHoverColor', 'rgba(43, 48, 153, 1)'],\n                ['contextMenuItemBorderRadius', '3px'],\n                ['contextMenuItemMargin', '2px'],\n                ['contextMenuLabelDisplay', 'inline-block'],\n                ['contextMenuLabelMargin', '0 3px 0 0'],\n                ['contextMenuLabelMaxWidth', '700px'],\n                ['contextMenuLabelMinWidth', '75px'],\n                ['contextMenuMarginLeft', 3],\n                ['contextMenuMarginTop', -3],\n                ['contextMenuOpacity', '0.98'],\n                ['contextMenuPadding', '2px'],\n                ['contextMenuWindowMargin', 30],\n                ['contextMenuZIndex', 10000],\n                ['cornerCellBackgroundColor', 'rgba(240, 240, 240, 1)'],\n                ['cornerCellBorderColor', 'rgba(202, 202, 202, 1)'],\n                ['debugBackgroundColor', 'rgba(0, 0, 0, .0)'],\n                ['debugColor', 'rgba(255, 15, 24, 1)'],\n                ['debugEntitiesColor', 'rgba(76, 231, 239, 1.00)'],\n                ['debugFont', '11px sans-serif'],\n                ['debugPerfChartBackground', 'rgba(29, 25, 26, 1.00)'],\n                ['debugPerfChartTextColor', 'rgba(255, 255, 255, 0.8)'],\n                ['debugPerformanceColor', 'rgba(252, 255, 37, 1.00)'],\n                ['debugScrollHeightColor', 'rgba(248, 33, 103, 1.00)'],\n                ['debugScrollWidthColor', 'rgba(66, 255, 27, 1.00)'],\n                ['debugTouchPPSXColor', 'rgba(246, 102, 24, 1.00)'],\n                ['debugTouchPPSYColor', 'rgba(186, 0, 255, 1.00)'],\n                ['display', 'inline-block'],\n                ['editCellBackgroundColor', 'white'],\n                ['editCellBorder', 'solid 1px rgba(110, 168, 255, 1)'],\n                ['editCellBoxShadow', '0 2px 5px rgba(0,0,0,0.4)'],\n                ['editCellColor', 'black'],\n                ['editCellFontFamily', 'sans-serif'],\n                ['editCellFontSize', '16px'],\n                ['editCellPaddingLeft', 4],\n                ['editCellZIndex', 10000],\n                ['frozenMarkerHoverColor', 'rgba(236, 243, 255, 1)'],\n                ['frozenMarkerHoverBorderColor', 'rgba(110, 168, 255, 1)'],\n                ['frozenMarkerActiveColor', 'rgba(236, 243, 255, 1)'],\n                ['frozenMarkerActiveBorderColor', 'rgba(110, 168, 255, 1)'],\n                ['frozenMarkerColor', 'rgba(222, 222, 222, 1)'],\n                ['frozenMarkerBorderColor', 'rgba(168, 168, 168, 1)'],\n                ['frozenMarkerBorderWidth', 1],\n                ['frozenMarkerWidth', 2],\n                ['gridBackgroundColor', 'rgba(240, 240, 240, 1)'],\n                ['gridBorderCollapse', 'collapse'],\n                ['gridBorderColor', 'rgba(202, 202, 202, 1)'],\n                ['gridBorderWidth', 1],\n                ['height', 'auto'],\n                ['maxHeight', 'inherit'],\n                ['maxWidth', 'inherit'],\n                ['minColumnWidth', 45],\n                ['minHeight', 'inherit'],\n                ['minRowHeight', 24],\n                ['minWidth', 'inherit'],\n                ['mobileContextMenuMargin', 10],\n                ['mobileEditInputHeight', 30],\n                ['mobileEditFontFamily', 'sans-serif'],\n                ['mobileEditFontSize', '16px'],\n                ['moveOverlayBorderWidth', 1],\n                ['moveOverlayBorderColor', 'rgba(66, 133, 244, 1)'],\n                ['moveOverlayBorderSegments', '12, 7'],\n                ['name', 'default'],\n                ['overflowY', 'auto'],\n                ['overflowX', 'auto'],\n                ['reorderMarkerBackgroundColor', 'rgba(0, 0, 0, 0.1)'],\n                ['reorderMarkerBorderColor', 'rgba(0, 0, 0, 0.2)'],\n                ['reorderMarkerBorderWidth', 1.25],\n                ['reorderMarkerIndexBorderColor', 'rgba(66, 133, 244, 1)'],\n                ['reorderMarkerIndexBorderWidth', 2.75],\n                ['rowHeaderCellBackgroundColor', 'rgba(240, 240, 240, 1)'],\n                ['rowHeaderCellBorderColor', 'rgba(200, 200, 200, 1)'],\n                ['rowHeaderCellBorderWidth', 1],\n                ['rowHeaderCellColor', 'rgba(50, 50, 50, 1)'],\n                ['rowHeaderCellFont', '16px sans-serif'],\n                ['rowHeaderCellHeight', 25],\n                ['rowHeaderCellHorizontalAlignment', 'left'],\n                ['rowHeaderCellHoverBackgroundColor', 'rgba(235, 235, 235, 1)'],\n                ['rowHeaderCellHoverColor', 'rgba(0, 0, 0, 1)'],\n                ['rowHeaderCellPaddingBottom', 5],\n                ['rowHeaderCellPaddingLeft', 5],\n                ['rowHeaderCellPaddingRight', 5],\n                ['rowHeaderCellPaddingTop', 5],\n                ['rowHeaderCellSelectedBackgroundColor', 'rgba(217, 217, 217, 1)'],\n                ['rowHeaderCellSelectedColor', 'rgba(50, 50, 50, 1)'],\n                ['rowHeaderCellVerticalAlignment', 'center'],\n                ['rowHeaderCellWidth', 57],\n                ['scrollBarActiveColor', 'rgba(125, 125, 125, 1)'],\n                ['scrollBarBackgroundColor', 'rgba(240, 240, 240, 1)'],\n                ['scrollBarBorderColor', 'rgba(202, 202, 202, 1)'],\n                ['scrollBarBorderWidth', 0.5],\n                ['scrollBarBoxBorderRadius', 4.125],\n                ['scrollBarBoxColor', 'rgba(192, 192, 192, 1)'],\n                ['scrollBarBoxMargin', 2],\n                ['scrollBarBoxMinSize', 15],\n                ['scrollBarBoxWidth', 8],\n                ['scrollBarCornerBackgroundColor', 'rgba(240, 240, 240, 1)'],\n                ['scrollBarCornerBorderColor', 'rgba(202, 202, 202, 1)'],\n                ['scrollBarWidth', 11],\n                ['selectionHandleBorderColor', 'rgba(255, 255, 255, 1)'],\n                ['selectionHandleBorderWidth', 1.5],\n                ['selectionHandleColor', 'rgba(66, 133, 244, 1)'],\n                ['selectionHandleSize', 8],\n                ['selectionHandleType', 'square'],\n                ['selectionOverlayBorderColor', 'rgba(66, 133, 244, 1)'],\n                ['selectionOverlayBorderWidth', 1],\n                ['treeArrowBorderColor', 'rgba(195, 199, 202, 1)'],\n                ['treeArrowBorderWidth', 1],\n                ['treeArrowClickRadius', 5],\n                ['treeArrowColor', 'rgba(155, 155, 155, 1)'],\n                ['treeArrowHeight', 8],\n                ['treeArrowMarginLeft', 0],\n                ['treeArrowMarginRight', 5],\n                ['treeArrowMarginTop', 6],\n                ['treeArrowWidth', 13],\n                ['treeGridHeight', 250],\n                ['width', 'auto']\n            ]\n        };\n    };\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/defaults.js\n// module id = 0\n// module chunks = 0","/*jslint browser: true, unparam: true, todo: true, evil: true*/\n/*globals Reflect: false, HTMLElement: true, define: true, MutationObserver: false, requestAnimationFrame: false, performance: false, btoa: false*/\ndefine([\n    './component',\n    './defaults',\n    './draw',\n    './events',\n    './touch',\n    './intf',\n    './contextMenu',\n    './dom',\n    './publicMethods'\n], function context(component) {\n    'use strict';\n    component = component();\n    var modules = Array.prototype.slice.call(arguments);\n    function Grid(args) {\n        args = args || {};\n        var self = {};\n        self.isComponent = args.component === undefined;\n        self.isChildGrid = args.parentNode && /canvas-datagrid-(cell|tree)/.test(args.parentNode.nodeType);\n        if (self.isChildGrid) {\n            self.intf = {};\n        } else {\n            self.intf = self.isComponent ? eval('Reflect.construct(HTMLElement, [], new.target)')\n                : document.createElement('canvas');\n        }\n        self.args = args;\n        self.intf.args = args;\n        self.applyComponentStyle = component.applyComponentStyle;\n        self.hyphenateProperty = component.hyphenateProperty;\n        self.dehyphenateProperty = component.dehyphenateProperty;\n        self.createGrid = function grid(args) {\n            args.component = false;\n            return new Grid(args);\n        };\n        modules.forEach(function (module) {\n            module(self);\n        });\n        if (self.isChildGrid) {\n            self.shadowRoot = args.parentNode.shadowRoot;\n            self.parentNode = args.parentNode;\n        } else {\n            self.shadowRoot = self.intf.attachShadow({mode: 'open'});\n            self.parentNode = self.shadowRoot;\n        }\n        self.init();\n        return self.intf;\n    }\n    if (window.HTMLElement) {\n        Grid.prototype = Object.create(window.HTMLElement.prototype);\n    }\n    // export web component\n    if (window.customElements) {\n        Grid.observedAttributes = component.getObservableAttributes();\n        Grid.prototype.disconnectedCallback = component.disconnectedCallback;\n        Grid.prototype.attributeChangedCallback = component.attributeChangedCallback;\n        Grid.prototype.connectedCallback = component.connectedCallback;\n        Grid.prototype.adoptedCallback = component.adoptedCallback;\n        window.customElements.define('canvas-datagrid', Grid);\n    }\n    // export global\n    if (window && !window.canvasDatagrid && !window.require) {\n        window.canvasDatagrid = function (args) { return new Grid(args); };\n    }\n    // export amd loader\n    module.exports = function grid(args) {\n        args = args || {};\n        var i, tKeys = ['style', 'formatters', 'sorters', 'filters',\n                    'treeGridAttributes', 'cellGridAttributes', 'data', 'schema'];\n        if (window.customElements) {\n            i = document.createElement('canvas-datagrid');\n            Object.keys(args).forEach(function (argKey) {\n                // set data and parentNode after everything else\n                if (argKey === 'data') { return; }\n                if (argKey === 'parentNode') { return; }\n                // top level keys in args\n                if (tKeys.indexOf(argKey) !== -1) {\n                    tKeys.forEach(function (tKey) {\n                        if (args[tKey] === undefined || tKey !== argKey) { return; }\n                        if (['formatters', 'sorters', 'filters'].indexOf(argKey) !== -1) {\n                            if (typeof args[tKey] === 'object' && args[tKey] !== null) {\n                                Object.keys(args[tKey]).forEach(function (sKey) {\n                                    i[tKey][sKey] = args[tKey][sKey];\n                                });\n                            }\n                        } else {\n                            i[tKey] = args[tKey];\n                        }\n                    });\n                    return;\n                }\n                // all others are attribute level keys\n                i.attributes[argKey] = args[argKey];\n            });\n            if (args.data) {\n                i.data = args.data;\n            }\n            // add to the dom very last to avoid redraws\n            if (args.parentNode) {\n                args.parentNode.appendChild(i);\n            }\n            return i;\n        }\n        args.component = false;\n        i = new Grid(args);\n        if (args.parentNode && args.parentNode.appendChild) {\n            args.parentNode.appendChild(i);\n        }\n        return i;\n    };\n    return module.exports;\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/main.js\n// module id = 1\n// module chunks = 0","/*jslint browser: true, unparam: true, todo: true*/\n/*globals define: true, MutationObserver: false, requestAnimationFrame: false, performance: false, btoa: false*/\ndefine(['./defaults'], function (defaults) {\n    'use strict';\n    return function () {\n        var typeMap, component = {};\n        component.dehyphenateProperty = function hyphenateProperty(prop) {\n            prop = prop.replace('--cdg-', '');\n            var p = '', nextLetterCap;\n            Array.prototype.forEach.call(prop, function (char) {\n                if (nextLetterCap) {\n                    nextLetterCap = false;\n                    p += char.toUpperCase();\n                    return;\n                }\n                if (char === '-') {\n                    nextLetterCap = true;\n                    return;\n                }\n                p += char;\n            });\n            return p;\n        };\n        component.hyphenateProperty = function hyphenateProperty(prop, cust) {\n            var p = '';\n            Array.prototype.forEach.call(prop, function (char) {\n                if (char === char.toUpperCase()) {\n                    p += '-' + char.toLowerCase();\n                    return;\n                }\n                p += char;\n            });\n            return (cust ? '--cdg-' : '') + p;\n        };\n        function getDefaultItem(base, item) {\n            var i = {},\n                r;\n            defaults(i);\n            r = i.defaults[base].filter(function (i) {\n                return i[0].toLowerCase() === item.toLowerCase()\n                    || component.hyphenateProperty(i[0]) === item.toLowerCase()\n                    || component.hyphenateProperty(i[0], true) === item.toLowerCase();\n            })[0];\n            return r;\n        }\n        component.applyComponentStyle = function (supressChangeAndDrawEvents, intf) {\n            if (!intf.isComponent) { return; }\n            var cStyle = window.getComputedStyle(intf.tagName === 'CANVAS-DATAGRID' ? intf : intf.canvas, null),\n                defs = {};\n            intf.computedStyle = cStyle;\n            defaults(defs);\n            defs = defs.defaults.styles;\n            defs.forEach(function (def) {\n                var val;\n                val = cStyle.getPropertyValue(component.hyphenateProperty(def[0], true));\n                if (val === \"\") {\n                    val = cStyle.getPropertyValue(component.hyphenateProperty(def[0], false));\n                }\n                if (val !== \"\" && typeof val === 'string') {\n                    intf.setStyleProperty(def[0], typeMap[typeof def[1]](val\n                        .replace(/^\\s+/, '').replace(/\\s+$/, ''), def[1]), true);\n                }\n            });\n            if (!supressChangeAndDrawEvents && intf.dispatchEvent) {\n                requestAnimationFrame(function () { intf.resize(true); });\n                intf.dispatchEvent('stylechanged', intf.style);\n            }\n        };\n        typeMap = {\n            data: function (strData) {\n                try {\n                    return JSON.parse(strData);\n                } catch (e) {\n                    throw new Error('Cannot read JSON data in canvas-datagrid data.');\n                }\n            },\n            schema: function (strSchema) {\n                try {\n                    return JSON.parse(strSchema);\n                } catch (e) {\n                    throw new Error('Cannot read JSON data in canvas-datagrid schema attribute.');\n                }\n            },\n            number: function (strNum, def) {\n                var n = parseInt(strNum, 10);\n                return isNaN(n) ? def : n;\n            },\n            boolean: function (strBool) {\n                return (/true/i).test(strBool);\n            },\n            string: function (str) {\n                return str;\n            }\n        };\n        component.getObservableAttributes = function () {\n            var i = {}, attrs = ['data', 'schema', 'style', 'className', 'name'];\n            defaults(i);\n            i.defaults.attributes.forEach(function (attr) {\n                attrs.push(attr[0].toLowerCase());\n            });\n            return attrs;\n        };\n        component.disconnectedCallback = function () {\n            this.connected = false;\n        };\n        component.connectedCallback = function () {\n            var intf = this;\n            intf.parentDOMNode.innerHTML = \"\";\n            intf.parentDOMNode.appendChild(intf.canvas);\n            intf.connected = true;\n            component.observe(intf);\n            component.applyComponentStyle(true, intf);\n            intf.resize(true);\n        };\n        component.adoptedCallback = function () {\n            this.resize();\n        };\n        component.attributeChangedCallback = function (attrName, oldVal, newVal) {\n            var tfn, intf = this, def;\n            if (attrName === 'style') {\n                component.applyComponentStyle(false, intf);\n                return;\n            }\n            if (attrName === 'data') {\n                if (intf.dataType === 'application/x-canvas-datagrid') {\n                    intf.dataType = 'application/json+x-canvas-datagrid';\n                }\n                intf.args.data = newVal;\n                return;\n            }\n            if (attrName === 'schema') {\n                intf.args.schema = typeMap.schema(newVal);\n                return;\n            }\n            if (attrName === 'name') {\n                intf.name = newVal;\n                return;\n            }\n            if (attrName === 'class' || attrName === 'className') {\n                return;\n            }\n            def = getDefaultItem('attributes', attrName);\n            if (def) {\n                tfn = typeMap[typeof def[1]];\n                intf.attributes[def[0]] = tfn(newVal);\n                return;\n            }\n            if (/^on/.test(attrName)) {\n                intf.addEventListener('on' + attrName, function (e) {\n                    eval(newVal);\n                });\n            }\n            return;\n        };\n        component.observe = function (intf) {\n            var observer;\n            if (!window.MutationObserver) { return; }\n            intf.applyComponentStyle = function () { component.applyComponentStyle(false, intf); intf.resize(); };\n            /**\n             * Applies the computed css styles to the grid.  In some browsers, changing directives in attached style sheets does not automatically update the styles in this component.  It is necessary to call this method to update in these cases.\n             * @memberof canvasDatagrid\n             * @name applyComponentStyle\n             * @method\n             */\n            observer = new window.MutationObserver(function (mutations) {\n                var checkInnerHTML, checkStyle;\n                Array.prototype.forEach.call(mutations, function (mutation) {\n                    if (mutation.attributeName === 'class'\n                            || mutation.attributeName === 'style') {\n                        checkStyle = true;\n                        return;\n                    }\n                    if (mutation.target.nodeName === 'STYLE') {\n                        checkStyle = true;\n                        return;\n                    }\n                    if (mutation.target.parentNode\n                            && mutation.target.parentNode.nodeName === 'STYLE') {\n                        checkStyle = true;\n                        return;\n                    }\n                    if (mutation.target === intf && (mutation.addedNodes.length > 0 || mutation.type === 'characterData')) {\n                        checkInnerHTML = true;\n                    }\n                });\n                if (checkStyle) {\n                    intf.applyComponentStyle(false, intf);\n                }\n                if (checkInnerHTML) {\n                    if (intf.dataType === 'application/x-canvas-datagrid') {\n                        intf.dataType = 'application/json+x-canvas-datagrid';\n                    }\n                    intf.data = intf.innerHTML;\n                }\n            });\n            observer.observe(intf, { characterData: true, childList: true, attributes: true, subtree: true });\n            Array.prototype.forEach.call(document.querySelectorAll('style'), function (el) {\n                observer.observe(el, { characterData: true, childList: true, attributes: true, subtree: true });\n            });\n        };\n        return component;\n    };\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/component.js\n// module id = 2\n// module chunks = 0","/*jslint browser: true, unparam: true, todo: true*/\n/*globals XMLSerializer: false, define: true, Blob: false, MutationObserver: false, requestAnimationFrame: false, performance: false, btoa: false*/\ndefine([], function () {\n    'use strict';\n    return function (self) {\n        var perfCounters = [],\n            cachedImagesDrawn = false,\n            drawCount = 0,\n            perfWindowSize = 300,\n            entityCount = [],\n            hiddenFrozenColumnCount = 0,\n            scrollDebugCounters = [],\n            touchPPSCounters = [];\n        self.htmlImageCache = {};\n        // more heavyweight version than fillArray defined in intf.js\n        function fillArray(low, high, step, def) {\n            step = step || 1;\n            var i = [], x;\n            for (x = low; x <= high; x += step) {\n                i[x] = def === undefined ? x : (typeof def === 'function' ? def(x) : def);\n            }\n            return i;\n        }\n        function drawPerfLine(w, h, x, y, perfArr, arrIndex, max, color, useAbs) {\n            var i = w / perfArr.length,\n                r = h / max;\n            x += self.canvasOffsetLeft;\n            y += self.canvasOffsetTop;\n            self.ctx.beginPath();\n            self.ctx.moveTo(x, y + h);\n            perfArr.forEach(function (n) {\n                var val = (arrIndex === undefined ? n : n[arrIndex]),\n                    cx,\n                    cy;\n                if (useAbs) {\n                    val = Math.abs(val);\n                }\n                cx = x + i;\n                cy = y + h - (val * r);\n                self.ctx.lineTo(cx, cy);\n                x += i;\n            });\n            self.ctx.moveTo(x + w, y + h);\n            self.ctx.strokeStyle = color;\n            self.ctx.stroke();\n        }\n        function drawOnAllImagesLoaded() {\n            var loaded = true;\n            Object.keys(self.htmlImageCache).forEach(function (html) {\n                if (!self.htmlImageCache[html].img.complete) {\n                    loaded = false;\n                }\n            });\n            if (loaded && !cachedImagesDrawn) {\n                cachedImagesDrawn = true;\n                self.draw();\n            }\n        }\n        function drawHtml(cell) {\n            var img,\n                v = cell.innerHTML || cell.formattedValue,\n                cacheKey = v.toString() + cell.rowIndex.toString() + cell.columnIndex.toString(), \n                x = cell.x + self.canvasOffsetLeft,\n                y = cell.y + self.canvasOffsetTop;\n            if (self.htmlImageCache[cacheKey]) {\n                img = self.htmlImageCache[cacheKey].img;\n                if (self.htmlImageCache[cacheKey].height !== cell.height || self.htmlImageCache[cacheKey].width !== cell.width) {\n                    // height and width of the cell has changed, invalidate cache\n                    self.htmlImageCache[cacheKey] = undefined;\n                } else {\n                    if (!img.complete) {\n                        return;\n                    }\n                    return self.ctx.drawImage(img, x, y);\n                }\n            } else {\n                cachedImagesDrawn = false;\n            }\n            img = new Image(cell.width, cell.height);\n            self.htmlImageCache[cacheKey] = { img, width: cell.width, height: cell.height };\n            img.onload = function () {\n                self.ctx.drawImage(img, x, y);\n                drawOnAllImagesLoaded();\n            };\n            img.src = 'data:image/svg+xml;base64,' + btoa(\n                '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"' + cell.width + '\" height=\"' + cell.height + '\">\\n' +\n                    '<foreignObject class=\"node\" x=\"0\" y=\"0\" width=\"100%\" height=\"100%\">\\n' +\n                    '<body xmlns=\"http://www.w3.org/1999/xhtml\" style=\"margin:0;padding:0;\">\\n' +\n                    v + '\\n' +\n                    '</body>' +\n                    '</foreignObject>\\n' +\n                    '</svg>\\n'\n            );\n        }\n        function drawOrderByArrow(x, y) {\n            var mt = self.style.columnHeaderOrderByArrowMarginTop * self.scale,\n                ml = self.style.columnHeaderOrderByArrowMarginLeft * self.scale,\n                mr = self.style.columnHeaderOrderByArrowMarginRight * self.scale,\n                aw = self.style.columnHeaderOrderByArrowWidth * self.scale,\n                ah = self.style.columnHeaderOrderByArrowHeight * self.scale;\n            x += self.canvasOffsetLeft;\n            y += self.canvasOffsetTop;\n            self.ctx.fillStyle = self.style.columnHeaderOrderByArrowColor;\n            self.ctx.strokeStyle = self.style.columnHeaderOrderByArrowBorderColor;\n            self.ctx.beginPath();\n            x = x + ml;\n            y = y + mt;\n            if (self.orderDirection === 'asc') {\n                self.ctx.moveTo(x, y);\n                self.ctx.lineTo(x + aw, y);\n                self.ctx.lineTo(x + (aw * 0.5), y + ah);\n                self.ctx.moveTo(x, y);\n            } else {\n                self.ctx.lineTo(x, y + ah);\n                self.ctx.lineTo(x + aw, y + ah);\n                self.ctx.lineTo(x + (aw * 0.5), y);\n                self.ctx.lineTo(x, y + ah);\n            }\n            self.ctx.stroke();\n            self.ctx.fill();\n            return ml + aw + mr;\n        }\n        function drawTreeArrow(cell, x, y) {\n            var mt = self.style.treeArrowMarginTop * self.scale,\n                mr = self.style.treeArrowMarginRight * self.scale,\n                ml = self.style.treeArrowMarginLeft * self.scale,\n                aw = self.style.treeArrowWidth * self.scale,\n                ah = self.style.treeArrowHeight * self.scale;\n            x += self.canvasOffsetLeft;\n            y += self.canvasOffsetTop;\n            self.ctx.fillStyle = self.style.treeArrowColor;\n            self.ctx.strokeStyle = self.style.treeArrowBorderColor;\n            self.ctx.beginPath();\n            x = x + ml;\n            y = y + mt;\n            if (self.openChildren[cell.rowIndex]) {\n                self.ctx.moveTo(x, y);\n                self.ctx.lineTo(x + aw, y);\n                self.ctx.lineTo(x + (aw * 0.5), y + ah);\n                self.ctx.moveTo(x, y);\n            } else {\n                self.ctx.lineTo(x, y);\n                self.ctx.lineTo(x + ah, y + (aw * 0.5));\n                self.ctx.lineTo(x, y + aw);\n                self.ctx.lineTo(x, y);\n            }\n            self.ctx.stroke();\n            self.ctx.fill();\n            return ml + aw + mr;\n        }\n        function radiusRect(x, y, w, h, radius) {\n            x += self.canvasOffsetLeft;\n            y += self.canvasOffsetTop;\n            var r = x + w, b = y + h;\n            self.ctx.beginPath();\n            self.ctx.moveTo(x + radius, y);\n            self.ctx.lineTo(r - radius, y);\n            self.ctx.quadraticCurveTo(r, y, r, y + radius);\n            self.ctx.lineTo(r, y + h - radius);\n            self.ctx.quadraticCurveTo(r, b, r - radius, b);\n            self.ctx.lineTo(x + radius, b);\n            self.ctx.quadraticCurveTo(x, b, x, b - radius);\n            self.ctx.lineTo(x, y + radius);\n            self.ctx.quadraticCurveTo(x, y, x + radius, y);\n        }\n        function fillRect(x, y, w, h) {\n            x += self.canvasOffsetLeft;\n            y += self.canvasOffsetTop;\n            self.ctx.fillRect(x, y, w, h);\n        }\n        function strokeRect(x, y, w, h) {\n            x += self.canvasOffsetLeft;\n            y += self.canvasOffsetTop;\n            self.ctx.strokeRect(x, y, w, h);\n        }\n        function fillText(text, x, y) {\n            x += self.canvasOffsetLeft;\n            y += self.canvasOffsetTop;\n            self.ctx.fillText(text, x, y);\n        }\n        function fillCircle(x, y, r) {\n            x += self.canvasOffsetLeft;\n            y += self.canvasOffsetTop;\n            self.ctx.beginPath();\n            self.ctx.arc(x, y, r, 0, 2 * Math.PI);\n            self.ctx.fill();\n        }\n        function strokeCircle(x, y, r) {\n            x += self.canvasOffsetLeft;\n            y += self.canvasOffsetTop;\n            self.ctx.beginPath();\n            self.ctx.arc(x, y, r, 0, 2 * Math.PI);\n            self.ctx.stroke();\n        }\n        function clipFrozenArea(mode) {\n            // 0 both, 1 rows, 2 cols\n            // self.lastFrozenColumnPixel;\n            // self.lastFrozenRowPixel;\n            self.ctx.beginPath();\n            if (mode === 0) {\n                self.ctx.moveTo(self.lastFrozenColumnPixel, self.lastFrozenRowPixel);\n                self.ctx.lineTo(self.lastFrozenColumnPixel, self.height);\n                self.ctx.lineTo(self.width, self.height);\n                self.ctx.lineTo(self.width, self.lastFrozenRowPixel);\n            }\n            if (mode === 1) {\n                self.ctx.moveTo(0, self.lastFrozenRowPixel);\n                self.ctx.lineTo(0, self.height);\n                self.ctx.lineTo(self.width, self.height);\n                self.ctx.lineTo(self.width, self.lastFrozenRowPixel);\n            }\n            if (mode === 2) {\n                self.ctx.moveTo(self.lastFrozenColumnPixel, 0);\n                self.ctx.lineTo(self.width, 0);\n                self.ctx.lineTo(self.width, self.height);\n                self.ctx.lineTo(self.lastFrozenColumnPixel, self.height);\n            }\n            self.ctx.clip();\n        }\n        function fillHandle(x, y, r) {\n            if (self.style.selectionHandleType === 'circle') {\n                return fillCircle(x, y, r * 0.5);\n            }\n            fillRect(x - r * 0.5, y - r * 0.5, r, r);\n        }\n        function strokeHandle(x, y, r) {\n            if (self.style.selectionHandleType === 'circle') {\n                return strokeCircle(x, y, r * 0.5);\n            }\n            strokeRect(x - r * 0.5, y - r * 0.5, r, r);\n        }\n        function addselectionHandle(c, pos) {\n            var hw = self.style.selectionHandleSize,\n                p = {\n                    tr: function () {\n                        fillHandle(c.x + c.width, c.y, hw);\n                        strokeHandle(c.x + c.width, c.y, hw);\n                    },\n                    br: function () {\n                        fillHandle(c.x + c.width, c.y + c.height, hw);\n                        strokeHandle(c.x + c.width, c.y + c.height, hw);\n                    },\n                    tl: function () {\n                        fillHandle(c.x, c.y, hw);\n                        strokeHandle(c.x, c.y, hw);\n                    },\n                    bl: function () {\n                        fillHandle(c.x, c.y + c.height, hw);\n                        strokeHandle(c.x, c.y + c.height, hw);\n                    }\n                };\n            p[pos]();\n        }\n        function addBorderLine(c, pos) {\n            self.ctx.beginPath();\n            var p = {\n                t: function () {\n                    self.ctx.moveTo(c.x + self.canvasOffsetLeft, c.y + self.canvasOffsetTop);\n                    self.ctx.lineTo(c.x + self.canvasOffsetLeft + c.width, c.y + self.canvasOffsetTop);\n                },\n                r: function () {\n                    self.ctx.moveTo(c.x + self.canvasOffsetLeft + c.width, c.y + self.canvasOffsetTop);\n                    self.ctx.lineTo(c.x + self.canvasOffsetLeft + c.width, c.y + self.canvasOffsetTop + c.height);\n                },\n                b: function () {\n                    self.ctx.moveTo(c.x + self.canvasOffsetLeft, c.y + self.canvasOffsetTop + c.height);\n                    self.ctx.lineTo(c.x + self.canvasOffsetLeft + c.width, c.y + self.canvasOffsetTop + c.height);\n                },\n                l: function () {\n                    self.ctx.moveTo(c.x + self.canvasOffsetLeft, c.y + self.canvasOffsetTop);\n                    self.ctx.lineTo(c.x + self.canvasOffsetLeft, c.y + self.canvasOffsetTop + c.height);\n                }\n            };\n            p[pos]();\n            self.ctx.stroke();\n        }\n        function addEllipsis(text, width) {\n            var c, w = 0;\n            if (self.ellipsisCache[text] && self.ellipsisCache[text][width]) {\n                return self.ellipsisCache[text][width];\n            }\n            //TODO Add ellipsis back when there is a fast way to do it\n            w = self.ctx.measureText(text).width;\n            self.ellipsisCache[text] = self.ellipsisCache[text] || {};\n            c = {value: text, width: w};\n            self.ellipsisCache[text][width] = c;\n            return c;\n        }\n        function wrapText(cell, splitChar) {\n            if (!cell.formattedValue) {\n                return { lines: [{width: 0, value: ''}], width: 0, height: cell.calculatedLineHeight };\n            }\n            var max = 0,\n                n = '\\n',\n                x,\n                word,\n                words = cell.formattedValue.split(splitChar),\n                textHeight = cell.calculatedLineHeight,\n                lines = [],\n                out = [],\n                wrap = self.style.cellWhiteSpace !== 'nowrap',\n                elWidth,\n                et = self.attributes.ellipsisText,\n                elClipLength,\n                plWidth,\n                clippedVal,\n                ogWordWidth,\n                previousLine,\n                line = {\n                    width: 0,\n                    value: ''\n                },\n                cHeight = wrap ? cell.paddedHeight : cell.calculatedLineHeight;\n            lines.push(line);\n            elWidth = self.ctx.measureText(' ' + et).width;\n            for (x = 0; x < words.length; x += 1) {\n                word = words[x];\n                var measure = self.ctx.measureText(word + splitChar);\n                if (line.width + measure.width + elWidth < cell.paddedWidth) {\n                    line.value += word + splitChar;\n                    line.width += measure.width;\n                    continue;\n                }\n                // if there is a hyphenated word that is too long\n                // split it and add the split set to the array\n                // then back up and re-read new split set\n                // this behavior seems right, it might not be\n                if (/\\w-\\w/.test(word) && cell.paddedWidth < measure.width) {\n                    words.splice(x, 1, word.split('-')[0] + '-', word.split('-')[1]);\n                    x -= 1;\n                    continue;\n                }\n                line = {\n                    width: measure.width,\n                    value: word + splitChar\n                };\n                if (x === 0) {\n                    lines = [];\n                    lines.push(line);\n                }\n                textHeight += cell.calculatedLineHeight;\n                if (textHeight > cHeight) {\n                    if (lines.length === 0) { break; }\n                    elClipLength = 1;\n                    previousLine = lines[lines.length - 1];\n                    if (previousLine.width < cell.paddedWidth && words.length === 1) { break; }\n                    clippedVal = previousLine.value + word;\n                    plWidth = self.ctx.measureText(clippedVal + et).width;\n                    var originText = clippedVal;\n                    if (plWidth > cell.paddedWidth) {\n                        var stepLength = parseInt(clippedVal.length / 2);\n                        var direction = -1;\n                        while (stepLength > 0) {\n                            clippedVal = originText.substr(0, stepLength * direction + clippedVal.length);\n                            plWidth = self.ctx.measureText(clippedVal + et).width;\n                            direction = plWidth > cell.paddedWidth ? -1 : 1;\n                            stepLength = parseInt(stepLength / 2);\n                        }\n                    }\n                    clippedVal = clippedVal + (originText.length != clippedVal.length ? et : '');\n                    previousLine.value = clippedVal;\n                    previousLine.width = plWidth;\n                    break;\n                }\n                if (x > 0) {\n                    lines.push(line);\n                }\n            }\n            return {\n                lines: lines,\n                width: max,\n                height: cell.calculatedLineHeight * lines.length\n            }\n        }\n        function drawText(cell) {\n            var ll = cell.text.lines.length,\n                h = (cell.fontHeight * cell.lineHeight),\n                x,\n                line,\n                wrap = self.style.cellWhiteSpace !== 'nowrap',\n                textHeight = 0;\n            for (x = 0; x < cell.text.lines.length; x += 1) {\n                line = cell.text.lines[x];\n                var vPos = Math.max((cell.height - (wrap ? cell.text.height : cell.calculatedLineHeight)) * 0.5, 0) + h,\n                    hPos = cell.paddingLeft + cell.treeArrowWidth + cell.orderByArrowWidth;\n                if (cell.horizontalAlignment === 'right') {\n                    hPos = cell.paddingLeft + cell.paddedWidth - line.width;\n                } else if (cell.horizontalAlignment === 'center') {\n                    hPos = cell.paddingLeft + ((cell.paddedWidth + cell.paddingRight) / 2) - (line.width / 2);\n                }\n                if (cell.verticalAlignment === 'top') {\n                    vPos = cell.calculatedLineHeight;\n                } else if (cell.verticalAlignment === 'bottom') {\n                    vPos = cell.height - cell.paddingBottom - cell.text.height;\n                }\n                line.height = h + cell.lineSpacing;\n                line.offsetLeft = hPos;\n                line.offsetTop = vPos;\n                line.x = cell.x + hPos;\n                line.y = cell.y + textHeight + vPos;\n                textHeight += line.height;\n                fillText(line.value, line.x, line.y);\n            }\n            if (self.attributes.debug && cell.active) {\n                requestAnimationFrame(function () {\n                    self.ctx.font = self.style.debugFont;\n                    self.ctx.fillStyle = self.style.debugColor;\n                    fillText(JSON.stringify({\n                        x: cell.x,\n                        y: cell.y,\n                        h: cell.height,\n                        w: cell.width,\n                        pw: cell.paddedWidth,\n                        idx: cell.columnIndex,\n                        idx_ord: cell.sortColumnIndex\n                    }, null, '\\t'),\n                        cell.x + 14, cell.y + 14);\n                    fillText(JSON.stringify(cell.text.lines.map(function (l) { return {w: l.width, v: l.value.length }; }), null, '\\t'),\n                        cell.x + 14, cell.y + 30);\n                });\n            }\n        }\n        function getFrozenColumnsWidth() {\n            var w = 0,\n                s = self.getSchema(),\n                x = 0,\n                n = Math.min(self.frozenColumn, s.length),\n                column;\n            hiddenFrozenColumnCount = 0;\n            while (x < n) {\n                column = s[x];\n                if (column.hidden) {\n                    hiddenFrozenColumnCount += 1;\n                } else {\n                    w += self.getColummnWidth(x);\n                }\n                x += 1;\n            }\n            return w;\n        }\n        /**\n         * Redraws the grid. No matter what the change, this is the only method required to refresh everything.\n         * @memberof canvasDatagrid\n         * @name draw\n         * @method\n         */\n         // r = literal row index\n         // rd = row data array\n         // i = user order index\n         // o = literal data index\n         // y = y drawing cursor\n         // x = x drawing cursor\n         // s = visible schema array\n         // cx = current x drawing cursor sub calculation var\n         // cy = current y drawing cursor sub calculation var\n         // a = static cell (like corner cell)\n         // p = perf counter\n         // l = data length\n         // u = current cell\n         // h = current height\n         // w = current width\n        self.draw = function (internal) {\n            if (self.dispatchEvent('beforedraw', {})) { return; }\n            if (!self.isChildGrid && (!self.height || !self.width)) {\n                return;\n            }\n            if (self.isChildGrid && internal) {\n                requestAnimationFrame(self.parentGrid.draw);\n                return;\n            }\n            if (self.intf.visible === false) {\n                return;\n            }\n            // initial values\n            var checkScrollHeight, rowHeaderCell, p, cx, cy, treeGrid, rowOpen,\n                rowHeight, cornerCell, y, x, c, h, w, s, r, rd, aCell,\n                data = (self.data || []),\n                bc = self.style.gridBorderCollapse === 'collapse',\n                selectionBorders = [],\n                moveBorders = [],\n                selectionHandles = [],\n                rowHeaders = [],\n                l = data.length,\n                u = self.currentCell || {},\n                columnHeaderCellHeight = self.getColumnHeaderCellHeight(),\n                rowHeaderCellWidth = self.getRowHeaderCellWidth(),\n                cellHeight = self.style.cellHeight;\n            drawCount += 1;\n            p = performance.now();\n            self.visibleRowHeights = [];\n            // if data length has changed, there is no way to know\n            if (data.length > self.orders.rows.length) {\n                self.createRowOrders();\n            }\n            function drawScrollBars() {\n                var drawCorner,\n                    en = self.scrollBox.entities,\n                    m = (self.style.scrollBarBoxMargin * 2);\n                self.ctx.strokeStyle = self.style.scrollBarBorderColor;\n                self.ctx.lineWidth = self.style.scrollBarBorderWidth;\n                en.horizontalBox.x = rowHeaderCellWidth + self.style.scrollBarBoxMargin\n                    + ((en.horizontalBar.width - self.scrollBox.scrollBoxWidth)\n                        * (self.scrollBox.scrollLeft / self.scrollBox.scrollWidth));\n                en.verticalBox.y = columnHeaderCellHeight + self.style.scrollBarBoxMargin\n                    + ((en.verticalBar.height - self.scrollBox.scrollBoxHeight)\n                        * (self.scrollBox.scrollTop / self.scrollBox.scrollHeight));\n                if (self.scrollBox.horizontalBarVisible) {\n                    self.ctx.fillStyle = self.style.scrollBarBackgroundColor;\n                    fillRect(en.horizontalBar.x, en.horizontalBar.y, en.horizontalBar.width + m, en.horizontalBar.height);\n                    strokeRect(en.horizontalBar.x, en.horizontalBar.y, en.horizontalBar.width + m, en.horizontalBar.height);\n                    self.ctx.fillStyle = self.style.scrollBarBoxColor;\n                    if (self.scrollBox.horizontalBoxVisible) {\n                        if (/horizontal/.test(u.context)) {\n                            self.ctx.fillStyle = self.style.scrollBarActiveColor;\n                        }\n                        radiusRect(en.horizontalBox.x, en.horizontalBox.y,\n                            en.horizontalBox.width, en.horizontalBox.height, self.style.scrollBarBoxBorderRadius);\n                        self.ctx.stroke();\n                        self.ctx.fill();\n                    }\n                    drawCorner = true;\n                    self.visibleCells.unshift(en.horizontalBar);\n                    self.visibleCells.unshift(en.horizontalBox);\n                }\n                if (self.scrollBox.verticalBarVisible) {\n                    self.ctx.fillStyle = self.style.scrollBarBackgroundColor;\n                    fillRect(en.verticalBar.x, en.verticalBar.y, en.verticalBar.width, en.verticalBar.height + m);\n                    strokeRect(en.verticalBar.x, en.verticalBar.y, en.verticalBar.width, en.verticalBar.height + m);\n                    if (self.scrollBox.verticalBoxVisible) {\n                        self.ctx.fillStyle = self.style.scrollBarBoxColor;\n                        if (/vertical/.test(u.context)) {\n                            self.ctx.fillStyle = self.style.scrollBarActiveColor;\n                        }\n                        radiusRect(en.verticalBox.x, en.verticalBox.y, en.verticalBox.width,\n                            en.verticalBox.height, self.style.scrollBarBoxBorderRadius);\n                        self.ctx.stroke();\n                        self.ctx.fill();\n                    }\n                    drawCorner = true;\n                    self.visibleCells.unshift(en.verticalBar);\n                    self.visibleCells.unshift(en.verticalBox);\n                }\n                if (drawCorner) {\n                    //corner\n                    self.ctx.strokeStyle = self.style.scrollBarCornerBorderColor;\n                    self.ctx.fillStyle = self.style.scrollBarCornerBackgroundColor;\n                    radiusRect(en.corner.x, en.corner.y, en.corner.width, en.corner.height, 0);\n                    self.ctx.stroke();\n                    self.ctx.fill();\n                    self.visibleCells.unshift(en.corner);\n                }\n            }\n            function createHandlesOverlayArray(cell) {\n                if (self.attributes.allowMovingSelection || self.mobile) {\n                    if (cell.selectionBorderTop && cell.selectionBorderRight && self.mobile) {\n                        selectionHandles.push([cell, 'tr']);\n                        cell.selectionHandle = 'tr';\n                    }\n                    if (cell.selectionBorderTop && cell.selectionBorderLeft && self.mobile) {\n                        selectionHandles.push([cell, 'tl']);\n                        cell.selectionHandle = 'tl';\n                    }\n                    if (cell.selectionBorderBottom && cell.selectionBorderLeft && self.mobile) {\n                        selectionHandles.push([cell, 'bl']);\n                        cell.selectionHandle = 'bl';\n                    }\n                    if (cell.selectionBorderBottom && cell.selectionBorderRight\n                            && (self.attributes.selectionHandleBehavior !== 'none' || self.mobile)) {\n                        selectionHandles.push([cell, 'br']);\n                        cell.selectionHandle = 'br';\n                    }\n                }\n            }\n            function createBorderOverlayArray(cell, drawArray, propPrefix, offsetPoint) {\n                offsetPoint = offsetPoint || {x: 0, y: 0};\n                cell.selectionBorder = '';\n                if (!cell.isRowHeader\n                        && self.selections[cell.rowIndex + -offsetPoint.y]\n                        && self.selections[cell.rowIndex + -offsetPoint.y].indexOf(cell.columnIndex + -offsetPoint.x) !== -1) {\n                    if ((!self.selections[cell.rowIndex - 1 + -offsetPoint.y]\n                            || self.selections[cell.rowIndex - 1 + -offsetPoint.y].indexOf(cell.columnIndex + -offsetPoint.x) === -1\n                            || cell.rowIndex === 0)\n                            && !cell.isHeader) {\n                        drawArray.push([cell, 't']);\n                        cell[propPrefix + 'BorderTop'] = true;\n                        cell[propPrefix + 'Border'] += 't';\n                    }\n                    if (!self.selections[cell.rowIndex + 1 + -offsetPoint.y]\n                            || self.selections[cell.rowIndex + 1 + -offsetPoint.y].indexOf(cell.columnIndex + -offsetPoint.x) === -1) {\n                        drawArray.push([cell, 'b']);\n                        cell[propPrefix + 'BorderBottom'] = true;\n                        cell[propPrefix + 'Border'] += 'b';\n                    }\n                    if (!self.selections[cell.rowIndex + -offsetPoint.y] || cell.columnIndex === 0\n                            || self.selections[cell.rowIndex + -offsetPoint.y].indexOf(cell.columnIndex - 1 + -offsetPoint.x) === -1) {\n                        drawArray.push([cell, 'l']);\n                        cell[propPrefix + 'BorderLeft'] = true;\n                        cell[propPrefix + 'Border'] += 'l';\n                    }\n                    if (!self.selections[cell.rowIndex + -offsetPoint.y] || cell.columnIndex === s.length\n                            || self.selections[cell.rowIndex + -offsetPoint.y].indexOf(cell.columnIndex + 1 + -offsetPoint.x) === -1) {\n                        drawArray.push([cell, 'r']);\n                        cell[propPrefix + 'BorderRight'] = true;\n                        cell[propPrefix + 'Border'] += 'r';\n                    }\n                }\n            }\n            function drawCell(d, rowOrderIndex, rowIndex) {\n                return function drawEach(header, headerIndex, columnOrderIndex) {\n                    if (header.hidden) { return 0; }\n                    var cellStyle = header.style || 'cell',\n                        cellGridAttributes,\n                        cell,\n                        isHeader = /HeaderCell/.test(cellStyle),\n                        isCorner = /cornerCell/.test(cellStyle),\n                        isRowHeader = 'rowHeaderCell' === cellStyle,\n                        isColumnHeader = 'columnHeaderCell' === cellStyle,\n                        selected = self.selections[rowOrderIndex] && self.selections[rowOrderIndex].indexOf(columnOrderIndex) !== -1,\n                        hovered = self.hovers.rowIndex === rowOrderIndex && self.hovers.columnIndex === columnOrderIndex,\n                        active = self.activeCell.rowIndex === rowOrderIndex && self.activeCell.columnIndex === columnOrderIndex,\n                        isColumnHeaderCellCap = cellStyle === 'columnHeaderCellCap',\n                        rawValue = d ? d[header.name] : undefined,\n                        isGrid = header.type === 'canvas-datagrid',\n                        activeHeader = (self.orders.rows[self.activeCell.rowIndex] === rowOrderIndex\n                                || self.orders.columns[self.activeCell.columnIndex] === headerIndex)\n                            && (columnOrderIndex === -1 || rowOrderIndex === -1)\n                            ? (isRowHeader ? 'activeRowHeaderCell' : 'activeColumnHeaderCell') : false,\n                        val,\n                        f = self.formatters[header.type || 'string'],\n                        orderByArrowSize = 0,\n                        treeArrowSize = 0,\n                        cellWidth = self.sizes.columns[headerIndex] || header.width,\n                        ev = {\n                            value: rawValue,\n                            row: d,\n                            header: header\n                        };\n                    if (isColumnHeaderCellCap) {\n                        cellWidth = w - x;\n                    }\n                    // if no data or schema are defined, a width is provided to the stub column\n                    if (cellWidth === undefined) {\n                        cellWidth = self.style.cellWidth;\n                    }\n                    cellWidth = cellWidth * self.scale;\n                    if (x + cellWidth + self.style.cellBorderWidth < 0) {\n                        x += cellWidth + self.style.cellBorderWidth;\n                    }\n                    if (active && cellStyle !== 'cornerCell') {\n                        cellStyle = 'activeCell';\n                    }\n                    if (self.visibleRows.indexOf(rowIndex) === -1 && !isHeader) {\n                        self.visibleRows.push(rowIndex);\n                    }\n                    val = self.dispatchEvent('formatcellvalue', ev);\n                    cx = x;\n                    cy = y;\n                    if (cellStyle === 'cornerCell') {\n                        cx = 0;\n                        cy = 0;\n                    } else if (isRowHeader) {\n                        cx = 0;\n                    } else if (isHeader) {\n                        cy = 0;\n                    }\n                    cell = {\n                        type: isGrid ? 'canvas-datagrid-cell' : header.type,\n                        style: cellStyle,\n                        nodeType: 'canvas-datagrid-cell',\n                        x: cx,\n                        y: cy,\n                        fontHeight: (self.style[cellStyle + 'FontHeight'] || 0) * self.scale,\n                        horizontalAlignment: self.style[cellStyle + 'HorizontalAlignment'],\n                        verticalAlignment: self.style[cellStyle + 'VerticalAlignment'],\n                        paddingLeft: (self.style[cellStyle + 'PaddingLeft'] || 0) * self.scale,\n                        paddingTop: (self.style[cellStyle + 'PaddingTop'] || 0) * self.scale,\n                        paddingRight: (self.style[cellStyle + 'PaddingRight'] || 0) * self.scale,\n                        paddingBottom: (self.style[cellStyle + 'PaddingBottom'] || 0) * self.scale,\n                        whiteSpace: self.style.cellWhiteSpace,\n                        lineHeight: self.style.cellLineHeight,\n                        lineSpacing: self.style.cellLineSpacing,\n                        offsetTop: self.canvasOffsetTop + cy,\n                        offsetLeft: self.canvasOffsetLeft + cx,\n                        scrollTop: self.scrollBox.scrollTop,\n                        scrollLeft: self.scrollBox.scrollLeft,\n                        active: active || activeHeader,\n                        hovered: hovered,\n                        selected: selected,\n                        width: cellWidth,\n                        height: cellHeight,\n                        offsetWidth: cellWidth,\n                        offsetHeight: cellHeight,\n                        parentNode: self.intf.parentNode,\n                        offsetParent: self.intf.parentNode,\n                        data: d,\n                        isCorner: isCorner,\n                        isHeader: isHeader,\n                        isColumnHeader: isColumnHeader,\n                        isColumnHeaderCellCap: isColumnHeaderCellCap,\n                        isRowHeader: isRowHeader,\n                        rowOpen: rowOpen,\n                        header: header,\n                        columnIndex: columnOrderIndex,\n                        rowIndex: rowOrderIndex,\n                        sortColumnIndex: headerIndex,\n                        sortRowIndex: rowIndex,\n                        isGrid: isGrid,\n                        isNormal: !isGrid && !isCorner && !isHeader,\n                        gridId: (self.attributes.name || '') + rowIndex + ':' + headerIndex,\n                        parentGrid: self.intf,\n                        innerHTML: '',\n                        activeHeader: activeHeader,\n                        value: isHeader && !isRowHeader ? (header.title || header.name) : rawValue\n                    };\n                    cell.calculatedLineHeight = (cell.fontHeight * cell.lineHeight) + cell.lineSpacing;\n                    cell.paddedWidth = cell.width - cell.paddingRight - cell.paddingLeft;\n                    cell.paddedHeight = cell.height - cell.paddingTop - cell.paddingBottom;\n                    ev.cell = cell;\n                    cell.userHeight = cell.isHeader ? self.sizes.rows[-1] : rowHeight;\n                    cell.userWidth = cell.isHeader ? self.sizes.columns.cornerCell : self.sizes.columns[headerIndex];\n                    self.visibleCells.unshift(cell);\n                    if (self.dispatchEvent('beforerendercell', ev)) { return; }\n                    self.ctx.fillStyle = self.style[cellStyle + 'BackgroundColor'];\n                    self.ctx.strokeStyle = self.style[cellStyle + 'BorderColor'];\n                    self.ctx.lineWidth = self.style[cellStyle + 'BorderWidth'];\n                    if (hovered) {\n                        self.ctx.fillStyle = self.style[cellStyle + 'HoverBackgroundColor'];\n                        self.ctx.strokeStyle = self.style[cellStyle + 'HoverBorderColor'];\n                    }\n                    if (selected) {\n                        self.ctx.fillStyle = self.style[cellStyle + 'SelectedBackgroundColor'];\n                        self.ctx.strokeStyle = self.style[cellStyle + 'SelectedBorderColor'];\n                    }\n                    if (activeHeader) {\n                        self.ctx.fillStyle = self.style[activeHeader + 'BackgroundColor'];\n                    }\n                    self.dispatchEvent('rendercell', ev);\n                    if (cell.isGrid) {\n                        if (cell.height !== rowHeight) {\n                            cell.height = rowHeight || self.style.cellHeightWithChildGrid;\n                            checkScrollHeight = true;\n                        }\n                        cell.width = self.sizes.columns[headerIndex] || self.style.cellWidthWithChildGrid;\n                    }\n                    if (rowOpen && !cell.isRowHeader) {\n                        cell.height = self.sizes.rows[rowIndex] || self.style.cellHeight;\n                    }\n                    if (!cell.isGrid) {\n                        fillRect(cx, cy, cell.width, cell.height);\n                        strokeRect(cx, cy, cell.width, cell.height);\n                    }\n                    self.ctx.save();\n                    radiusRect(cell.x, cell.y, cell.width, cell.height, 0);\n                    self.ctx.clip();\n                    self.dispatchEvent('afterrendercell', ev);\n                    if (cell.height !== cellHeight && !(rowOpen && !cell.isRowHeader)) {\n                        self.sizes.rows[isHeader ? -1 : rowIndex] = cell.height;\n                        checkScrollHeight = true;\n                    }\n                    if (cell.width !== cellWidth) {\n                        self.sizes.columns[headerIndex] = cell.width;\n                        checkScrollHeight = true;\n                    }\n                    if (isRowHeader && self.attributes.tree) {\n                        if (!self.dispatchEvent('rendertreearrow', ev)) {\n                            treeArrowSize = drawTreeArrow(cell, self.style[cellStyle + 'PaddingLeft'], cy, 0);\n                        }\n                    }\n                    if ((self.attributes.showRowNumbers && isRowHeader)\n                            || !isRowHeader) {\n                        if (cell.isGrid && !self.dispatchEvent('beforerendercellgrid', ev)) {\n                            if (!self.childGrids[cell.gridId]) {\n                                // HACK: this only allows setting of the child grids styles if data is set _after_\n                                // this is less than desirable.  An interface needs to be made to effect the\n                                // style of all cell grids.  One for individual grids already exists.\n                                cellGridAttributes = self.cellGridAttributes;\n                                cellGridAttributes.name = self.attributes.saveAppearance ? cell.gridId : undefined;\n                                cellGridAttributes.component = false;\n                                cellGridAttributes.parentNode = cell;\n                                cellGridAttributes.data = rawValue;\n                                ev.cellGridAttributes = cellGridAttributes;\n                                if (self.dispatchEvent('beforecreatecellgrid', ev)) { return; }\n                                self.childGrids[cell.gridId] = self.createGrid(cellGridAttributes);\n                                self.sizes.rows[rowIndex]\n                                    = self.sizes.rows[rowIndex] || self.style.cellGridHeight;\n                                checkScrollHeight = true;\n                            }\n                            cell.grid = self.childGrids[cell.gridId];\n                            cell.grid.parentNode = cell;\n                            cell.grid.visible = true;\n                            cell.grid.draw();\n                            self.dispatchEvent('rendercellgrid', ev);\n                        } else if (!cell.isGrid) {\n                            if (self.childGrids[cell.gridId]) {\n                                self.childGrids[cell.gridId].parentNode.offsetHeight = 0;\n                            }\n                            if (isHeader && self.orderBy === header.name) {\n                                if (!self.dispatchEvent('renderorderbyarrow', ev)) {\n                                    orderByArrowSize = drawOrderByArrow(cx + self.style[cellStyle + 'PaddingLeft'], 0);\n                                }\n                            }\n                            self.ctx.fillStyle = self.style[cellStyle + 'Color'];\n                            if (hovered) {\n                                self.ctx.fillStyle = self.style[cellStyle + 'HoverColor'];\n                            }\n                            if (selected) {\n                                self.ctx.fillStyle = self.style[cellStyle + 'SelectedColor'];\n                            }\n                            if (activeHeader) {\n                                self.ctx.fillStyle = self.style[activeHeader + 'Color'];\n                            }\n                            cell.treeArrowWidth = treeArrowSize;\n                            cell.orderByArrowWidth = orderByArrowSize;\n                            // create text ref to see if height needs to expand\n                            val = val !== undefined ? val : f\n                                ? f(ev) : '';\n                            if (val === undefined && !f) {\n                                val = '';\n                                console.warn('canvas-datagrid: Unknown format '\n                                    + header.type + ' add a cellFormater');\n                            }\n                            cell.formattedValue = ((val !== undefined && val !== null) ? val : '').toString();\n                            if (self.columnFilters && self.columnFilters[val] !== undefined && isHeader) {\n                                cell.formattedValue = self.attributes.filterTextPrefix + val;\n                            }\n                            self.ctx.font = (self.style[cellStyle + 'FontHeight'] * self.scale) + 'px ' + self.style[cellStyle + 'FontName'];\n                            if (!self.dispatchEvent('formattext', ev)) {\n                                cell.text = wrapText(cell, ' ');\n                            }\n                            if (!self.dispatchEvent('rendertext', ev)) {\n                                if (cell.innerHTML || header.type === 'html') {\n                                    drawHtml(cell);\n                                } else {\n                                    drawText(cell);\n                                }\n                            }\n                        }\n                    }\n                    if (active) {\n                        aCell = cell;\n                    }\n                    createBorderOverlayArray(cell, selectionBorders, 'selection');\n                    // createBorderOverlayArray calculates data for createHandlesOverlayArray so it must go 2nd\n                    createHandlesOverlayArray(cell);\n                    if (self.movingSelection) {\n                        createBorderOverlayArray(cell, moveBorders, 'move', self.moveOffset);\n                    }\n                    self.ctx.restore();\n                    x += cell.width + (bc ? 0 : self.style.cellBorderWidth);\n                    return cell.width;\n                };\n            }\n            function drawRowHeader(rowData, index, rowOrderIndex) {\n                var a, i;\n                if (self.attributes.showRowHeaders) {\n                    x = 0;\n                    i = index + 1;\n                    rowHeaderCell = {'rowHeaderCell': i };\n                    a = {\n                        name: 'rowHeaderCell',\n                        width: self.sizes.columns[-1] || self.style.rowHeaderCellWidth,\n                        style: 'rowHeaderCell',\n                        type: 'string',\n                        data: i,\n                        index: -1\n                    };\n                    rowOpen = self.openChildren[index];\n                    drawCell(rowHeaderCell, index, rowOrderIndex)(a, -1, -1);\n                }\n            }\n            function drawHeaders() {\n                var d, g = s.length, i, o, columnHeaderCell, header, nonFrozenHeaderWidth;\n                function drawHeaderColumnRange(start, end) {\n                    end = Math.min(end, g);\n                    for (o = start; o < end; o += 1) {\n                        i = self.orders.columns[o];\n                        header = s[i];\n                        if (!header.hidden) {\n                            d = {\n                                title: header.title,\n                                name: header.name,\n                                width: header.width || self.style.cellWidth,\n                                style: 'columnHeaderCell',\n                                type: 'string',\n                                index: o,\n                                order: i\n                            };\n                            columnHeaderCell = {'columnHeaderCell': header.title || header.name};\n                            x += drawCell(columnHeaderCell, -1, -1)(d, i, o);\n                            if (x > self.width + self.scrollBox.scrollLeft) {\n                                break;\n                            }\n                        }\n                    }\n                }\n                rowHeaders.forEach(function (rArgs, rhIndex) {\n                    y = rArgs[3];\n                    cellHeight = rArgs[4];\n                    if (rhIndex === self.frozenRow) {\n                        self.ctx.save();\n                        radiusRect(0, self.lastFrozenRowPixel, self.width, self.height - self.lastFrozenRowPixel, 0);\n                        self.ctx.clip();\n                    }\n                    drawRowHeader(rArgs[0], rArgs[1], rArgs[2]);\n                });\n                self.ctx.restore();\n                if (self.attributes.showColumnHeaders) {\n                    x = -self.scrollBox.scrollLeft + self.scrollPixelLeft + self.style.columnHeaderCellBorderWidth;\n                    if (self.attributes.showRowHeaders) {\n                        x += rowHeaderCellWidth;\n                    }\n                    y = 0;\n                    // cell height might have changed during drawing\n                    cellHeight = self.getColumnHeaderCellHeight();\n                    drawHeaderColumnRange(self.scrollIndexLeft, g);\n                    nonFrozenHeaderWidth = x;\n                    x = self.style.columnHeaderCellBorderWidth;\n                    if (self.attributes.showRowHeaders) {\n                        x += rowHeaderCellWidth;\n                    }\n                    drawHeaderColumnRange(0, self.frozenColumn);\n                    // fill in the space right of the headers\n                    x = nonFrozenHeaderWidth;\n                    if (x < w) {\n                        c = {\n                            name: '',\n                            width: self.style.scrollBarWidth,\n                            style: 'columnHeaderCellCap',\n                            isColumnHeaderCell: true,\n                            isColumnHeaderCellCap: true,\n                            type: 'string',\n                            index: s.length\n                        };\n                        drawCell({endCap: ''}, -1, -1)(c, -1, -1);\n                    }\n                    // fill in the space right of the headers\n                    if (self.attributes.showRowHeaders) {\n                        cornerCell = {'cornerCell': '' };\n                        x = 0;\n                        c = {\n                            name: 'cornerCell',\n                            width: self.style.rowHeaderCellWidth,\n                            style: 'cornerCell',\n                            type: 'string',\n                            index: -1\n                        };\n                        drawCell(cornerCell, -1, -1)(c, -1, -1);\n                    }\n                }\n            }\n            function drawRow(r, d) {\n                var i, treeHeight, rowSansTreeHeight, o, g = s.length;\n                if (y - (cellHeight * 2) > h) {\n                    return false;\n                }\n                rd = data[r];\n                rowOpen = self.openChildren[r];\n                rowSansTreeHeight = (self.sizes.rows[r] || self.style.cellHeight) * self.scale;\n                treeHeight = (rowOpen ? self.sizes.trees[r] : 0) * self.scale;\n                rowHeight = (rowSansTreeHeight + treeHeight);\n                if (y < -rowHeight) {\n                    return false;\n                }\n                if (self.attributes.showRowHeaders) {\n                    x += rowHeaderCellWidth;\n                }\n                cellHeight = rowHeight;\n                //draw normal columns\n                for (o = (self.scrollIndexLeft); o < g; o += 1) {\n                    i = self.orders.columns[o];\n                    x += drawCell(rd, r, d)(s[i], i, o);\n                    if (x > self.width) {\n                        self.scrollIndexRight = o;\n                        self.scrollPixelRight = x;\n                        break;\n                    }\n                }\n                //draw frozen columns\n                x = 0;\n                if (self.attributes.showRowHeaders) {\n                    x += rowHeaderCellWidth;\n                }\n                for (o = 0; o < self.frozenColumn; o += 1) {\n                    i = self.orders.columns[o];\n                    x += drawCell(rd, r, d)(s[i], i, o);\n                    if (x > self.width) {\n                        break;\n                    }\n                }\n                self.lastFrozenColumnPixel = x;\n                // cell height might have changed during drawing\n                cellHeight = rowHeight;\n                x = -self.scrollBox.scrollLeft + self.scrollPixelLeft + self.style.cellBorderWidth;\n                // don't draw a tree for the new row\n                treeGrid = self.childGrids[r];\n                if (r !== data.length && rowOpen) {\n                    treeGrid.visible = true;\n                    treeGrid.parentNode = {\n                        offsetTop: y + rowSansTreeHeight + self.canvasOffsetTop,\n                        offsetLeft: rowHeaderCellWidth - 1 + self.canvasOffsetLeft,\n                        offsetHeight: treeHeight,\n                        offsetWidth: self.width - rowHeaderCellWidth - self.style.scrollBarWidth - 1,\n                        offsetParent: self.intf.parentNode,\n                        parentNode: self.intf.parentNode,\n                        style: self.style,\n                        nodeType: 'canvas-datagrid-tree',\n                        scrollTop: self.scrollBox.scrollTop,\n                        scrollLeft: self.scrollBox.scrollLeft,\n                        rowIndex: r\n                    };\n                    self.visibleCells.unshift({\n                        rowIndex: r,\n                        columnIndex: 0,\n                        y: treeGrid.parentNode.offsetTop,\n                        x: treeGrid.parentNode.offsetLeft,\n                        height: treeGrid.height,\n                        width: treeGrid.width,\n                        style: 'tree-grid',\n                        type: treeGrid.parentNode.nodeType\n                    });\n                    treeGrid.draw();\n                } else if (treeGrid) {\n                    treeGrid.parentNode.offsetHeight = 0;\n                    delete self.sizes.trees[r];\n                }\n                rowHeaders.push([rd, r, d, y, rowHeight]);\n                self.visibleRowHeights[r] = rowHeight;\n                y += cellHeight + (bc ? 0 : self.style.cellBorderWidth);\n                return true;\n            }\n            function initDraw() {\n                self.visibleRows = [];\n                s = self.getSchema();\n                self.visibleCells = [];\n                self.canvasOffsetTop = self.isChildGrid ? self.parentNode.offsetTop : 0;\n                self.canvasOffsetLeft = self.isChildGrid ? self.parentNode.offsetLeft : 0;\n                h = self.height;\n                w = self.width;\n            }\n            function drawBackground() {\n                radiusRect(0, 0, w, h, 0);\n                self.ctx.clip();\n                self.ctx.fillStyle = self.style.gridBackgroundColor;\n                fillRect(0, 0, w, h);\n            }\n            function drawFrozenRows() {\n                var n, ln = Math.min(data.length, self.frozenRow);\n                x = -self.scrollBox.scrollLeft + self.scrollPixelLeft + self.style.cellBorderWidth;\n                y = columnHeaderCellHeight;\n                for (r = 0; r < ln; r += 1) {\n                    n = self.orders.rows[r];\n                    if (!drawRow(n, r)) {\n                        break;\n                    }\n                }\n                if (self.attributes.allowFreezingRows) {\n                    // HACK great, another stupid magic number.\n                    // Background will appear as a 0.5px artifact behind the row freeze bar without this hack\n                    y += self.style.frozenMarkerBorderWidth + self.style.frozenMarkerWidth - 0.4999999999;\n                }\n                self.lastFrozenRowPixel = y;\n            }\n            function drawRows() {\n                self.ctx.save();\n                if (self.frozenRow > 0) {\n                    radiusRect(0, self.lastFrozenRowPixel, self.width, self.height - self.lastFrozenRowPixel, 0);\n                    self.ctx.clip();\n                }\n                var o, n, i, g = s.length;\n                x = -self.scrollBox.scrollLeft + self.scrollPixelLeft + self.style.cellBorderWidth;\n                if (!self.attributes.snapToRow) {\n                    y += -self.scrollBox.scrollTop + self.scrollPixelTop + self.style.cellBorderWidth;\n                }\n                for (r = self.frozenRow + self.scrollIndexTop; r < l; r += 1) {\n                    n = self.orders.rows[r];\n                    self.scrollIndexBottom = r;\n                    self.scrollPixelBottom = y;\n                    if (!drawRow(n, r)) {\n                        break;\n                    }\n                }\n                if (self.attributes.showNewRow) {\n                    if (self.attributes.showRowHeaders) {\n                        x += rowHeaderCellWidth;\n                    }\n                    rowHeight = cellHeight = self.style.cellHeight;\n                    rowOpen = false;\n                    for (o = self.scrollIndexLeft; o < g; o += 1) {\n                        i = self.orders.columns[o];\n                        x += drawCell(self.newRow, data.length, data.length)(s[i], i, o);\n                        if (x > self.width + self.scrollBox.scrollLeft) {\n                            break;\n                        }\n                    }\n                    rowHeaders.push([self.newRow, data.length, data.length, y, rowHeight]);\n                }\n                self.ctx.restore();\n            }\n            function drawMoveMarkers() {\n                if (!self.movingSelection) { return; }\n                self.ctx.lineWidth = self.style.moveOverlayBorderWidth;\n                self.ctx.strokeStyle = self.style.moveOverlayBorderColor;\n                self.ctx.setLineDash(self.style.moveOverlayBorderSegments);\n                moveBorders.forEach(function (c) {\n                    addBorderLine(c[0], c[1]);\n                });\n                self.ctx.setLineDash([]);\n            }\n            function drawReorderMarkers() {\n                if (!self.reorderObject) { return; }\n                var b = {\n                        height: self.reorderObject.height,\n                        width: self.reorderObject.width,\n                        x: self.reorderObject.x + self.reorderObject.dragOffset.x,\n                        y: self.reorderObject.y + self.reorderObject.dragOffset.y\n                    },\n                    m = {\n                        width: w,\n                        height: h,\n                        x: 0,\n                        y: 0\n                    };\n                self.ctx.fillStyle = self.style.reorderMarkerBackgroundColor;\n                self.ctx.lineWidth = self.style.reorderMarkerBorderWidth;\n                self.ctx.strokeStyle = self.style.reorderMarkerBorderColor;\n                if (self.dragMode === 'row-reorder') {\n                    b.width = w;\n                    b.x = 0;\n                    m.width = w;\n                    m.height = self.currentCell.height;\n                    m.y = self.currentCell.y;\n                    fillRect(b.x, b.y, b.width, b.height);\n                    strokeRect(b.x, b.y, b.width, b.height);\n                    self.ctx.lineWidth = self.style.reorderMarkerIndexBorderWidth;\n                    self.ctx.strokeStyle = self.style.reorderMarkerIndexBorderColor;\n                    if (self.currentCell.rowIndex !== self.reorderObject.rowIndex\n                            && self.currentCell.rowIndex > -1\n                            && self.currentCell.rowIndex < l) {\n                        addBorderLine(m, self.reorderTarget.sortRowIndex > self.reorderObject.sortRowIndex ? 'b' : 't');\n                    }\n                } else if (self.dragMode === 'column-reorder' && self.reorderObject) {\n                    b.height = h;\n                    b.y = 0;\n                    m.height = h;\n                    m.width = self.currentCell.width;\n                    m.y = 0;\n                    m.x = self.currentCell.x;\n                    fillRect(b.x, b.y, b.width, b.height);\n                    strokeRect(b.x, b.y, b.width, b.height);\n                    self.ctx.lineWidth = self.style.reorderMarkerIndexBorderWidth;\n                    self.ctx.strokeStyle = self.style.reorderMarkerIndexBorderColor;\n                    if (self.currentCell.sortColumnIndex !== self.reorderObject.sortColumnIndex\n                            && self.currentCell.sortColumnIndex > -1\n                            && self.currentCell.sortColumnIndex < s.length) {\n                        addBorderLine(m, self.reorderTarget.columnIndex > self.reorderObject.columnIndex ? 'r' : 'l');\n                    }\n                }\n            }\n            function drawBorder() {\n                self.ctx.lineWidth = self.style.gridBorderWidth;\n                self.ctx.strokeStyle = self.style.gridBorderColor;\n                strokeRect(0, 0, self.width, self.height);\n            }\n            function drawSelectionBorders() {\n                self.ctx.lineWidth = self.style.selectionOverlayBorderWidth;\n                self.ctx.strokeStyle = self.style.selectionOverlayBorderColor;\n                function dsb(c) {\n                    addBorderLine(c[0], c[1]);\n                }\n                selectionBorders.filter(function (c) {\n                    return c[0].rowIndex < self.frozenRow && c[0].columnIndex < self.frozenColumn;\n                }).forEach(dsb);\n                self.ctx.save();\n                clipFrozenArea(0);\n                selectionBorders.filter(function (c) {\n                    return c[0].rowIndex >= self.frozenRow && c[0].columnIndex >= self.frozenColumn;\n                }).forEach(dsb);\n                self.ctx.restore();\n                self.ctx.save();\n                clipFrozenArea(1);\n                selectionBorders.filter(function (c) {\n                    return c[0].rowIndex >= self.frozenRow && c[0].columnIndex < self.frozenColumn;\n                }).forEach(dsb);\n                self.ctx.restore();\n                self.ctx.save();\n                clipFrozenArea(2);\n                selectionBorders.filter(function (c) {\n                    return c[0].rowIndex < self.frozenRow && c[0].columnIndex >= self.frozenColumn;\n                }).forEach(dsb);\n                self.ctx.restore();\n            }\n            function drawSelectionHandles() {\n                if (self.mobile || self.attributes.allowMovingSelection) {\n                    self.ctx.lineWidth = self.style.selectionHandleBorderWidth;\n                    self.ctx.strokeStyle = self.style.selectionHandleBorderColor;\n                    self.ctx.fillStyle = self.style.selectionHandleColor;\n                    selectionHandles.forEach(function (c) {\n                        addselectionHandle(c[0], c[1]);\n                        var az = self.attributes.touchSelectHandleZone / 2,\n                            ax = c[0].x + (c[1] === 'tl' || c[1] === 'bl' ? 0 : c[0].width) - az,\n                            ay = c[0].y + (c[1] === 'bl' || c[1] === 'br' ? c[0].height : 0) - az;\n                        self.visibleCells.unshift({\n                            x: ax,\n                            y: ay,\n                            height: self.style.selectionHandleSize + az,\n                            width: self.style.selectionHandleSize + az,\n                            style: 'selection-handle-' + c[1]\n                        });\n                    });\n                }\n            }\n            function drawActiveCell() {\n                if (!aCell) { return; }\n                self.ctx.save();\n                var cl = self.activeCell.columnIndex + 1 > self.frozenColumn || self.activeCell.rowIndex + 1 > self.frozenRow,\n                    acx = cl ? self.lastFrozenColumnPixel : 0,\n                    acy = cl ? self.lastFrozenRowPixel : 0,\n                    acw = cl ? self.width - self.lastFrozenColumnPixel : self.width,\n                    ach = cl ? self.height - self.lastFrozenRowPixel : self.height;\n                radiusRect(acx, acy, acw, ach, 0);\n                self.ctx.clip();\n                if (self.attributes.selectionMode === 'row') {\n                    if (self.activeCell && self.activeCell.rowIndex === aCell.rowIndex) {\n                        self.ctx.lineWidth = self.style.activeCellOverlayBorderWidth;\n                        self.ctx.strokeStyle = self.style.activeCellOverlayBorderColor;\n                        strokeRect(0, aCell.y, self.getHeaderWidth() + rowHeaderCellWidth, self.visibleRowHeights[aCell.rowIndex]);\n                    }\n                } else {\n                    self.ctx.lineWidth = self.style.activeCellOverlayBorderWidth;\n                    self.ctx.strokeStyle = self.style.activeCellOverlayBorderColor;\n                    strokeRect(aCell.x, aCell.y, aCell.width, aCell.height);\n                }\n                self.ctx.restore();\n            }\n            function drawFrozenMarkers() {\n                var my = self.lastFrozenRowPixel - self.style.frozenMarkerWidth,\n                    mx = self.lastFrozenColumnPixel - self.style.frozenMarkerBorderWidth,\n                    xHover = self.currentCell && self.currentCell.style === 'frozen-row-marker',\n                    yHover = self.currentCell && self.currentCell.style === 'frozen-column-marker';\n                self.ctx.lineWidth = self.style.frozenMarkerBorderWidth;\n                if (self.attributes.allowFreezingColumns) {\n                    self.ctx.fillStyle = yHover ? self.style.frozenMarkerHoverColor : self.style.frozenMarkerColor;\n                    self.ctx.strokeStyle = yHover ? self.style.frozenMarkerHoverBorderColor : self.style.frozenMarkerBorderColor;\n                    fillRect(mx, 0, self.style.frozenMarkerWidth, self.height);\n                    strokeRect(mx, 0, self.style.frozenMarkerWidth, self.height);\n                    self.visibleCells.unshift({\n                        x: mx,\n                        y: 0,\n                        height: self.height,\n                        width: self.style.frozenMarkerWidth + self.style.frozenMarkerBorderWidth,\n                        style: 'frozen-column-marker'\n                    });\n                }\n                if (self.attributes.allowFreezingRows) {\n                    self.ctx.fillStyle = xHover ? self.style.frozenMarkerHoverColor : self.style.frozenMarkerColor;\n                    self.ctx.strokeStyle = xHover ? self.style.frozenMarkerHoverBorderColor : self.style.frozenMarkerBorderColor;\n                    fillRect(0, my, self.width, self.style.frozenMarkerWidth);\n                    strokeRect(0, my, self.width, self.style.frozenMarkerWidth);\n                    self.visibleCells.unshift({\n                        x: 0,\n                        y: my,\n                        height: self.style.frozenMarkerWidth + self.style.frozenMarkerBorderWidth,\n                        width: self.width,\n                        style: 'frozen-row-marker'\n                    });\n                }\n                if (self.freezeMarkerPosition) {\n                    self.ctx.fillStyle = self.style.frozenMarkerActiveColor;\n                    self.ctx.strokeStyle = self.style.frozenMarkerActiveBorderColor;\n                    if (self.dragMode === 'frozen-column-marker') {\n                        fillRect(self.freezeMarkerPosition.x, 0, self.style.frozenMarkerWidth, self.height);\n                        strokeRect(self.freezeMarkerPosition.x, 0, self.style.frozenMarkerWidth, self.height);\n                    } else {\n                        fillRect(0, self.freezeMarkerPosition.y, self.width, self.style.frozenMarkerWidth);\n                        strokeRect(0, self.freezeMarkerPosition.y, self.width, self.style.frozenMarkerWidth);\n                    }\n                }\n            }\n            function drawPerfLines() {\n                if (!self.attributes.showPerformance) { return; }\n                var pw = 250,\n                    px = self.width - pw - self.style.scrollBarWidth - (self.style.scrollBarBorderWidth * 2),\n                    py = columnHeaderCellHeight,\n                    ph = 100;\n                if (scrollDebugCounters.length === 0) { scrollDebugCounters = fillArray(0, perfWindowSize, 1, function () { return [0, 0]; }); }\n                if (touchPPSCounters.length === 0) { touchPPSCounters = fillArray(0, perfWindowSize, 1, function () { return [0, 0]; }); }\n                if (entityCount.length === 0) { entityCount = fillArray(0, perfWindowSize, 1, 0); }\n                self.ctx.lineWidth = 0.5;\n                function dpl(name, perfArr, arrIndex, max, color, useAbs, rowIndex) {\n                    var v;\n                    drawPerfLine(pw, ph, px, py, perfArr, arrIndex, max, color, useAbs);\n                    self.ctx.fillStyle = color;\n                    fillRect(3 + px, py + 9 + (rowIndex * 11), 8, 8);\n                    self.ctx.fillStyle = self.style.debugPerfChartTextColor;\n                    v = arrIndex !== undefined ? perfArr[0][arrIndex] : perfArr[0];\n                    fillText(name + ' ' + (isNaN(v) ? 0 : v).toFixed(3), 14 + px, py + 16 + (rowIndex * 11));\n                }\n                self.ctx.textAlign = 'left';\n                self.ctx.font = self.style.debugFont;\n                self.ctx.fillStyle = self.style.debugPerfChartBackground;\n                fillRect(px, py, pw, ph);\n                [['Scroll Height', scrollDebugCounters, 0, self.scrollBox.scrollHeight, self.style.debugScrollHeightColor, false],\n                    ['Scroll Width', scrollDebugCounters, 1, self.scrollBox.scrollWidth, self.style.debugScrollWidthColor, false],\n                    ['Performance', perfCounters, undefined, 200, self.style.debugPerformanceColor, false],\n                    ['Entities', entityCount, undefined, 1500, self.style.debugEntitiesColor, false],\n                    ['TouchPPSX', touchPPSCounters, 0, 1000, self.style.debugTouchPPSXColor, true],\n                    ['TouchPPSY', touchPPSCounters, 1, 1000, self.style.debugTouchPPSYColor, true]\n                    ].forEach(function (i, index) {\n                    i.push(index);\n                    dpl.apply(null, i);\n                });\n                self.ctx.fillStyle = self.style.debugPerfChartBackground;\n                entityCount.pop();\n                entityCount.unshift(self.visibleCells.length);\n                scrollDebugCounters.pop();\n                scrollDebugCounters.unshift([self.scrollBox.scrollTop, self.scrollBox.scrollLeft]);\n                touchPPSCounters.pop();\n                touchPPSCounters.unshift([self.yPPS, self.xPPS]);\n            }\n            function drawDebug() {\n                self.ctx.save();\n                var d;\n                if (self.attributes.showPerformance || self.attributes.debug) {\n                    if (perfCounters.length === 0) { perfCounters = fillArray(0, perfWindowSize, 1, 0); }\n                    perfCounters.pop();\n                    perfCounters.unshift(performance.now() - p);\n                }\n                if (!self.attributes.debug) {\n                    self.ctx.restore();\n                    return;\n                }\n                self.ctx.font = self.style.debugFont;\n                d = {};\n                d.perf = (perfCounters.reduce(function (a, b) {\n                    return a + b;\n                }, 0) / Math.min(drawCount, perfCounters.length)).toFixed(1);\n                d.perfDelta = perfCounters[0].toFixed(1);\n                d.frozenColumnsWidth = getFrozenColumnsWidth();\n                d.htmlImages = Object.keys(self.htmlImageCache).length;\n                d.reorderObject = 'x: ' + (self.reorderObject || {columnIndex: 0}).columnIndex + ', y: ' + (self.reorderObject || {rowIndex: 0}).rowIndex;\n                d.reorderTarget = 'x: ' + (self.reorderTarget || {columnIndex: 0}).columnIndex + ', y: ' + (self.reorderTarget || {rowIndex: 0}).rowIndex;\n                d.scale = self.scale;\n                d.startScale = self.startScale;\n                d.scaleDelta = self.scaleDelta;\n                d.zoomDeltaStart = self.zoomDeltaStart;\n                d.touchLength = self.touchLength;\n                d.touches = 'y0: ' + (self.touchPosition || {y: 0}).y + ' y1: ' + (self.touchPosition1 || {y: 0}).y;\n                d.scrollBox = self.scrollBox.toString();\n                d.scrollIndex = 'x: ' + self.scrollIndexLeft + ', y: ' + self.scrollIndexTop;\n                d.scrollPixel = 'x: ' + self.scrollPixelLeft + ', y: ' + self.scrollPixelTop;\n                d.canvasOffset = 'x: ' + self.canvasOffsetLeft + ', y: ' + self.canvasOffsetTop;\n                d.touchDelta = 'x: ' + self.touchDelta.x + ', y: ' + self.touchDelta.y;\n                d.touchAnimateTo = 'x: ' + self.touchAnimateTo.x + ', y: ' + self.touchAnimateTo.y;\n                d.scrollAnimation = 'x: ' + self.scrollAnimation.x + ', y: ' + self.scrollAnimation.y;\n                d.touchPPS = 'x: ' + self.xPPS + ', y: ' + self.yPPS;\n                d.touchPPST = 'x: ' + self.xPPST + ', y: ' + self.yPPST;\n                d.touchDuration = self.touchDuration;\n                d.pointerLockPosition =  self.pointerLockPosition ?\n                        self.pointerLockPosition.x + ', ' + self.pointerLockPosition.y : '';\n                d.size = 'w: ' + self.width + ', h: ' + self.height;\n                d.mouse = 'x: ' + self.mouse.x + ', y: ' + self.mouse.y;\n                d.touch = !self.touchStart\n                    ? '' : 'x: ' + self.touchStart.x + ', y: ' + self.touchStart.y;\n                d.entities = self.visibleCells.length;\n                d.hasFocus = self.hasFocus;\n                d.dragMode = self.dragMode;\n                if (self.currentCell) {\n                    d.columnIndex = self.currentCell.columnIndex;\n                    d.rowIndex = self.currentCell.rowIndex;\n                    d.sortColumnIndex = self.currentCell.sortColumnIndex;\n                    d.sortRowIndex = self.currentCell.sortRowIndex;\n                    d.context = self.currentCell.context;\n                    d.dragContext = self.currentCell.dragContext;\n                    d.style = self.currentCell.style;\n                    d.type = self.currentCell.type;\n                }\n                self.ctx.textAlign = 'right';\n                self.ctx.fillStyle = self.style.debugBackgroundColor;\n                fillRect(0, 0, self.width, self.height);\n                Object.keys(d).forEach(function (key, index) {\n                    var m = key + ': ' + d[key],\n                        lh = 14;\n                    self.ctx.fillStyle = self.style.debugColor;\n                    fillText(m, w - 20, (self.attributes.showPerformance ? 140 : 24) + (index * lh));\n                });\n                self.ctx.restore();\n            }\n            self.ctx.save();\n            initDraw();\n            drawBackground();\n            drawFrozenRows();\n            drawRows();\n            drawActiveCell();\n            drawHeaders();\n            drawFrozenMarkers();\n            drawSelectionHandles();\n            drawReorderMarkers();\n            drawMoveMarkers();\n            drawBorder();\n            drawSelectionBorders();\n            drawScrollBars();\n            if (checkScrollHeight) {\n                self.resize(true);\n            }\n            drawDebug();\n            drawPerfLines();\n            if (self.dispatchEvent('afterdraw', {})) { return; }\n            self.ctx.restore();\n        };\n    };\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/draw.js\n// module id = 3\n// module chunks = 0","/*jslint browser: true, unparam: true, todo: true, plusplus: true*/\n/*globals define: true, MutationObserver: false, requestAnimationFrame: false, performance: false, btoa: false*/\ndefine([], function () {\n    'use strict';\n    return function (self) {\n        var wheeling;\n        self.stopPropagation = function (e) { e.stopPropagation(); };\n        /**\n         * Adds an event listener to the given event.\n         * @memberof canvasDatagrid\n         * @name addEventListener\n         * @method\n         * @param {string} ev The name of the event to subscribe to.\n         * @param {function} fn The event procedure to execute when the event is raised.\n         */\n        self.addEventListener = function (ev, fn) {\n            self.events[ev] = self.events[ev] || [];\n            self.events[ev].unshift(fn);\n        };\n        /**\n         * Removes the given listener function from the given event.  Must be an actual reference to the function that was bound.\n         * @memberof canvasDatagrid\n         * @name removeEventListener\n         * @method\n         * @param {string} ev The name of the event to unsubscribe from.\n         * @param {function} fn The event procedure to execute when the event is raised.\n         */\n        self.removeEventListener = function (ev, fn) {\n            (self.events[ev] || []).forEach(function removeEachListener(sfn, idx) {\n                if (fn === sfn) {\n                    self.events[ev].splice(idx, 1);\n                }\n            });\n        };\n        /**\n         * Fires the given event, padding an event object to the event subscribers.\n         * @memberof canvasDatagrid\n         * @name dispatchEvent\n         * @method\n         * @param {number} ev The name of the event to dispatch.\n         * @param {number} e The event object.\n         */\n        self.dispatchEvent = function (ev, e) {\n            e = ev.type ? ev : (e || {});\n            ev = ev.type || ev;\n            var defaultPrevented;\n            function preventDefault() {\n                defaultPrevented = true;\n            }\n            if (!self.events[ev]) { return; }\n            self.events[ev].forEach(function dispatchEachEvent(fn) {\n                e.ctx = self.ctx;\n                e.preventDefault = preventDefault;\n                fn.apply(self.intf, [e]);\n            });\n            return defaultPrevented;\n        };\n        self.getRatio = function () {\n            return Math.min(self.attributes.maxPixelRatio, (window.devicePixelRatio || 1) /\n                (self.ctx.webkitBackingStorePixelRatio ||\n                    self.ctx.mozBackingStorePixelRatio ||\n                    self.ctx.msBackingStorePixelRatio ||\n                    self.ctx.oBackingStorePixelRatio ||\n                    self.ctx.backingStorePixelRatio || 1));\n        };\n        self.resize = function (drawAfterResize) {\n            if (!self.canvas) { return; }\n            var x,\n                v = {\n                    x: 0,\n                    y: 0,\n                    height: 0,\n                    width: 0,\n                    style: 'vertical-scroll-bar'\n                },\n                n = {\n                    x: 0,\n                    y: 0,\n                    height: 0,\n                    width: 0,\n                    style: 'horizontal-scroll-bar'\n                },\n                vb = {\n                    x: 0,\n                    y: 0,\n                    height: 0,\n                    width: 0,\n                    style: 'vertical-scroll-box'\n                },\n                nb = {\n                    x: 0,\n                    y: 0,\n                    height: 0,\n                    width: 0,\n                    style: 'horizontal-scroll-box'\n                },\n                co = {\n                    x: 0,\n                    y: 0,\n                    height: 0,\n                    width: 0,\n                    isCorner: true,\n                    isScrollBoxCorner: true,\n                    style: 'scroll-box-corner'\n                },\n                m = (self.style.scrollBarBoxMargin * 2),\n                b = (self.style.scrollBarBorderWidth * 2),\n                d = self.style.scrollBarBoxMargin * 0.5,\n                sbw = self.style.scrollBarWidth + (self.style.scrollBarBorderWidth * 2),\n                ratio = self.getRatio(),\n                bm = self.style.gridBorderCollapse === 'collapse' ? 1 : 2,\n                cellBorder = self.style.cellBorderWidth * bm,\n                columnHeaderCellBorder = self.style.columnHeaderCellBorderWidth * bm,\n                dataHeight = 0,\n                dataWidth = 0,\n                dims,\n                l = (self.data || []).length,\n                columnHeaderCellHeight = self.getColumnHeaderCellHeight(),\n                rowHeaderCellWidth = self.getRowHeaderCellWidth(),\n                ch = self.style.cellHeight,\n                s = self.getSchema();\n            // sets actual DOM canvas element\n            function checkScrollBoxVisibility() {\n                self.scrollBox.horizontalBarVisible = (self.style.width !== 'auto' && dataWidth > self.scrollBox.width && self.style.overflowX !== 'hidden')\n                    || self.style.overflowX === 'scroll';\n                self.scrollBox.horizontalBoxVisible = dataWidth > self.scrollBox.width;\n                self.scrollBox.verticalBarVisible = (self.style.height !== 'auto' && dataHeight > self.scrollBox.height && self.style.overflowY !== 'hidden')\n                    || self.style.overflowY === 'scroll';\n                self.scrollBox.verticalBoxVisible = dataHeight > self.scrollBox.height;\n            }\n            function setScrollBoxSize() {\n                self.scrollBox.width = self.width - rowHeaderCellWidth;\n                self.scrollBox.height = self.height - columnHeaderCellHeight;\n            }\n            function setCanvasSize() {\n                if (self.isChildGrid) {\n                    return;\n                }\n                dims = {\n                    // HACK +1 ? maybe it's a magic cell border?  Required to line up properly in auto height mode.\n                    height: columnHeaderCellHeight + dataHeight + cellBorder + 1,\n                    width: dataWidth + rowHeaderCellWidth + cellBorder\n                };\n                ['width', 'height'].forEach(function (dim) {\n                    //TODO: support inherit\n                    if (['auto', undefined].indexOf(self.style[dim]) !== -1\n                            && ['auto', undefined].indexOf(self.appliedInlineStyles[dim]) !== -1) {\n                        self.parentNodeStyle[dim] = dims[dim] + 'px';\n                    } else {\n                        self.parentNodeStyle[dim] = self.style[dim];\n                        if (self.isComponet) {\n                            self.canvas.style[dim] = self.style[dim];\n                        }\n                    }\n                });\n            }\n            self.scrollCache.x = [];\n            self.scrollCache.y = [];\n            for (x = 0; x < l; x += 1) {\n                self.scrollCache.y[x] = dataHeight;\n                dataHeight += (((self.sizes.rows[x] || ch) + (self.sizes.trees[x] || 0)) * self.scale)\n                    // HACK? if an expanded tree row is frozen it is necessary to add the tree row's height a second time.\n                    + (self.frozenRow > x ? (self.sizes.trees[x] || 0) : 0);\n            }\n            if (l > 1) {\n                self.scrollCache.y[x] = dataHeight;\n            }\n            dataWidth = s.reduce(function reduceSchema(accumulator, column, columnIndex) {\n                // intentional redefintion of column.  This causes scrollCache to be in the correct order\n                column = s[self.orders.columns[columnIndex]];\n                if (column.hidden) {\n                    self.scrollCache.x[columnIndex] = accumulator;\n                    return accumulator;\n                }\n                var va = accumulator + self.getColummnWidth(self.orders.columns[columnIndex]);\n                self.scrollCache.x[columnIndex] = va;\n                return va;\n            }, 0) || 0;\n            if (self.attributes.showNewRow) {\n                dataHeight += ch;\n            }\n            if (self.attributes.snapToRow) {\n              dataHeight += self.style.cellHeight;\n            }\n            setCanvasSize();\n            if (self.isChildGrid) {\n                self.width = self.parentNode.offsetWidth;\n                self.height = self.parentNode.offsetHeight;\n            } else if (self.height !== self.canvas.offsetHeight || self.width !== self.canvas.offsetWidth) {\n                self.height = self.canvas.offsetHeight;\n                self.width = self.canvas.offsetWidth;\n                self.canvasOffsetLeft = self.args.canvasOffsetLeft || 0;\n                self.canvasOffsetTop = self.args.canvasOffsetTop || 0;\n            }\n            /// calculate scroll bar dimensions\n            // non-controversial\n            self.scrollBox.top = columnHeaderCellHeight + columnHeaderCellBorder;\n            self.scrollBox.left = rowHeaderCellWidth;\n            // width and height of scroll box\n            setScrollBoxSize();\n            // is the data larger than the scroll box\n            checkScrollBoxVisibility();\n            // if the scroll box is visible, make room for it by expanding the size of the element\n            // if the other dimension is set to auto\n            if (self.scrollBox.horizontalBarVisible) {\n                if (self.style.height === 'auto' && !self.isChildGrid) {\n                    self.height += sbw;\n                }\n                dataHeight += sbw;\n                setCanvasSize();\n                setScrollBoxSize();\n                checkScrollBoxVisibility();\n            }\n            if (self.scrollBox.verticalBarVisible) {\n                if (self.style.width === 'auto' && !self.isChildGrid) {\n                    self.width += sbw;\n                }\n                dataWidth += sbw;\n                setCanvasSize();\n                setScrollBoxSize();\n                checkScrollBoxVisibility();\n            }\n            // set again after bar visibility checks\n            setScrollBoxSize();\n            self.scrollBox.scrollWidth = dataWidth - self.scrollBox.width;\n            self.scrollBox.scrollHeight = dataHeight - self.scrollBox.height;\n            self.scrollBox.widthBoxRatio = self.scrollBox.width / dataWidth;\n            self.scrollBox.scrollBoxWidth = self.scrollBox.width\n                * self.scrollBox.widthBoxRatio\n                - self.style.scrollBarWidth - b - d;\n            // TODO: This heightBoxRatio number is terribly wrong.\n            // They should be a result of the size of the grid/canvas?\n            // it being off causes the scroll bar to \"slide\" under\n            // the dragged mouse.\n            // https://github.com/TonyGermaneri/canvas-datagrid/issues/97\n            self.scrollBox.heightBoxRatio = (self.scrollBox.height - columnHeaderCellHeight) / dataHeight;\n            self.scrollBox.scrollBoxHeight = self.scrollBox.height\n                * self.scrollBox.heightBoxRatio\n                - self.style.scrollBarWidth - b - d;\n            self.scrollBox.scrollBoxWidth = Math.max(self.scrollBox.scrollBoxWidth, self.style.scrollBarBoxMinSize);\n            self.scrollBox.scrollBoxHeight = Math.max(self.scrollBox.scrollBoxHeight, self.style.scrollBarBoxMinSize);\n            // horizontal\n            n.x += rowHeaderCellWidth;\n            n.y += self.height - self.style.scrollBarWidth - d;\n            n.width = self.width - self.style.scrollBarWidth - rowHeaderCellWidth - d - m;\n            n.height = self.style.scrollBarWidth + self.style.scrollBarBorderWidth + d;\n            // horizontal box\n            nb.y = n.y + self.style.scrollBarBoxMargin;\n            nb.width = self.scrollBox.scrollBoxWidth;\n            nb.height = self.style.scrollBarBoxWidth;\n            // vertical\n            v.x += self.width - self.style.scrollBarWidth - self.style.scrollBarBorderWidth - d;\n            v.y += columnHeaderCellHeight;\n            v.width = self.style.scrollBarWidth + self.style.scrollBarBorderWidth + d;\n            v.height = self.height - columnHeaderCellHeight - self.style.scrollBarWidth - d - m;\n            // vertical box\n            vb.x = v.x + self.style.scrollBarBoxMargin;\n            vb.width = self.style.scrollBarBoxWidth;\n            vb.height = self.scrollBox.scrollBoxHeight;\n            // corner\n            co.x = n.x + n.width + m;\n            co.y = v.y + v.height + m;\n            co.width = self.style.scrollBarWidth + self.style.scrollBarBorderWidth;\n            co.height = self.style.scrollBarWidth + self.style.scrollBarBorderWidth;\n            self.scrollBox.entities = {\n                horizontalBar: n,\n                horizontalBox: nb,\n                verticalBar: v,\n                verticalBox: vb,\n                corner: co\n            };\n            self.scrollBox.bar = {\n                v: v,\n                h: n\n            };\n            self.scrollBox.box = {\n                v: vb,\n                h: nb\n            };\n            /// calculate page and dom elements\n            self.page = Math.max(1, self.visibleRows.length - 3 - self.attributes.pageUpDownOverlap);\n            // set canvas drawing related items\n            if (!self.isChildGrid) {\n                self.canvas.width = self.width * ratio;\n                self.canvas.height = self.height * ratio;\n                self.ctx.scale(ratio, ratio);\n            }\n            // resize any open dom elements (input/textarea)\n            self.resizeEditInput();\n            self.scroll(true);\n            if (drawAfterResize) {\n                self.draw(true);\n            }\n            self.dispatchEvent('resize', {});\n            return true;\n        };\n        self.scroll = function (dontDraw) {\n            var s = self.getSchema(),\n                l = (self.data || []).length,\n                ch = self.style.cellHeight;\n            // go too far in leaps, then get focused\n            self.scrollIndexTop = Math.floor((l * (self.scrollBox.scrollTop / self.scrollBox.scrollHeight)) - 100);\n            self.scrollIndexTop = Math.max(self.scrollIndexTop, 0);\n            self.scrollPixelTop = self.scrollCache.y[self.scrollIndexTop];\n            // sometimes the grid is rendered but the height is zero\n            if (self.scrollBox.scrollHeight === 0) {\n                self.scrollIndexTop = 0;\n            }\n            self.scrollPixelTop = 0;\n            self.scrollIndexLeft = self.frozenColumn;\n            self.scrollPixelLeft = 0;\n            while (self.scrollPixelTop < self.scrollBox.scrollTop && self.scrollIndexTop < self.data.length) {\n                // start on index +1 since index 0 was used in \"go too far\" section above\n                self.scrollIndexTop += 1;\n                self.scrollPixelTop = self.scrollCache.y[self.scrollIndexTop];\n            }\n            while (self.scrollPixelLeft < (self.scrollBox.scrollLeft + 1) && self.scrollIndexLeft < s.length) {\n                self.scrollPixelLeft = self.scrollCache.x[self.scrollIndexLeft];\n                self.scrollIndexLeft += 1;\n            }\n            if (s.length > 0) {\n                self.scrollIndexLeft = Math.max(self.scrollIndexLeft - 1, 0);\n                self.scrollPixelLeft -= self.getColummnWidth(self.orders.columns[self.scrollIndexLeft]);\n            }\n            if ((self.data || []).length > 0) {\n                self.scrollIndexTop = Math.max(self.scrollIndexTop - 1, 0);\n                self.scrollPixelTop = Math.max((self.scrollPixelTop\n                    - (\n                        self.data[self.scrollIndexTop] ? (self.sizes.rows[self.scrollIndexTop] || ch)\n                                + (self.sizes.trees[self.scrollIndexTop] || 0)\n                        : ch\n                    ) * self.scale), 0);\n            }\n            self.ellipsisCache = {};\n            if (!dontDraw) {\n                self.draw(true);\n            }\n            //TODO: figure out why this has to be delayed for child grids\n            //BUG: wheeling event on 3rd level hierarchy fails to move input box\n            requestAnimationFrame(self.resizeEditInput);\n            self.dispatchEvent('scroll', {top: self.scrollBox.scrollTop, left: self.scrollBox.scrollLeft});\n        };\n        self.mousemove = function (e, overridePos) {\n            if (self.contextMenu || self.input) {\n                return;\n            }\n            self.mouse = overridePos || self.getLayerPos(e);\n            var ctrl = ((e.ctrlKey || e.metaKey || self.attributes.persistantSelectionMode) && !self.attributes.singleSelectionMode),\n                i,\n                s = self.getSchema(),\n                dragBounds,\n                sBounds,\n                x = self.mouse.x,\n                y = self.mouse.y,\n                o = self.getCellAt(x, y),\n                delta,\n                ev = {NativeEvent: e, cell: o, x: x, y: y},\n                previousCell = self.currentCell;\n            clearTimeout(self.scrollTimer);\n            if (!self.isInGrid({x: x, y: y})) {\n                self.hasFocus = false;\n            }\n            if (self.dispatchEvent('mousemove', ev)) {\n                return;\n            }\n            if (o && self.currentCell) {\n                self.rowBoundaryCrossed = self.currentCell.rowIndex !== o.rowIndex;\n                self.columnBoundaryCrossed = self.currentCell.columnIndex !== o.columnIndex;\n                self.cellBoundaryCrossed = self.rowBoundaryCrossed || self.columnBoundaryCrossed;\n                ['row', 'column', 'cell'].forEach(function (prefix) {\n                    if (self[prefix + 'BoundaryCrossed']) {\n                        ev.cell = previousCell;\n                        self.dispatchEvent(prefix + 'mouseout', ev);\n                        ev.cell = o;\n                        self.dispatchEvent(prefix + 'mouseover', ev);\n                    }\n                });\n            }\n            self.currentCell = o;\n            if (!self.hasFocus) {\n                return;\n            }\n            self.hovers = {};\n            if (!self.draggingItem\n                    && o\n                    && self.scrollModes.indexOf(o.context) === -1) {\n                self.dragItem = o;\n                self.dragMode = o.dragContext;\n                self.cursor = o.context;\n                if (o.context === 'cell') {\n                    self.cursor = 'default';\n                    self.hovers = { rowIndex: o.rowIndex, columnIndex: o.columnIndex };\n                }\n                if ((self.selecting || self.reorderObject)\n                        && o.context === 'cell') {\n                    delta = {\n                        x: Math.abs(self.dragStart.x - x),\n                        y: Math.abs(self.dragStart.y - y)\n                    };\n                    if (self.dragStartObject.columnIndex !== -1 && e.shiftKey) {\n                        self.dragStartObject = {\n                            rowIndex: self.activeCell.rowIndex,\n                            columnIndex: self.activeCell.columnIndex\n                        };\n                    }\n                    dragBounds = {\n                        top: Math.min(self.dragStartObject.rowIndex, o.rowIndex),\n                        left: Math.min(self.dragStartObject.columnIndex, o.columnIndex),\n                        bottom: Math.max(self.dragStartObject.rowIndex, o.rowIndex),\n                        right: Math.max(self.dragStartObject.columnIndex, o.columnIndex)\n                    };\n                    if (self.dragStartObject.columnIndex === -1) {\n                        sBounds = self.getSelectionBounds();\n                        dragBounds.left = -1;\n                        dragBounds.right = s.length - 1;\n                        dragBounds.top = Math.min(sBounds.top, o.rowIndex);\n                        dragBounds.bottom = Math.max(sBounds.bottom, o.rowIndex);\n                    }\n                    if (self.dragStartObject.rowIndex !== o.rowIndex\n                                || self.dragStartObject.columnIndex !== o.columnIndex) {\n                        self.ignoreNextClick = true;\n                    }\n                    if (self.cellBoundaryCrossed || (delta.x === 0 && delta.y === 0) || (self.attributes.selectionMode === 'row')) {\n                        if (((self.attributes.selectionMode === 'row') || self.dragStartObject.columnIndex === -1)\n                                && self.rowBoundaryCrossed) {\n                            self.selectRow(o.rowIndex, ctrl, null, true);\n                        } else if (self.attributes.selectionMode !== 'row') {\n                            if (!self.dragAddToSelection && o.rowIndex !== undefined) {\n                                if (self.selections[o.rowIndex] && self.selections[o.rowIndex].indexOf(o.columnIndex) !== -1) {\n                                    self.selections[o.rowIndex].splice(self.selections[o.rowIndex].indexOf(o.columnIndex), 1);\n                                }\n                            } else {\n                                self.selections[o.rowIndex] = self.selections[o.rowIndex] || [];\n                                if (self.selections[o.rowIndex].indexOf(o.columnIndex) === -1) {\n                                    self.selections[o.rowIndex].push(o.columnIndex);\n                                }\n                            }\n                        }\n                    }\n                    if ((!self.selectionBounds || (dragBounds.top !== self.selectionBounds.top\n                            || dragBounds.left !== self.selectionBounds.left\n                            || dragBounds.bottom !== self.selectionBounds.bottom\n                            || dragBounds.right !== self.selectionBounds.right)) && !ctrl) {\n                        self.selections = [];\n                        sBounds = dragBounds;\n                        if (self.attributes.selectionMode === 'row') {\n                            for (i = sBounds.top; i <= sBounds.bottom; i += 1) {\n                                self.selectRow(i, true, null, true);\n                            }\n                        } else if (dragBounds.top !== -1) {\n                            self.selectArea(sBounds, true);\n                        }\n                    }\n                    self.autoScrollZone(e, x, y, ctrl);\n                }\n            }\n            self.cellBoundaryCrossed = false;\n            self.rowBoundaryCrossed = false;\n            self.columnBoundaryCrossed = false;\n            self.draw(true);\n        };\n        self.click = function (e, overridePos) {\n            var i,\n                startingBounds = JSON.stringify(self.getSelectionBounds()),\n                ctrl = ((e.ctrlKey || e.metaKey || self.attributes.persistantSelectionMode) && !self.attributes.singleSelectionMode),\n                pos = overridePos || self.getLayerPos(e);\n            self.currentCell = self.getCellAt(pos.x, pos.y);\n            if (self.currentCell.grid !== undefined) {\n                return;\n            }\n            function checkSelectionChange() {\n                var ev, sb = self.getSelectionBounds();\n                if (startingBounds === JSON.stringify(sb)) {\n                    return;\n                }\n                ev = {\n                    selections: self.selections,\n                    selectionBounds: self.getSelectionBounds()\n                };\n                Object.defineProperty(ev, 'selectedData', {\n                    get: function () {\n                        return self.getSelectedData();\n                    }\n                });\n                self.dispatchEvent('selectionchanged', ev);\n            }\n            if (self.input) {\n                self.endEdit();\n            }\n            if (self.ignoreNextClick) {\n                self.ignoreNextClick = false;\n                return;\n            }\n            i = self.currentCell;\n            if (self.dispatchEvent('click', {NativeEvent: e, cell: self.currentCell})) { return; }\n            if (!self.hasFocus) {\n                return;\n            }\n            if (['rowHeaderCell', 'columnHeaderCell'].indexOf(self.currentCell.style) === -1 && !ctrl) {\n                self.setActiveCell(i.columnIndex, i.rowIndex);\n            }\n            if (self.currentCell.context === 'cell') {\n                if (self.currentCell.style === 'cornerCell') {\n                    self.selectAll();\n                    self.draw();\n                    checkSelectionChange();\n                    return;\n                }\n                if (self.currentCell.style === 'columnHeaderCell') {\n                    if (self.attributes.columnHeaderClickBehavior === 'sort') {\n                        if (self.orderBy === i.header.name) {\n                            self.orderDirection = self.orderDirection === 'asc' ? 'desc' : 'asc';\n                        } else {\n                            self.orderDirection = 'asc';\n                        }\n                        self.order(i.header.name, self.orderDirection);\n                        checkSelectionChange();\n                        return;\n                    }\n                    if (self.attributes.columnHeaderClickBehavior === 'select') {\n                        self.selectColumn(i.header.index, ctrl, e.shiftKey);\n                        self.draw();\n                        return;\n                    }\n                }\n                self.selections[i.rowIndex] = self.selections[i.rowIndex] || [];\n                if (((self.attributes.selectionMode === 'row') || self.currentCell.style === 'rowHeaderCell')) {\n                    if (self.currentCell.style === 'rowHeaderCell'\n                            && self.attributes.tree && pos.x > 0\n                            && pos.x - self.currentCell.x < self.style.treeArrowWidth\n                            + self.style.treeArrowMarginLeft\n                            + self.style.treeArrowMarginRight + self.style.treeArrowClickRadius\n                            && pos.y - self.currentCell.y < self.style.treeArrowHeight\n                            + self.style.treeArrowMarginTop + self.style.treeArrowClickRadius\n                            && pos.y > 0) {\n                        self.toggleTree(i.rowIndex);\n                        return;\n                    }\n                }\n                if (e.shiftKey && !ctrl) {\n                    self.selectionBounds = self.getSelectionBounds();\n                    self.selectArea(undefined, false);\n                }\n            }\n            checkSelectionChange();\n            self.draw(true);\n        };\n        self.dragResizeColumn = function (e) {\n            var pos, x, y;\n            pos = self.getLayerPos(e);\n            x = self.resizingStartingWidth + pos.x - self.dragStart.x;\n            y = self.resizingStartingHeight + pos.y - self.dragStart.y;\n            if (x < self.style.minColumnWidth) {\n                x = self.style.minColumnWidth;\n            }\n            if (y < self.style.minRowHeight) {\n                y = self.style.minRowHeight;\n            }\n            if (self.dispatchEvent('resizecolumn', {x: x, y: y, draggingItem: self.draggingItem})) { return false; }\n            if (self.scrollBox.scrollLeft > self.scrollBox.scrollWidth - self.attributes.resizeScrollZone\n                    && self.dragMode === 'ew-resize') {\n                self.resize(true);\n                self.scrollBox.scrollLeft += x;\n            }\n            if (self.dragMode === 'ew-resize') {\n                self.sizes.columns[self.draggingItem.header.style === 'rowHeaderCell'\n                       ? 'cornerCell' : self.draggingItem.sortColumnIndex] = x;\n                if (['rowHeaderCell', 'cornerCell'].indexOf(self.draggingItem.header.style) !== -1) {\n                    self.resize(true);\n                }\n                self.resizeChildGrids();\n                return;\n            }\n            if (self.dragMode === 'ns-resize') {\n                if (self.draggingItem.rowOpen) {\n                    self.sizes.trees[self.draggingItem.rowIndex] = y;\n                } else if (self.attributes.globalRowResize) {\n                    self.style.cellHeight = y;\n                } else {\n                    self.sizes.rows[self.draggingItem.rowIndex] = y;\n                }\n                self.dispatchEvent('resizerow', {row: y});\n                self.resizeChildGrids();\n                return;\n            }\n            self.ellipsisCache = {};\n        };\n        self.stopDragResize = function () {\n            self.resize();\n            document.body.removeEventListener('mousemove', self.dragResizeColumn, false);\n            document.body.removeEventListener('mouseup', self.stopDragResize, false);\n            self.setStorageData();\n            self.draw(true);\n            self.ignoreNextClick = true;\n        };\n        self.scrollGrid = function (e) {\n            var pos = self.getLayerPos(e);\n            if (self.attributes.scrollPointerLock && self.pointerLockPosition\n                    && ['horizontal-scroll-box', 'vertical-scroll-box'].indexOf(self.scrollStartMode) !== -1) {\n                self.pointerLockPosition.x += e.movementX;\n                self.pointerLockPosition.y += e.movementY;\n                self.pointerLockPosition.x = Math.min(self.width - self.style.scrollBarWidth, Math.max(0, self.pointerLockPosition.x));\n                self.pointerLockPosition.y = Math.min(self.height - self.style.scrollBarWidth, Math.max(0, self.pointerLockPosition.y));\n                pos = self.pointerLockPosition;\n            }\n            self.scrollMode = self.getCellAt(pos.x, pos.y).context;\n            if (self.scrollMode === 'horizontal-scroll-box' && self.scrollStartMode !== 'horizontal-scroll-box') {\n                self.scrollStartMode = 'horizontal-scroll-box';\n                self.dragStart = pos;\n                self.scrollStart.left = self.scrollBox.scrollLeft;\n                clearTimeout(self.scrollTimer);\n                return;\n            }\n            if (self.scrollMode === 'vertical-scroll-box' && self.scrollStartMode !== 'vertical-scroll-box') {\n                self.scrollStartMode = 'vertical-scroll-box';\n                self.dragStart = pos;\n                self.scrollStart.top = self.scrollBox.scrollTop;\n                clearTimeout(self.scrollTimer);\n                return;\n            }\n            if (self.scrollStartMode === 'vertical-scroll-box'\n                    && self.scrollMode !== 'vertical-scroll-box') {\n                self.scrollMode = 'vertical-scroll-box';\n            }\n            if (self.scrollStartMode === 'horizontal-scroll-box'\n                    && self.scrollMode !== 'horizontal-scroll-box') {\n                self.scrollMode = 'horizontal-scroll-box';\n            }\n            clearTimeout(self.scrollTimer);\n            if (self.scrollModes.indexOf(self.scrollMode) === -1) {\n                return;\n            }\n            if (self.scrollMode === 'vertical-scroll-box') {\n                self.scrollBox.scrollTop = self.scrollStart.top + ((pos.y - self.dragStart.y)\n                    / self.scrollBox.heightBoxRatio);\n            } else if (self.scrollMode === 'vertical-scroll-top') {\n                self.scrollBox.scrollTop -= (self.page * self.style.cellHeight);\n                self.scrollTimer = setTimeout(self.scrollGrid, self.attributes.scrollRepeatRate, e);\n            } else if (self.scrollMode === 'vertical-scroll-bottom') {\n                self.scrollBox.scrollTop += (self.page * self.style.cellHeight);\n                self.scrollTimer = setTimeout(self.scrollGrid, self.attributes.scrollRepeatRate, e);\n            }\n            if (self.scrollMode === 'horizontal-scroll-box') {\n                self.scrollBox.scrollLeft = self.scrollStart.left + ((pos.x - self.dragStart.x)\n                    / self.scrollBox.widthBoxRatio);\n            } else if (self.scrollMode === 'horizontal-scroll-right') {\n                self.scrollBox.scrollLeft += self.attributes.selectionScrollIncrement;\n                self.scrollTimer = setTimeout(self.scrollGrid, self.attributes.scrollRepeatRate, e);\n            } else if (self.scrollMode === 'horizontal-scroll-left') {\n                self.scrollBox.scrollLeft -= self.attributes.selectionScrollIncrement;\n                self.scrollTimer = setTimeout(self.scrollGrid, self.attributes.scrollRepeatRate, e);\n            }\n        };\n        self.stopScrollGrid = function () {\n            clearTimeout(self.scrollTimer);\n            if (document.exitPointerLock) {\n                document.exitPointerLock();\n            }\n            document.removeEventListener('mousemove', self.scrollGrid, false);\n        };\n        self.dragReorder = function (e) {\n            var pos, x, y,\n                columReorder = self.dragMode === 'column-reorder',\n                rowReorder = self.dragMode === 'row-reorder';\n            pos = self.getLayerPos(e);\n            x = pos.x - self.dragStart.x;\n            y = pos.y - self.dragStart.y;\n            if (!self.attributes.allowColumnReordering && columReorder) {\n                return;\n            }\n            if (!self.attributes.allowRowReordering && rowReorder) {\n                return;\n            }\n            if (self.dispatchEvent('reordering', {\n                    NativeEvent: e,\n                    source: self.dragStartObject,\n                    target: self.currentCell,\n                    dragMode: self.dragMode\n                })) {\n                return;\n            }\n            if (Math.abs(x) > self.attributes.reorderDeadZone || Math.abs(y) > self.attributes.reorderDeadZone) {\n                self.reorderObject = self.draggingItem;\n                self.reorderTarget = self.currentCell;\n                self.reorderObject.dragOffset = {\n                    x: x,\n                    y: y\n                };\n                self.autoScrollZone(e, columReorder ? pos.x : -1, rowReorder ? pos.y : -1, false);\n            }\n        };\n        self.stopDragReorder = function (e) {\n            var oIndex,\n                tIndex,\n                cr = {\n                    'row-reorder': self.orders.rows,\n                    'column-reorder': self.orders.columns\n                },\n                i = {\n                    'row-reorder': 'rowIndex',\n                    'column-reorder': 'sortColumnIndex'\n                }[self.dragMode];\n            document.body.removeEventListener('mousemove', self.dragReorder, false);\n            document.body.removeEventListener('mouseup', self.stopDragReorder, false);\n            if (self.reorderObject\n                    && self.reorderTarget\n                    && ((self.dragMode === 'column-reorder' && self.reorderTarget.sortColumnIndex > -1\n                        && self.reorderTarget.sortColumnIndex < self.getSchema().length)\n                    || (self.dragMode === 'row-reorder' && self.reorderTarget.rowIndex > -1\n                        && self.reorderTarget.rowIndex < self.data.length))\n                    && self.reorderObject[i] !== self.reorderTarget[i]\n                    && !self.dispatchEvent('reorder', {\n                        NativeEvent: e,\n                        source: self.reorderObject,\n                        target: self.reorderTarget,\n                        dragMode: self.dragMode\n                    })) {\n                self.ignoreNextClick = true;\n                oIndex = cr[self.dragMode].indexOf(self.reorderObject[i]);\n                tIndex = cr[self.dragMode].indexOf(self.reorderTarget[i]);\n                cr[self.dragMode].splice(oIndex, 1);\n                cr[self.dragMode].splice(tIndex, 0, self.reorderObject[i]);\n                if(self.dragMode === 'column-reorder') {\n                  self.orders.columns = cr[self.dragMode];\n                } else {\n                  self.orders.rows = cr[self.dragMode];\n                }\n                self.resize();\n                self.setStorageData();\n            }\n            self.reorderObject = undefined;\n            self.reorderTarget = undefined;\n            self.draw(true);\n        };\n        self.dragMove = function (e) {\n            if (self.dispatchEvent('moving', {NativeEvent: e, cell: self.currentCell})) { return; }\n            var pos = self.getLayerPos(e);\n            self.moveOffset = {\n                x: self.currentCell.columnIndex - self.dragStartObject.columnIndex,\n                y: self.currentCell.rowIndex - self.dragStartObject.rowIndex\n            };\n            if (Math.abs(pos.x) > self.attributes.reorderDeadZone || Math.abs(pos.y) > self.attributes.reorderDeadZone) {\n                setTimeout(function () {\n                    self.autoScrollZone(e, pos.x, pos.y, false);\n                }, 1);\n            }\n        };\n        self.stopDragMove = function (e) {\n            document.body.removeEventListener('mousemove', self.dragMove, false);\n            document.body.removeEventListener('mouseup', self.stopDragMove, false);\n            var b = self.getSelectionBounds();\n            if (self.dispatchEvent('endmove', {NativeEvent: e, cell: self.currentCell})) {\n                self.movingSelection = undefined;\n                self.moveOffset = undefined;\n                self.draw(true);\n                return;\n            }\n            if (self.moveOffset) {\n                self.moveTo(self.movingSelection, b.left + self.moveOffset.x, b.top + self.moveOffset.y);\n                self.moveSelection(self.moveOffset.x, self.moveOffset.y);\n            }\n            self.movingSelection = undefined;\n            self.moveOffset = undefined;\n            self.draw(true);\n        };\n        self.freezeMove = function (e) {\n            if (self.dispatchEvent('freezemoving', {NativeEvent: e, cell: self.currentCell})) { return; }\n            var pos = self.getLayerPos(e);\n            self.ignoreNextClick = true;\n            self.freezeMarkerPosition = pos;\n            if (self.currentCell && self.currentCell.rowIndex !== undefined && self.dragMode === 'frozen-row-marker') {\n                self.scrollBox.scrollTop = 0;\n                self.frozenRow = self.currentCell.rowIndex + 1;\n            }\n            if (self.currentCell && self.currentCell.columnIndex !== undefined && self.dragMode === 'frozen-column-marker') {\n                self.scrollBox.scrollLeft = 0;\n                self.frozenColumn = self.currentCell.columnIndex + 1;\n            }\n            if (Math.abs(pos.x) > self.attributes.reorderDeadZone || Math.abs(pos.y) > self.attributes.reorderDeadZone) {\n                setTimeout(function () {\n                    self.autoScrollZone(e, pos.x, pos.y, false);\n                }, 1);\n            }\n        };\n        self.stopFreezeMove = function (e) {\n            document.body.removeEventListener('mousemove', self.freezeMove, false);\n            document.body.removeEventListener('mouseup', self.stopFreezeMove, false);\n            self.freezeMarkerPosition = undefined;\n            if (self.dispatchEvent('endfreezemove', {NativeEvent: e, cell: self.currentCell})) {\n                self.frozenRow = self.startFreezeMove.x;\n                self.frozenColumn = self.startFreezeMove.y;\n                self.draw(true);\n                return;\n            }\n            self.draw(true);\n        };\n        self.mousedown = function (e, overridePos) {\n            self.lastMouseDownTarget = e.target;\n            if (self.dispatchEvent('mousedown', {NativeEvent: e, cell: self.currentCell})) { return; }\n            if (!self.hasFocus) {\n                return;\n            }\n            if (e.button === 2 || self.input) { return; }\n            var ctrl = (e.ctrlKey || e.metaKey),\n                move = /-move/.test(self.dragMode),\n                freeze = /frozen-row-marker|frozen-column-marker/.test(self.dragMode),\n                resize = /-resize/.test(self.dragMode);\n            self.dragStart = overridePos || self.getLayerPos(e);\n            self.scrollStart = {\n                left: self.scrollBox.scrollLeft,\n                top: self.scrollBox.scrollTop\n            };\n            self.dragStartObject = self.getCellAt(self.dragStart.x, self.dragStart.y);\n            self.dragAddToSelection = !self.dragStartObject.selected;\n            if (!ctrl && !e.shiftKey && !/(vertical|horizontal)-scroll-(bar|box)/\n                    .test(self.dragStartObject.context)\n                    && self.currentCell\n                    && !self.currentCell.isColumnHeader\n                    && !move\n                    && !freeze\n                    && !resize) {\n                self.selections = [];\n            }\n            if (self.dragStartObject.isGrid) {\n                return;\n            }\n            if (self.scrollModes.indexOf(self.dragStartObject.context) !== -1) {\n                self.scrollMode = self.dragStartObject.context;\n                self.scrollStartMode = self.dragStartObject.context;\n                self.scrollGrid(e);\n                if (self.attributes.scrollPointerLock\n                        && ['horizontal-scroll-box', 'vertical-scroll-box'].indexOf(self.scrollStartMode) !== -1) {\n                    self.pointerLockPosition = {\n                        x: self.dragStart.x,\n                        y: self.dragStart.y\n                    };\n                    self.canvas.requestPointerLock();\n                }\n                document.addEventListener('mousemove', self.scrollGrid, false);\n                document.addEventListener('mouseup', self.stopScrollGrid, false);\n                self.ignoreNextClick = true;\n                return;\n            }\n            if (self.dragMode === 'cell') {\n                self.selecting = true;\n                if ((self.attributes.selectionMode === 'row' || self.dragStartObject.columnIndex === -1)\n                        && self.dragStartObject.rowIndex > -1) {\n                    self.selectRow(self.dragStartObject.rowIndex, ctrl, null);\n                } else if (self.attributes.selectionMode !== 'row') {\n                    self.mousemove(e);\n                }\n                return;\n            }\n            if (move) {\n                self.draggingItem = self.dragItem;\n                self.movingSelection = self.selections.concat([]);\n                self.dragging = self.dragStartObject;\n                if (self.dispatchEvent('beginmove', {NativeEvent: e, cell: self.currentCell})) { return; }\n                document.body.addEventListener('mousemove', self.dragMove, false);\n                document.body.addEventListener('mouseup', self.stopDragMove, false);\n                return self.mousemove(e);\n            }\n            if (freeze) {\n                self.draggingItem = self.dragItem;\n                self.startFreezeMove = {\n                    x: self.frozenRow,\n                    y: self.frozenColumn\n                };\n                if (self.dispatchEvent('beginfreezemove', {NativeEvent: e})) { return; }\n                document.body.addEventListener('mousemove', self.freezeMove, false);\n                document.body.addEventListener('mouseup', self.stopFreezeMove, false);\n                return self.mousemove(e);\n            }\n            if (resize) {\n                self.draggingItem = self.dragItem;\n                if (self.draggingItem.rowOpen) {\n                    self.resizingStartingHeight = self.sizes.trees[self.draggingItem.rowIndex];\n                } else {\n                    self.resizingStartingHeight = self.sizes.rows[self.draggingItem.rowIndex] || self.style.cellHeight;\n                }\n                self.resizingStartingWidth = self.sizes.columns[self.draggingItem.header.style === 'rowHeaderCell'\n                       ? 'cornerCell' : self.draggingItem.sortColumnIndex] || self.draggingItem.width;\n                document.body.addEventListener('mousemove', self.dragResizeColumn, false);\n                document.body.addEventListener('mouseup', self.stopDragResize, false);\n                return;\n            }\n            if (['row-reorder', 'column-reorder'].indexOf(self.dragMode) !== -1) {\n                self.draggingItem = self.dragStartObject;\n                document.body.addEventListener('mousemove', self.dragReorder, false);\n                document.body.addEventListener('mouseup', self.stopDragReorder, false);\n                return;\n            }\n        };\n        self.mouseup = function (e) {\n            clearTimeout(self.scrollTimer);\n            self.cellBoundaryCrossed = true;\n            self.rowBoundaryCrossed = true;\n            self.columnBoundaryCrossed = true;\n            self.selecting = undefined;\n            self.draggingItem = undefined;\n            self.dragStartObject = undefined;\n            if (self.dispatchEvent('mouseup', {NativeEvent: e, cell: self.currentCell})) { return; }\n            if (!self.hasFocus && e.target !== self.canvas) {\n                return;\n            }\n            if (self.currentCell && self.currentCell.grid !== undefined) {\n                return;\n            }\n            if (self.contextMenu || self.input) { return; }\n            if (self.dragStart && self.isInGrid(self.dragStart)) {\n                self.controlInput.focus();\n            }\n            e.preventDefault();\n        };\n        // gets the horizontal adjacent cells as well as first/last based on column visibility\n        self.getAdjacentCells = function () {\n            var x,\n                i,\n                s = self.getSchema(),\n                o = {};\n            for (x = 0; x < s.length; x += 1) {\n                i = self.orders.columns[x];\n                if (!s[i].hidden) {\n                    if (o.first === undefined) {\n                        o.first = x;\n                        o.left = x;\n                    }\n                    o.last = x;\n                    if (x > self.activeCell.columnIndex && o.right === undefined) {\n                        o.right = x;\n                    }\n                    if (x < self.activeCell.columnIndex) {\n                        o.left = x;\n                    }\n                }\n            }\n            if (o.right === undefined) {\n                o.right = o.last;\n            }\n            return o;\n        };\n        self.keydown = function (e) {\n            var i,\n                ev,\n                adjacentCells = self.getAdjacentCells(),\n                x = self.activeCell.columnIndex,\n                y = self.activeCell.rowIndex,\n                ctrl = (e.ctrlKey || e.metaKey),\n                last = self.data.length - 1,\n                s = self.getSchema(),\n                cols = s.length - 1;\n            if (self.dispatchEvent('keydown', {NativeEvent: e, cell: self.currentCell})) { return; }\n            if (!self.hasFocus) {\n                return;\n            }\n            if (self.attributes.showNewRow) {\n                last += 1;\n            }\n            if (e.keyCode === 9) {\n                e.preventDefault();\n            }\n            // esc\n            if (e.keyCode === 27) {\n                self.selections = [];\n                self.draw(true);\n            // ctrl + a\n            } else if (ctrl && e.keyCode === 65) {\n                self.selectAll();\n            //ArrowDown\n            } else if (e.keyCode === 40) {\n                y += 1;\n            //ArrowUp\n            } else if (e.keyCode === 38) {\n                y -= 1;\n            //ArrowLeft Tab\n            } else if (e.keyCode === 37 || (e.shiftKey && e.keyCode === 9)) {\n                x = adjacentCells.left;\n            //ArrowRight Tab\n            } else if (e.keyCode === 39 || (!e.shiftKey && e.keyCode === 9)) {\n                x = adjacentCells.right;\n            //PageUp\n            } else if (e.keyCode === 33) {\n                y -= self.page;\n                e.preventDefault();\n            //PageDown\n            } else if (e.keyCode === 34) {\n                y += self.page;\n                e.preventDefault();\n            //Home ArrowUp\n            } else if (e.keyCode === 36 || (ctrl && e.keyCode === 38)) {\n                y = 0;\n            //End ArrowDown\n            } else if (e.keyCode === 35 || (ctrl && e.keyCode === 40)) {\n                y = self.data.length - 1;\n            //ArrowRight\n            } else if (ctrl && e.keyCode === 39) {\n                x = adjacentCells.last;\n            //ArrowLeft\n            } else if (ctrl && e.keyCode === 37) {\n                x = adjacentCells.first;\n            }\n            //Enter\n            if (e.keyCode === 13) {\n                return self.beginEditAt(x, y, e);\n            }\n            //Space\n            if (e.keyCode === 32) {\n                self.selections = [];\n                self.selections[Math.max(y, 0)] = [];\n                self.selections[Math.max(y, 0)].push(x);\n                self.selectionBounds = self.getSelectionBounds();\n                if (self.attributes.selectionMode === 'row') {\n                    for (i = self.selectionBounds.top; i <= self.selectionBounds.bottom; i += 1) {\n                        self.selectRow(i, ctrl, null, true);\n                    }\n                } else {\n                    self.selectArea(undefined, ctrl);\n                }\n                e.preventDefault();\n                self.draw(true);\n                return;\n            }\n            if (x < 0 || Number.isNaN(x)) {\n                x = adjacentCells.first;\n            }\n            if (y > last) {\n                y = last;\n            }\n            if (y < 0 || Number.isNaN(y)) {\n                y = 0;\n            }\n            if (x > cols) {\n                x = adjacentCells.last;\n            }\n            // TODO - most likley some column order related bugs in key based selection\n            // Arrows\n            if (e.shiftKey && [37, 38, 39, 40].indexOf(e.keyCode) !== -1) {\n                self.selections[Math.max(y, 0)] = self.selections[Math.max(y, 0)] || [];\n                self.selections[Math.max(y, 0)].push(x);\n                self.selectionBounds = self.getSelectionBounds();\n                self.selectArea(undefined, ctrl);\n                self.draw(true);\n            }\n            if (x !== self.activeCell.columnIndex || y !== self.activeCell.rowIndex) {\n                self.scrollIntoView(\n                  x !== self.activeCell.columnIndex ? x : undefined,\n                  y !== self.activeCell.rowIndex && !Number.isNaN(y) ? y : undefined\n                );\n\n                self.setActiveCell(x, y);\n                if (!e.shiftKey && self.attributes.selectionFollowsActiveCell) {\n                    if (!ctrl) {\n                        self.selections = [];\n                    }\n                    self.selections[y] = self.selections[y] || [];\n                    self.selections[y].push(x);\n                    ev = {\n                        selectedData: self.getSelectedData(),\n                        selections: self.selections,\n                        selectionBounds: self.getSelectionBounds()\n                    };\n                    Object.defineProperty(ev, 'selectedData', {\n                        get: function () {\n                            return self.getSelectedData();\n                        }\n                    });\n                    self.dispatchEvent('selectionchanged', ev);\n                }\n                self.draw(true);\n            }\n        };\n        self.keyup = function (e) {\n            if (self.dispatchEvent('keyup', {NativeEvent: e, cell: self.currentCell})) { return; }\n            if (!self.hasFocus) {\n                return;\n            }\n        };\n        self.keypress = function (e) {\n            if (!self.hasFocus) {\n                return;\n            }\n            if (self.dispatchEvent('keypress', {NativeEvent: e, cell: self.currentCell})) { return; }\n        };\n        self.dblclick = function (e) {\n            if (self.dispatchEvent('dblclick', {NativeEvent: e, cell: self.currentCell})) { return; }\n            if (!self.hasFocus) {\n                return;\n            }\n            if (self.currentCell.context === 'ew-resize'\n                    && self.currentCell.style === 'columnHeaderCell') {\n                self.fitColumnToValues(self.currentCell.header.name);\n            } else if (self.currentCell.context === 'ew-resize'\n                    && self.currentCell.style === 'cornerCell') {\n                self.autosize();\n            } else if (['cell', 'activeCell'].indexOf(self.currentCell.style) !== -1) {\n                self.beginEditAt(self.currentCell.columnIndex, self.currentCell.rowIndex);\n            }\n        };\n        self.scrollWheel = function (e) {\n            var l,\n                t,\n                ev = e,\n                deltaX = e.deltaX === undefined ? e.NativeEvent.deltaX : e.deltaX,\n                deltaY = e.deltaY === undefined ? e.NativeEvent.deltaY : e.deltaY,\n                deltaMode = e.deltaMode === undefined ? e.NativeEvent.deltaMode : e.deltaMode;\n            if (wheeling) {\n                return;\n            }\n            if (self.dispatchEvent('wheel', {NativeEvent: e})) {\n                return;\n            }\n            var e = e.NativeEvent || e;\n            self.touchHaltAnimation = true;\n            l = self.scrollBox.scrollLeft;\n            t = self.scrollBox.scrollTop;\n            if (self.hasFocus) {\n                //BUG Issue 42: https://github.com/TonyGermaneri/canvas-datagrid/issues/42\n                //https://stackoverflow.com/questions/20110224/what-is-the-height-of-a-line-in-a-wheel-event-deltamode-dom-delta-line\n                if (deltaMode === 1) {\n                    // line mode = 17 pixels per line\n                    deltaY = deltaY * 17;\n                }\n                if ((self.scrollBox.scrollTop  < self.scrollBox.scrollHeight && deltaY > 0)\n                        || (self.scrollBox.scrollLeft < self.scrollBox.scrollWidth && deltaX > 0)\n                        || (self.scrollBox.scrollTop > 0 && deltaY < 0)\n                        || (self.scrollBox.scrollLeft > 0 && deltaX < 0)) {\n                    ev.preventDefault(e);\n                }\n                wheeling = setTimeout(function () {\n                    wheeling = undefined;\n                    self.scrollBox.scrollTo(deltaX + l, deltaY + t);\n                }, 1);\n            }\n        };\n        self.pasteItem = function (clipData, x, y, mimeType) {\n            var l, s = self.getVisibleSchema(), yi = y - 1, sel = [];\n            function normalizeRowData(importingRow, existingRow, offsetX, schema, mimeType, rowIndex) {\n                var r = existingRow;\n                if (!Array.isArray(importingRow) && importingRow !== null && typeof importingRow === 'object') {\n                    importingRow = Object.keys(importingRow).map(function (colKey) {\n                        return importingRow[colKey];\n                    });\n                }\n                if (/^text\\/html/.test(mimeType)) {\n                    importingRow = importingRow.substring(4, importingRow.length - 5).split('</td><td>');\n                }\n                if (typeof importingRow === 'string') {\n                    importingRow = [importingRow];\n                }\n                sel[rowIndex] = [];\n                importingRow.forEach(function (cellData, colIndex) {\n                    var cName = schema[colIndex + offsetX].name;\n                    if (importingRow[colIndex] === undefined || importingRow[colIndex] === null) {\n                        r[cName] = existingRow[cName];\n                        return;\n                    }\n                    sel[rowIndex].push(colIndex + offsetX);\n                    r[cName] = importingRow[colIndex];\n                });\n                return r;\n            }\n            if (/^text\\/html/.test(mimeType)) {\n                if (!/^(<meta[^>]+>)?<table>/.test(clipData.substring(0, 29))) {\n                    console.warn('Unrecognized HTML format.  HTML must be a simple table, e.g.: <table><tr><td>data</td></tr></table>.  Data with the mime type text/html not in this format will not be imported as row data.');\n                    return;\n                }\n                // strip table beginning and ending off, then split at rows\n                clipData = clipData.substring(clipData.indexOf('<table><tr>') + 11, clipData.length - 13).split('</tr><tr>');\n                // ditch any headers on the table\n                clipData = clipData.filter(function (row) {\n                    return !/^<th>|^<thead>/.test(row);\n                });\n            } else {\n                clipData = clipData.split('\\n');\n            }\n            l = clipData.length;\n            clipData.forEach(function (rowData) {\n                yi += 1;\n                var i = self.orders.rows[yi];\n                self.data[i] = normalizeRowData(rowData, self.data[i], x, s, mimeType, i);\n            });\n            self.selections = sel;\n            return l;\n        };\n        self.getNextVisibleColumnIndex = function (visibleColumnIndex) {\n            var x, s = self.getVisibleSchema();\n            for (x = 0; x < s.length; x += 1) {\n                if (s[x].columnIndex === visibleColumnIndex) {\n                    return s[x + 1].columnIndex;\n                }\n            }\n            return -1;\n        };\n        self.getVisibleColumnIndexOf = function (columnIndex) {\n            var x, s = self.getVisibleSchema();\n            for (x = 0; x < s.length; x += 1) {\n                if (s[x].columnIndex === columnIndex) {\n                    return x;\n                }\n            }\n            return -1;\n        };\n        self.paste = function (e) {\n            var d;\n            function getItem(dti) {\n                var type = dti.type;\n                dti.getAsString(function (s) {\n                    self.pasteItem(s, self.getVisibleColumnIndexOf(self.activeCell.columnIndex), self.activeCell.rowIndex, type);\n                    self.draw();\n                });\n            }\n            d = Array.prototype.filter.call(e.clipboardData.items, function (dti) {\n                return dti.type === 'text/html';\n            })[0] || Array.prototype.filter(function (dti) {\n                return dti.type === 'text/csv';\n            })[0] || Array.prototype.filter(function (dti) {\n                return dti.type === 'text/plain';\n            })[0];\n            if (!d) {\n                console.warn('Cannot find supported clipboard data type.  Supported types are text/html, text/csv, text/plain.');\n                return;\n            }\n            getItem(d);\n        };\n        self.cut = function (e) {\n            self.copy(e);\n            self.forEachSelectedCell(function (data, index, colName) {\n                data[index][colName] = '';\n            });\n        };\n        self.copy = function (e) {\n            if (self.dispatchEvent('copy', {NativeEvent: e})) { return; }\n            if (!self.hasFocus || !e.clipboardData) { return; }\n            var t,\n                d,\n                data = (self.data || []),\n                tableRows = [],\n                textRows = [],\n                outputHeaders = {},\n                outputHeaderKeys,\n                sData = self.getSelectedData(),\n                s = self.getSchema();\n            function htmlSafe(v) {\n                return v.replace(/</g, '&lt;').replace(/>/g, '&gt;');\n            }\n            function fCopyCell(v) {\n                v = v === null || v === undefined ? '' : v;\n                return '<td>' + (typeof v === 'string' ? htmlSafe(v) : v) + '</td>';\n            }\n            function addHeaders(headers, useHtml) {\n                if (!s.length || headers.length < 2) { return ''; }\n                var h = [];\n                if (useHtml) {\n                    h.push('<tr>');\n                }\n                s.forEach(function (column, columnIndex) {\n                    // intentional redefinition of column\n                    column = s[self.orders.columns[columnIndex]];\n                    if (!column.hidden && headers.indexOf(column.name) !== -1) {\n                        var ev = {NativeEvent: e, column: column};\n                        if(self.dispatchEvent('copyonschema', ev)) {\n                            column = ev.column;\n                        }\n\n                        var hVal = (column.name || column.title) || '';\n                        if (useHtml) {\n                            h.push('<th>' + htmlSafe(hVal) + '</th>');\n                        } else {\n                            h.push('\"' + hVal.replace(/\"/g, '\"\"') + '\"');\n                        }\n                    }\n                });\n                h.push(useHtml ? '</tr>' : '\\n');\n                return h.join(useHtml ? '' : ',');\n            }\n            function addCellValue(val, trRow, textRow, column) {\n                // escape strings\n                if (val !== null\n                        && val !== false\n                        && val !== undefined\n                        && val.replace) {\n                    trRow.push(fCopyCell(val));\n                    textRow.push('\"' + val.replace(/\"/g, '\"\"') + '\"');\n                    return;\n                }\n                if (val !== undefined) {\n                    textRow.push(val);\n                    trRow.push(fCopyCell(val));\n                    return;\n                }\n                // issue #66\n                textRow.push('');\n                trRow.push('<td>&nbsp;</td>');\n            }\n            if (sData.length > 0) {\n                sData.forEach(function (row) {\n                    var rowKeys = Object.keys(row);\n                    if (row) {\n                        var trRow = [],\n                            textRow = [],\n                            sSorted = [];\n                        // HACK: https://github.com/TonyGermaneri/canvas-datagrid/issues/181\n                        // I can't use sort here or O(1), so hacks\n                        s.forEach(function (column, columnIndex) {\n                            sSorted.push(s[self.orders.columns[columnIndex]]);\n                        });\n                        sSorted.forEach(function (column, columnIndex) {\n                            if (rowKeys.indexOf(column.name) !== -1) {\n                                outputHeaders[column.name] = true;\n                                // escape strings\n                                addCellValue(row[column.name], trRow, textRow, column);\n                            }\n                        });\n                        tableRows.push(trRow.join(''));\n                        textRows.push(textRow.join(','));\n                    }\n                });\n                outputHeaderKeys = Object.keys(outputHeaders);\n                t = addHeaders(outputHeaderKeys) + textRows.join('\\n');\n                d = '<table>' + addHeaders(outputHeaderKeys, true) + '<tr>' + tableRows.join('</tr><tr>') + '</tr></table>';\n                if (outputHeaderKeys.length === 1) {\n                    // if there was only one cell selected, remove the quotes from the string\n                    t = t.substring(1, t.length -1);\n                }\n                e.clipboardData.setData('text/html', d);\n                e.clipboardData.setData('text/plain', t);\n                e.clipboardData.setData('text/csv', t);\n                e.clipboardData.setData('application/json', JSON.stringify(sData));\n                e.preventDefault();\n            }\n        };\n        return;\n    };\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/events.js\n// module id = 4\n// module chunks = 0","/*jslint browser: true, unparam: true, todo: true, plusplus: true*/\n/*globals define: true, MutationObserver: false, requestAnimationFrame: false, performance: false, btoa: false*/\ndefine([], function () {\n    'use strict';\n    return function (self) {\n        var touchTimerMs = 50,\n            debounceTouchMove,\n            touchMoving,\n            touchScrollTimeout;\n        self.scrollAnimation = {};\n        self.touchDelta = {};\n        self.touchAnimateTo = {};\n        self.animationFrames = 0;\n        self.getTouchPos = function (e, touchIndex) {\n            var t = touchIndex ? e.touches[touchIndex] : e.touches[0],\n                rect = self.canvas.getBoundingClientRect(),\n                pos;\n            if (!t) { return; }\n            pos = {\n                x: t.clientX - rect.left,\n                y: t.clientY - rect.top\n            };\n            if (self.isChildGrid) {\n                pos.x -= self.canvasOffsetLeft;\n                pos.y -= self.canvasOffsetTop;\n            }\n            return {\n                x: pos.x,\n                y: pos.y,\n                rect: rect\n            };\n        };\n        // shamelessly stolen from from https://gist.github.com/gre/1650294\n        self.easingFunctions = {\n            linear: function (t) { return t; },\n            easeInQuad: function (t) { return t * t; },\n            easeOutQuad: function (t) { return t * (2 - t); },\n            easeInOutQuad: function (t) { return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t; },\n            easeInCubic: function (t) { return t * t * t; },\n            easeOutCubic: function (t) { return (--t) * t * t + 1; },\n            easeInOutCubic: function (t) { return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1; },\n            easeInQuart: function (t) { return t * t * t * t; },\n            easeOutQuart: function (t) { return 1 - (--t) * t * t * t; },\n            easeInOutQuart: function (t) { return t < 0.5 ? 8 * t  * t  * t * t : 1 - 8 * (--t) * t * t * t; },\n            easeInQuint: function (t) { return t * t * t * t * t; },\n            easeOutQuint: function (t) { return 1 + (--t) * t *  t * t * t; },\n            easeInOutQuint: function (t) { return t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * (--t) * t * t * t * t; }\n        };\n        self.easing = function (t, b, c, d) {\n            return c * self.easingFunctions[self.attributes.touchEasingMethod](t / d) + b;\n        };\n        self.calculatePPSTimed = function () {\n            self.xPPST = -((self.touchDelta.x - self.touchSigmaTimed.x) / (self.touchDelta.t - self.touchSigmaTimed.t));\n            self.yPPST = -((self.touchDelta.y - self.touchSigmaTimed.y) / (self.touchDelta.t - self.touchSigmaTimed.t));\n            self.touchSigmaTimed = {\n                x: self.touchDelta.x,\n                y: self.touchDelta.y,\n                t: performance.now()\n            };\n        };\n        self.calculatePPS = function () {\n            self.xPPS = -((self.touchDelta.x - self.touchSigma.x) / (self.touchDelta.t - self.touchSigma.t));\n            self.yPPS = -((self.touchDelta.y - self.touchSigma.y) / (self.touchDelta.t - self.touchSigma.t));\n            self.touchSigma = {\n                x: self.touchDelta.x,\n                y: self.touchDelta.y,\n                t: performance.now()\n            };\n        };\n        self.touchEndAnimation = function () {\n            if (!self.canvas || !self.scrollBox.scrollTo) { return requestAnimationFrame(self.touchEndAnimation); }\n            var n = performance.now(),\n                d = self.attributes.touchReleaseAnimationDurationMs,\n                t;\n            t = n - self.touchDelta.t;\n            self.animationFrames += 1;\n            self.scrollAnimation.x = self.easing(t, self.touchDelta.scrollLeft, self.touchAnimateTo.x, d);\n            self.scrollAnimation.y = self.easing(t, self.touchDelta.scrollTop, self.touchAnimateTo.y, d);\n            if (t > d || (self.scrollAnimation.y === self.scrollBox.scrollTop\n                    && self.scrollAnimation.x === self.scrollBox.scrollLeft) || self.stopAnimation) {\n                return;\n            }\n            self.scrollBox.scrollTo(self.scrollAnimation.x, self.scrollAnimation.y);\n            requestAnimationFrame(self.touchEndAnimation);\n        };\n        self.touchEditCell = function (cell) {\n            self.beginEditAt(cell.columnIndex, cell.rowIndex);\n        };\n        self.touchCell = function (e) {\n            return function () {\n                clearInterval(self.calculatePPSTimer);\n                var i, pos = self.getTouchPos(e);\n                if (Math.abs(self.touchDelta.x) + Math.abs(self.touchDelta.y) < self.attributes.touchDeadZone) {\n                    i = self.getCellAt(pos.x, pos.y);\n                    if (!i) { return; }\n                    if (self.touchingCell && self.touchingCell.rowIndex === i.rowIndex\n                            && self.touchingCell.columnIndex === i.columnIndex) {\n                        self.touchEditCell(i);\n                        return;\n                    }\n                    if (self.input && self.input.editCell) {\n                        self.endEdit();\n                    }\n                    self.touchingCell = i;\n                    self.selectArea({\n                        top: i.rowIndex,\n                        bottom: i.rowIndex,\n                        left: i.columnIndex,\n                        right: i.columnIndex\n                    });\n                    self.draw(true);\n                }\n            };\n        };\n        self.touchstart = function (e) {\n            if (e.changedTouches[0]) {\n                self.touchStart = self.getTouchPos(e);\n                self.startingCell = self.getCellAt(self.touchStart.x, self.touchStart.y, true);\n            }\n            if (self.dispatchEvent('touchstart', {NativeEvent: e, cell: self.startingCell})) { return; }\n            self.disposeContextMenu();\n            clearInterval(self.calculatePPSTimer);\n            clearTimeout(self.touchContextTimeout);\n            self.touchStartEvent = e;\n            self.stopAnimation = true;\n            self.animationFrames = 0;\n            self.stopPropagation(e);\n            e.preventDefault();\n            if (e.touches.length === 1 && e.changedTouches[0] && !self.zoomAltered) {\n                self.touchLength = 1;\n                self.touchStart = self.touchStart || self.touchStart1;\n                self.touchScrollStart = {\n                    x: self.scrollBox.scrollLeft,\n                    y: self.scrollBox.scrollTop,\n                    t: performance.now()\n                };\n                self.touchDelta = {\n                    x: 0,\n                    y: 0,\n                    scrollLeft: self.scrollBox.scrollLeft,\n                    scrollTop: self.scrollBox.scrollTop,\n                    t: self.touchScrollStart.t\n                };\n                self.touchSigma = {\n                    x: self.touchDelta.x,\n                    y: self.touchDelta.y,\n                    t: self.touchDelta.t\n                };\n                self.touchSigmaTimed = {\n                    x: self.touchDelta.x,\n                    y: self.touchDelta.y,\n                    t: self.touchDelta.t\n                };\n                self.touchContextTimeout = setTimeout(function () {\n                    self.contextmenuEvent(e, self.touchStart);\n                }, self.attributes.touchContextMenuTimeMs);\n                self.calculatePPSTimer = setInterval(self.calculatePPSTimed, touchTimerMs);\n                if (self.startingCell && (self.startingCell.isGrid || ['tree', 'inherit'].indexOf(self.startingCell.context) !== -1)) {\n                    self.hasFocus = false;\n                    return;\n                }\n                self.hasFocus = true;\n                if (self.startingCell.isHeader) {\n                    if (self.startingCell.isRowHeader) {\n                        self.selectArea({\n                            top: self.startingCell.rowIndex,\n                            bottom: self.startingCell.rowIndex,\n                            left: 0,\n                            right: self.getVisibleSchema().length - 1,\n                        });\n                        self.draw(true);\n                    } else if (self.startingCell.isColumnHeader) {\n                        if (self.attributes.columnHeaderClickBehavior === 'sort') {\n                            if (self.orderBy === self.startingCell.header.name) {\n                                self.orderDirection = self.orderDirection === 'asc' ? 'desc' : 'asc';\n                            } else {\n                                self.orderDirection = 'asc';\n                            }\n                            self.order(self.startingCell.header.name, self.orderDirection);\n                        }\n                        if (self.attributes.columnHeaderClickBehavior === 'select') {\n                            self.selectArea({\n                                top: 0,\n                                bottom: self.data.length - 1,\n                                left: self.startingCell.columnIndex,\n                                right: self.startingCell.columnIndex,\n                            });\n                            self.draw(true);\n                        }\n                    }\n                    self.touchEndEvents(e);\n                    return;\n                }\n            }\n            if (self.zoomAltered) { return; }\n            document.body.addEventListener('touchmove', self.touchmove, {passive: false});\n            document.body.addEventListener('touchend', self.touchend, false);\n            document.body.addEventListener('touchcancel', self.touchcancel, false);\n            self.draw(true);\n        };\n        self.touchSelect = function (cell, handleType) {\n            if (cell.rowIndex === undefined || cell.columnIndex === undefined) { return; }\n            self.touchSelecting = true;\n            var bounds = self.getSelectionBounds();\n            if (handleType === 'selection-handle-bl'\n                    && cell.rowIndex >= bounds.top\n                    && cell.columnIndex <= bounds.right) {\n                bounds.bottom = cell.rowIndex;\n                bounds.left = cell.columnIndex;\n            } else if (handleType === 'selection-handle-tl'\n                    && cell.rowIndex <= bounds.bottom\n                    && cell.columnIndex <= bounds.right) {\n                bounds.top = cell.rowIndex;\n                bounds.left = cell.columnIndex;\n            } else if (handleType === 'selection-handle-tr'\n                    && cell.rowIndex <= bounds.bottom\n                    && cell.columnIndex >= bounds.left) {\n                bounds.top = cell.rowIndex;\n                bounds.right = cell.columnIndex;\n            } else if (handleType === 'selection-handle-br'\n                    && cell.rowIndex >= bounds.top\n                    && cell.columnIndex >= bounds.left) {\n                bounds.bottom = cell.rowIndex;\n                bounds.right = cell.columnIndex;\n            }\n            if (self.attributes.selectionMode === 'row' || cell.rowIndex === -1) {\n                bounds.left = 0;\n                bounds.right = self.getSchema().length - 1;\n            } else {\n                bounds.left = Math.max(0, bounds.left);\n            }\n            self.selectArea(bounds);\n            self.draw(true);\n        };\n        function touchMove(e) {\n            var ch, rw, rScrollZone, lScrollZone, bScrollZone, tScrollZone, sbw, t1, t2;\n            if (self.dispatchEvent('beforetouchmove', {NativeEvent: e})) { return; }\n            clearTimeout(touchScrollTimeout);\n            if (e.changedTouches[0]) {\n                self.touchPosition = self.getTouchPos(e);\n            }\n            if (e.changedTouches[1]) {\n                self.touchPosition1 = self.getTouchPos(e, 1);\n            }\n            if (Math.abs(self.touchDelta.x) + Math.abs(self.touchDelta.y) > self.attributes.touchDeadZone) {\n                clearTimeout(self.touchContextTimeout);\n            }\n            if (e.touches.length === 2 && self.touchPosition && self.touchPosition1) {\n                t1 = self.touchPosition.y;\n                t2 = self.touchPosition1.y;\n                if (!self.zoomDeltaStart) {\n                    self.zoomDeltaStart = Math.abs(t1 - t2);\n                    self.startScale = self.scale;\n                }\n                self.touchLength = 2;\n                self.scaleDelta = self.zoomDeltaStart - Math.abs(t1 - t2);\n                self.scale = self.startScale - (self.scaleDelta * self.attributes.touchZoomSensitivity);\n                self.scale = Math.min(Math.max(self.scale, self.attributes.touchZoomMin), self.attributes.touchZoomMax);\n                self.zoomAltered = true;\n                self.resize(true);\n                self.resizeChildGrids();\n                return;\n            }\n            if (self.zoomAltered) { return; }\n            self.touchLength = 1;\n            self.touchPosition = self.touchPosition || self.touchPosition1;\n            ch = self.getColumnHeaderCellHeight();\n            rw = self.getRowHeaderCellWidth();\n            rScrollZone = self.width - self.style.scrollBarWidth - self.touchPosition.x < self.attributes.selectionScrollZone;\n            lScrollZone = self.touchPosition.x - rw < self.attributes.selectionScrollZone;\n            bScrollZone = self.height - self.style.scrollBarWidth - self.touchPosition.y < self.attributes.selectionScrollZone;\n            tScrollZone = self.touchPosition.y - ch < self.attributes.selectionScrollZone;\n            sbw = self.style.scrollBarWidth;\n            function touchScroll() {\n                var x = self.scrollBox.scrollLeft,\n                    y = self.scrollBox.scrollTop;\n                x += (rScrollZone ? self.attributes.selectionScrollIncrement : 0);\n                y += (bScrollZone ? self.attributes.selectionScrollIncrement : 0);\n                y -= (tScrollZone ? self.attributes.selectionScrollIncrement : 0);\n                x -= (lScrollZone ? self.attributes.selectionScrollIncrement : 0);\n                self.scrollBox.scrollTo(x, y);\n                touchScrollTimeout = setTimeout(touchScroll, self.attributes.scrollRepeatRate);\n            }\n            e.stopPropagation();\n            self.touchDelta = {\n                x: self.touchPosition.x - self.touchStart.x,\n                y: self.touchPosition.y - self.touchStart.y,\n                scrollLeft: self.scrollBox.scrollLeft,\n                scrollTop: self.scrollBox.scrollTop,\n                t: performance.now()\n            };\n            self.currentCell = self.getCellAt(self.touchPosition.x, self.touchPosition.y);\n            self.dispatchEvent('touchmove', {NativeEvent: e, cell: self.currentCell});\n            self.calculatePPS();\n            self.touchDuration = performance.now() - self.touchScrollStart.t;\n            self.stopAnimation = true;\n            self.animationFrames = 0;\n            if (self.touchSelecting && (rScrollZone || lScrollZone || tScrollZone || bScrollZone)) {\n                touchScroll();\n            }\n            if (/vertical-scroll-/.test(self.startingCell.style)) {\n                self.scrollBox.scrollTop = self.scrollBox.scrollHeight\n                    * ((self.touchPosition.y - ch - sbw) / (self.scrollBox.height - sbw - ch));\n                return;\n            }\n            if (/horizontal-scroll-/.test(self.startingCell.style)) {\n                self.scrollBox.scrollLeft = self.scrollBox.scrollWidth\n                    * ((self.touchPosition.x - rw - sbw) / (self.scrollBox.width - sbw - rw));\n                return;\n            }\n            if (/selection-handle-/.test(self.startingCell.style)) {\n                self.touchSelect(self.currentCell, self.startingCell.style);\n                return;\n            }\n            self.scrollBox.scrollTo(self.touchScrollStart.x - self.touchDelta.x,\n                self.touchScrollStart.y - self.touchDelta.y);\n        };\n        self.touchmove = function (e) {\n            if (touchMoving) {\n                return;\n            }\n            requestAnimationFrame(function () {\n                touchMoving = true;\n                touchMove(e);\n                touchMoving = false;\n            });\n        };\n        self.touchEndEvents = function (e) {\n            self.zoomDeltaStart = undefined;\n            self.touchSelecting = false;\n            clearInterval(self.touchScrollTimeout);\n            clearInterval(self.touchContextTimeout);\n            clearInterval(self.calculatePPSTimer);\n            e.stopPropagation();\n            document.body.removeEventListener('touchmove', self.touchmove, {passive: false});\n            document.body.removeEventListener('touchend', self.touchend, false);\n            document.body.removeEventListener('touchcancel', self.touchcancel, false);\n        };\n        self.touchend = function (e) {\n            if (self.dispatchEvent('touchend', {NativeEvent: e, cell: self.currentCell})) { return; }\n            self.zoomDeltaStart = undefined;\n            if (e.changedTouches[0]) {\n                self.touchPosition = undefined;\n            }\n            if (e.changedTouches[1]) {\n                self.touchPosition1 = undefined;\n            }\n            if (self.zoomAltered) {\n                if (e.touches.length === 0) {\n                    self.zoomAltered = false;\n                }\n                return;\n            }\n            var dz = Math.abs(self.touchDelta.x) + Math.abs(self.touchDelta.y) < self.attributes.touchDeadZone;\n            if (isNaN(self.xPPS)) {\n                self.xPPS = 0;\n            }\n            if (isNaN(self.yPPS)) {\n                self.yPPS = 0;\n            }\n            if (isNaN(self.xPPST)) {\n                self.xPPST = 0;\n            }\n            if (isNaN(self.yPPST)) {\n                self.yPPST = 0;\n            }\n            self.touchAnimateTo.x = self.xPPS * self.attributes.touchReleaseAcceleration;\n            self.touchAnimateTo.y = self.yPPS * self.attributes.touchReleaseAcceleration;\n            self.calculatePPSTimed();\n            if (dz && !self.contextMenu) {\n                self.touchCell(self.touchStartEvent)();\n            } else if (self.animationFrames === 0\n                    && (Math.abs(self.xPPST) > self.attributes.scrollAnimationPPSThreshold\n                        || Math.abs(self.yPPST) > self.attributes.scrollAnimationPPSThreshold)\n                    && !/-scroll-/.test(self.startingCell.style)\n                    && !dz) {\n                self.stopAnimation = false;\n                self.touchEndAnimation();\n            }\n            self.touchEndEvents(e);\n        };\n        self.touchcancel = function (e) {\n            if (self.dispatchEvent('touchcancel', {NativeEvent: e, cell: self.currentCell})) { return; }\n            self.touchEndEvents(e);\n        };\n    };\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/touch.js\n// module id = 5\n// module chunks = 0","/*jslint browser: true, unparam: true, todo: true*/\n/*globals HTMLElement: false, Reflect: false, define: true, MutationObserver: false, requestAnimationFrame: false, performance: false, btoa: false*/\ndefine([], function () {\n    'use strict';\n    return function (self, ctor) {\n        self.scale = 1;\n        self.orders = {\n            rows: [],\n            columns: []\n        };\n        self.appliedInlineStyles = {};\n        self.cellGridAttributes = {};\n        self.treeGridAttributes = {};\n        self.visibleRowHeights = [];\n        self.hasFocus = false;\n        self.activeCell = {\n            columnIndex: 0,\n            rowIndex: 0\n        };\n        self.innerHTML = '';\n        self.storageName = 'canvasDataGrid';\n        self.invalidSearchExpClass = 'canvas-datagrid-invalid-search-regExp';\n        self.localStyleLibraryStorageKey = 'canvas-datagrid-user-style-library';\n        self.dataType = 'application/x-canvas-datagrid';\n        self.orderBy = null;\n        self.orderDirection = 'asc';\n        self.orderings = {\n            columns: [],\n            add: function (orderBy, orderDirection, sortFunction) {\n                self.orderings.columns = self.orderings.columns.filter(function (col) {\n                    return col.orderBy !== orderBy;\n                });\n                self.orderings.columns.push({\n                    orderBy: orderBy,\n                    orderDirection: orderDirection,\n                    sortFunction: sortFunction\n                });\n            },\n            sort: function () {\n                self.orderings.columns.forEach(function (col) {\n                    self.data.sort(col.sortFunction(col.orderBy, col.orderDirection));\n                });\n            }\n        };\n        self.columnFilters = {};\n        self.filters = {};\n        self.frozenRow = 0;\n        self.frozenColumn = 0;\n        self.ellipsisCache = {};\n        self.scrollCache = { x: [], y: [] };\n        self.scrollBox = {};\n        self.visibleRows = [];\n        self.visibleCells = [];\n        self.sizes = {\n            rows: {},\n            columns: {},\n            trees: {}\n        };\n        self.currentFilter = function () {\n            return true;\n        };\n        self.selections = [];\n        self.hovers = {};\n        self.attributes = {};\n        self.style = {};\n        self.formatters = {};\n        self.sorters = {};\n        self.parsers = {};\n        self.schemaHashes = {};\n        self.events = {};\n        self.changes = [];\n        self.scrollIndexTop = 0;\n        self.scrollPixelTop = 0;\n        self.scrollIndexLeft = 0;\n        self.scrollPixelLeft = 0;\n        self.childGrids = {};\n        self.openChildren = {};\n        self.scrollModes = [\n            'vertical-scroll-box',\n            'vertical-scroll-top',\n            'vertical-scroll-bottom',\n            'horizontal-scroll-box',\n            'horizontal-scroll-right',\n            'horizontal-scroll-left'\n        ];\n        self.componentL1Events = {};\n        self.eventNames = ['afterdraw', 'afterrendercell', 'attributechanged', 'beforebeginedit',\n            'beforecreatecellgrid', 'beforedraw', 'beforeendedit', 'beforerendercell', 'beforerendercellgrid',\n            'beginedit', 'cellmouseout', 'cellmouseover', 'click', 'collapsetree', 'contextmenu', 'copy',\n            'datachanged', 'dblclick', 'endedit', 'expandtree', 'formatcellvalue', 'keydown', 'keypress',\n            'keyup', 'mousedown', 'mousemove', 'mouseup', 'newrow', 'ordercolumn', 'rendercell', 'rendercellgrid',\n            'renderorderbyarrow', 'rendertext', 'rendertreearrow', 'reorder', 'reordering', 'resize',\n            'resizecolumn', 'resizerow', 'schemachanged', 'scroll', 'selectionchanged', 'stylechanged',\n            'touchcancel', 'touchend', 'touchmove', 'touchstart', 'wheel'];\n        self.mouse = { x: 0, y: 0};\n        self.getSelectedData = function (expandToRow) {\n            var d = [], s = self.getSchema(), l = self.data.length;\n            if (l === 0) { return []; }\n            self.selections.forEach(function (row, index) {\n                if (!row) { return; }\n                if (index === l) { return; }\n                if (row.length === 0) {\n                    d[index] = null;\n                    return;\n                }\n                d[index] = {};\n                row.forEach(function (col) {\n                    var orderedIndex;\n                    if (col === -1 || !s[col]) { return; }\n                    orderedIndex = self.orders.columns[col];\n                    if (!expandToRow && s[orderedIndex].hidden) { return; }\n                    if (self.data[index]) {\n                        d[index][s[orderedIndex].name] = self.data[index][s[orderedIndex].name];\n                    }\n                });\n            });\n            return d;\n        };\n        self.getColumnHeaderCellHeight = function () {\n            if (!self.attributes.showColumnHeaders) { return 0; }\n            return ((self.sizes.rows[-1] || self.style.columnHeaderCellHeight) * self.scale);\n        };\n        self.getRowHeaderCellWidth = function () {\n            if (!self.attributes.showRowHeaders) { return 0; }\n            return (self.sizes.columns[-1] || self.style.rowHeaderCellWidth) * self.scale;\n        };\n        self.setStorageData = function () {\n            if (!self.attributes.saveAppearance || !self.attributes.name) { return; }\n            var visibility = {};\n            self.getSchema().forEach(function (column) {\n                visibility[column.name] = !column.hidden;\n            });\n            localStorage.setItem(self.storageName + '-' + self.attributes.name, JSON.stringify({\n                sizes: {\n                    rows: self.sizes.rows,\n                    columns: self.sizes.columns\n                },\n                orders: {\n                    rows: self.orders.rows,\n                    columns: self.orders.columns\n                },\n                orderBy: self.orderBy,\n                orderDirection: self.orderDirection,\n                visibility: visibility\n            }));\n        };\n        self.getSchema = function () {\n            return self.schema || self.tempSchema || [];\n        };\n        function fillArray(low, high) {\n            var i = [], x;\n            for (x = low; x <= high; x += 1) {\n                i[x] = x;\n            }\n            return i;\n        }\n        self.createColumnOrders = function () {\n            var s = self.getSchema();\n            self.orders.columns = fillArray(0, s.length - 1);\n        };\n        self.createRowOrders = function () {\n            self.orders.rows = fillArray(0, self.data.length - 1);\n        };\n        self.getVisibleSchema = function () {\n            return self.getSchema().filter(function (col) {\n                return !col.hidden;\n            });\n        };\n        self.applyDefaultValue = function (row, header) {\n            var d = header.defaultValue || '';\n            if (typeof d === 'function') {\n                d = d.apply(self.intf, [header]);\n            }\n            row[header.name] = d;\n        };\n        self.createNewRowData = function () {\n            self.newRow = {};\n            self.getSchema().forEach(function forEachHeader(header) {\n                self.applyDefaultValue(self.newRow, header);\n            });\n        };\n        self.getSchemaNameHash = function (key) {\n            var n = 0;\n            while (self.schemaHashes[key]) {\n                n += 1;\n                key = key + n;\n            }\n            return key;\n        };\n        self.filter = function (type) {\n            var f = self.filters[type];\n            if (!f && type !== undefined) {\n                console.warn('Cannot find filter for type %s, falling back to substring match.', type);\n                f = self.filters.string;\n            }\n            return f;\n        };\n        self.applyFilter = function () {\n            self.refreshFromOrigialData();\n            Object.keys(self.columnFilters).forEach(function (filter) {\n                var header = self.getHeaderByName(filter);\n                if (!header) {\n                    return;\n                }\n                self.currentFilter = header.filter || self.filter(header.type || 'string');\n                self.data = self.data.filter(function (row) {\n                    return self.currentFilter(row[filter], self.columnFilters[filter]);\n                });\n            });\n            self.resize();\n            self.draw(true);\n        };\n        self.applyDataTransforms = function () {\n            self.applyFilter();\n            self.orderings.sort();\n        }\n        self.getBestGuessDataType = function (columnName, data) {\n            var t, x, l = data.length;\n            for (x = 0; x < l; x += 1) {\n                if (data[x] !== undefined && data[x] !== null && [null, undefined].indexOf(data[x][columnName]) !== -1) {\n                    t = typeof data[x];\n                    return t === 'object' ? 'string' : t;\n                }\n            }\n            return 'string';\n        };\n        self.drawChildGrids = function () {\n            Object.keys(self.childGrids).forEach(function (gridKey) {\n                self.childGrids[gridKey].draw();\n            });\n        };\n        self.resizeChildGrids = function () {\n            Object.keys(self.childGrids).forEach(function (gridKey) {\n                self.childGrids[gridKey].resize();\n            });\n        };\n        self.autoScrollZone = function (e, x, y, ctrl) {\n            var setTimer,\n                rowHeaderCellWidth = self.getRowHeaderCellWidth(),\n                columnHeaderCellHeight = self.getColumnHeaderCellHeight();\n            if (y !== -1) {\n                if (x > self.width - self.attributes.selectionScrollZone && x < self.width) {\n                    self.scrollBox.scrollLeft += self.attributes.selectionScrollIncrement;\n                    setTimer = true;\n                }\n                if (x - self.attributes.selectionScrollZone - rowHeaderCellWidth < 0) {\n                    self.scrollBox.scrollLeft -= self.attributes.selectionScrollIncrement;\n                    setTimer = true;\n                }\n            }\n            if (y !== -1) {\n                if (y > self.height - self.attributes.selectionScrollZone && y < self.height) {\n                    self.scrollBox.scrollTop += self.attributes.selectionScrollIncrement;\n                    setTimer = true;\n                }\n                if (y - self.attributes.selectionScrollZone - columnHeaderCellHeight < 0) {\n                    self.scrollBox.scrollTop -= self.attributes.selectionScrollIncrement;\n                    setTimer = true;\n                }\n            }\n            if (setTimer && !ctrl && self.currentCell && self.currentCell.columnIndex !== -1) {\n                self.scrollTimer = setTimeout(self.mousemove, self.attributes.scrollRepeatRate, e);\n            }\n        };\n        self.refreshFromOrigialData = function () {\n            self.data = self.originalData.filter(function (row) {\n                return true;\n            });\n        };\n        self.validateColumn = function (c, s) {\n            if (!c.name) {\n                throw new Error('A column must contain at least a name.');\n            }\n            if (s.filter(function (i) { return i.name === c.name; }).length > 0) {\n                throw new Error('A column with the name '\n                    + c.name + ' already exists and cannot be added again.');\n            }\n            return true;\n        };\n        self.setDefaults = function (obj1, obj2, key, def) {\n            obj1[key] = obj2[key] === undefined ? def : obj2[key];\n        };\n        self.setAttributes = function () {\n            self.defaults.attributes.forEach(function eachAttribute(i) {\n                self.setDefaults(self.attributes, self.args, i[0], i[1]);\n            });\n        };\n        self.setStyle = function () {\n            self.defaults.styles.forEach(function eachStyle(i) {\n                self.setDefaults(self.style, self.args.style || {}, i[0], i[1]);\n            });\n        };\n        self.autosize = function (colName) {\n            self.getVisibleSchema().forEach(function (col, colIndex) {\n                if (col.name === colName || colName === undefined) {\n                    self.sizes.columns[colIndex]\n                        = Math.max(self.findColumnMaxTextLength(col.name), self.style.minColumnWidth);\n                }\n            });\n            self.sizes.columns[-1] = self.findColumnMaxTextLength('cornerCell');\n        };\n        self.dispose = function () {\n            if (!self.isChildGrid && self.canvas && self.canvas.parentNode) {\n                self.canvas.parentNode.removeChild(self.canvas);\n            }\n            if(!self.isChildGrid) {\n                document.body.removeChild(self.controlInput)\n            }\n            self.eventParent.removeEventListener('mouseup', self.mouseup, false);\n            self.eventParent.removeEventListener('mousedown', self.mousedown, false);\n            self.eventParent.removeEventListener('dblclick', self.dblclick, false);\n            self.eventParent.removeEventListener('click', self.click, false);\n            self.eventParent.removeEventListener('mousemove', self.mousemove);\n            self.eventParent.removeEventListener('wheel', self.scrollWheel, false);\n            self.canvas.removeEventListener('contextmenu', self.contextmenu, false);\n            self.canvas.removeEventListener('copy', self.copy);\n            self.controlInput.removeEventListener('copy', self.copy);\n            self.controlInput.removeEventListener('cut', self.cut);\n            self.controlInput.removeEventListener('paste', self.paste);\n            self.controlInput.removeEventListener('keypress', self.keypress, false);\n            self.controlInput.removeEventListener('keyup', self.keyup, false);\n            self.controlInput.removeEventListener('keydown', self.keydown, false);\n            window.removeEventListener('resize', self.resize);\n            if (self.observer && self.observer.disconnect) {\n                self.observer.disconnect();\n            }\n        };\n        self.tryLoadStoredSettings = function () {\n            var s;\n            self.reloadStoredValues();\n            if (self.storedSettings\n                    && typeof self.storedSettings.orders === 'object'\n                    && self.storedSettings.orders !== null) {\n                if (self.storedSettings.orders.rows.length >= (self.data || []).length) {\n                    self.orders.rows = self.storedSettings.orders.rows;\n                }\n                s = self.getSchema();\n                if (self.storedSettings.orders.columns.length === s.length) {\n                    self.orders.columns = self.storedSettings.orders.columns;\n                }\n                self.orderBy = self.storedSettings.orderBy === undefined\n                    ? s[0].name : self.storedSettings.orderBy;\n                self.orderDirection = self.storedSettings.orderDirection === undefined\n                    ? 'asc' : self.storedSettings.orderDirection;\n                if (self.storedSettings.orderBy !== undefined && self.getHeaderByName(self.orderBy) && self.orderDirection) {\n                    self.order(self.orderBy, self.orderDirection);\n                }\n            }\n        };\n        self.getDomRoot = function () {\n            return self.shadowRoot ? self.shadowRoot.host : self.parentNode;\n        };\n        self.getFontName = function (fontStyle) {\n            return fontStyle.replace(/\\d+\\.?\\d*px/, '');\n        };\n        self.getFontHeight = function (fontStyle) {\n            return parseFloat(fontStyle, 10);\n        };\n        self.parseStyleValue = function (key) {\n            if (/Font/.test(key)) {\n                self.style[key + 'Height'] = self.getFontHeight(self.style[key]);\n                self.style[key + 'Name'] = self.getFontName(self.style[key]);\n                return;\n            }\n            // when inheriting styles from already instantiated grids, don't parse already parsed values.\n            if (key === 'moveOverlayBorderSegments' && typeof self.style[key] === 'string') {\n                self.style[key] = self.style[key].split(',')\n                    .map(function (i) { return parseInt(i, 10); });\n            }\n        };\n        self.initProp = function (propName) {\n            if (!self.args[propName]) { return; }\n            Object.keys(self.args[propName]).forEach(function (key) {\n                self[propName][key] = self.args[propName][key];\n            });\n        };\n        self.getStyleProperty = function (key) {\n            if (self.styleKeys.indexOf(key) === -1) {\n                return self.parentNodeStyle[key];\n            }\n            return self.style[key];\n        };\n        self.setStyleProperty = function (key, value, supressDrawAndEvent) {\n            var isDim = ['height', 'width', 'minHeight', 'minWidth', 'maxHeight', 'maxWidth'].indexOf(key) !== -1;\n            if (self.styleKeys.indexOf(key) === -1) {\n                self.parentNodeStyle[key] = value;\n            } else {\n                if (/-/.test(key)) {\n                    key = self.dehyphenateProperty(key);\n                }\n                self.style[key] = value;\n                self.parseStyleValue(key);\n            }\n            if (isDim) {\n                self.resize();\n            }\n            if (!supressDrawAndEvent) {\n                self.draw(true);\n                self.dispatchEvent('stylechanged', {name: 'style', value: value});\n            }\n        };\n        self.reloadStoredValues = function () {\n            if (self.attributes.name && self.attributes.saveAppearance) {\n                try {\n                    self.storedSettings = localStorage.getItem(self.storageName + '-' + self.attributes.name);\n                } catch (e) {\n                    console.warn(\"Error loading stored values. \" + e.message);\n                    self.storedSettings = undefined;\n                }\n                if (self.storedSettings) {\n                    try {\n                        self.storedSettings = JSON.parse(self.storedSettings);\n                    } catch (e) {\n                        console.warn('could not read settings from localStore', e);\n                        self.storedSettings = undefined;\n                    }\n                }\n                if (self.storedSettings) {\n                    if (typeof self.storedSettings.sizes === 'object'\n                            && self.storedSettings.sizes !== null) {\n                        self.sizes.rows = self.storedSettings.sizes.rows;\n                        self.sizes.columns = self.storedSettings.sizes.columns;\n                        ['trees', 'columns', 'rows'].forEach(function (i) {\n                            if (!self.sizes[i]) {\n                                self.sizes[i] = {};\n                            }\n                        });\n                    }\n                    if (typeof self.storedSettings.visibility === 'object') {\n                        self.getSchema().forEach(function (column) {\n                            if (self.storedSettings.visibility && self.storedSettings.visibility[column.name] !== undefined) {\n                                column.hidden = !self.storedSettings.visibility[column.name];\n                            }\n                        });\n                    }\n                }\n            }\n        };\n        self.init = function () {\n            if (self.initialized) { return; }\n            function addStyleKeyIfNoneExists(key) {\n                if (self.styleKeys.indexOf(key) === -1) {\n                    self.styleKeys.push(key);\n                }\n            }\n            var publicStyleKeyIntf = {};\n            self.setAttributes();\n            self.setStyle();\n            self.initScrollBox();\n            self.setDom();\n            self.nodeType = 'canvas-datagrid';\n            self.ie = /Trident/.test(window.navigator.userAgent);\n            self.edge = /Edge/.test(window.navigator.userAgent);\n            self.webKit = /WebKit/.test(window.navigator.userAgent);\n            self.moz = /Gecko/.test(window.navigator.userAgent);\n            self.mobile = /Mobile/i.test(window.navigator.userAgent);\n            self.cursorGrab = 'grab';\n            self.cursorGrabing = 'grabbing';\n            self.cursorGrab = self.webKit ? '-webkit-grab' : self.cursorGrab;\n            self.cursorGrabing = self.moz ? '-webkit-grabbing' : self.cursorGrabbing;\n            self.pointerLockPosition = {x: 0, y: 0};\n            Object.keys(self.style).forEach(self.parseStyleValue);\n            self.intf.moveSelection = self.moveSelection;\n            self.intf.moveTo = self.moveTo;\n            self.intf.addEventListener = self.addEventListener;\n            self.intf.removeEventListener = self.removeEventListener;\n            self.intf.dispatchEvent = self.dispatchEvent;\n            /**\n             * Releases grid resources and removes grid elements.\n             * @memberof canvasDatagrid\n             * @name dispose\n             * @method\n             */\n            self.intf.dispose = self.dispose;\n            /**\n             * Appends the grid to another element later.  Not implemented.\n             * @memberof canvasDatagrid\n             * @name appendTo\n             * @method\n             * @param {number} el The element to append the grid to.\n             */\n            self.intf.appendTo = self.appendTo;\n            self.intf.getVisibleCellByIndex = self.getVisibleCellByIndex;\n            self.intf.filters = self.filters;\n            self.intf.sorters = self.sorters;\n            self.intf.autosize = self.autosize;\n            self.intf.beginEditAt = self.beginEditAt;\n            self.intf.endEdit = self.endEdit;\n            self.intf.setActiveCell = self.setActiveCell;\n            self.intf.forEachSelectedCell = self.forEachSelectedCell;\n            self.intf.scrollIntoView = self.scrollIntoView;\n            self.intf.clearChangeLog = self.clearChangeLog;\n            self.intf.gotoCell = self.gotoCell;\n            self.intf.gotoRow = self.gotoRow;\n            self.intf.getHeaderByName = self.getHeaderByName;\n            self.intf.findColumnScrollLeft = self.findColumnScrollLeft;\n            self.intf.findRowScrollTop = self.findRowScrollTop;\n            self.intf.fitColumnToValues = self.fitColumnToValues;\n            self.intf.findColumnMaxTextLength = self.findColumnMaxTextLength;\n            self.intf.disposeContextMenu = self.disposeContextMenu;\n            self.intf.getCellAt = self.getCellAt;\n            self.intf.isCellVisible = self.isCellVisible;\n            self.intf.isRowVisible = self.isRowVisible;\n            self.intf.isColumnVisible = self.isColumnVisible;\n            self.intf.order = self.order;\n            self.intf.draw = self.draw;\n            self.intf.isComponent = self.isComponent;\n            self.intf.selectArea = self.selectArea;\n            self.intf.clipElement = self.clipElement;\n            self.intf.getSchemaFromData = self.getSchemaFromData;\n            self.intf.setFilter = self.setFilter;\n            self.intf.selectRow = self.selectRow;\n            self.intf.parentGrid = self.parentGrid;\n            self.intf.toggleTree = self.toggleTree;\n            self.intf.expandTree = self.expandTree;\n            self.intf.collapseTree = self.collapseTree;\n            self.intf.canvas = self.canvas;\n            self.intf.context = self.ctx;\n            self.intf.insertRow = self.insertRow;\n            self.intf.deleteRow = self.deleteRow;\n            self.intf.addRow = self.addRow;\n            self.intf.insertColumn = self.insertColumn;\n            self.intf.deleteColumn = self.deleteColumn;\n            self.intf.addColumn = self.addColumn;\n            self.intf.getClippingRect = self.getClippingRect;\n            self.intf.setRowHeight = self.setRowHeight;\n            self.intf.setColumnWidth = self.setColumnWidth;\n            self.intf.resetColumnWidths = self.resetColumnWidths;\n            self.intf.resetRowHeights = self.resetRowHeights;\n            self.intf.resize = self.resize;\n            self.intf.selectColumn = self.selectColumn;\n            self.intf.selectRow = self.selectRow;\n            self.intf.selectAll = self.selectAll;\n            self.intf.selectNone = self.selectNone;\n            self.intf.drawChildGrids = self.drawChildGrids;\n            self.intf.assertPxColor = self.assertPxColor;\n            self.intf.clearPxColorAssertions = self.clearPxColorAssertions;\n            self.intf.integerToAlpha = self.integerToAlpha;\n            self.intf.copy = self.copy;\n            self.intf.setStyleProperty = self.setStyleProperty;\n            Object.defineProperty(self.intf, 'defaults', {\n                get: function () {\n                    return {\n                        styles: self.defaults.styles.reduce(function (a, i) { a[i[0]] = i[1]; return a; }, {}),\n                        attributes: self.defaults.attributes.reduce(function (a, i) { a[i[0]] = i[1]; return a; }, {})\n                    };\n                }\n            });\n            self.styleKeys = Object.keys(self.intf.defaults.styles);\n            self.styleKeys.map(function (i) { return self.hyphenateProperty(i, false); }).forEach(addStyleKeyIfNoneExists);\n            self.styleKeys.map(function (i) { return self.hyphenateProperty(i, true); }).forEach(addStyleKeyIfNoneExists);\n            self.DOMStyles = window.getComputedStyle(document.body, null);\n            self.styleKeys.concat(Object.keys(self.DOMStyles)).forEach(function (key) {\n                // unless this line is here, Object.keys() will not work on <instance>.style\n                publicStyleKeyIntf[key] = undefined;\n                Object.defineProperty(publicStyleKeyIntf, key, {\n                    get: function () {\n                        return self.getStyleProperty(key);\n                    },\n                    set: function (value) {\n                        if (self.initialized) {\n                            self.appliedInlineStyles[key] = value;\n                        }\n                        self.setStyleProperty(key, value);\n                    }\n                });\n            });\n            Object.defineProperty(self.intf, 'shadowRoot', {\n                get: function () {\n                    return self.shadowRoot;\n                }\n            });\n            Object.defineProperty(self.intf, 'activeCell', {\n                get: function () {\n                    return self.activeCell;\n                }\n            });\n            Object.defineProperty(self.intf, 'hasFocus', {\n                get: function () {\n                    return self.hasFocus;\n                }\n            });\n            Object.defineProperty(self.intf, 'style', {\n                get: function () {\n                    return publicStyleKeyIntf;\n                },\n                set: function (valueObject) {\n                    Object.keys(valueObject).forEach(function (key) {\n                        self.setStyleProperty(key, valueObject[key], true);\n                    });\n                    self.draw(true);\n                    self.dispatchEvent('stylechanged', {name: 'style', value: valueObject});\n                }\n            });\n            Object.defineProperty(self.intf, 'attributes', { value: {}});\n            Object.keys(self.attributes).forEach(function (key) {\n                Object.defineProperty(self.intf.attributes, key, {\n                    get: function () {\n                        return self.attributes[key];\n                    },\n                    set: function (value) {\n                        self.attributes[key] = value;\n                        if (key === 'name') {\n                            self.tryLoadStoredSettings();\n                        }\n                        self.draw(true);\n                        self.dispatchEvent('attributechanged', {name: key, value: value[key]});\n                    }\n                });\n            });\n            self.filters.string = function (value, filterFor) {\n                value = String(value);\n                var filterRegExp,\n                    regEnd = /\\/(i|g|m)*$/,\n                    pattern = regEnd.exec(filterFor),\n                    flags = pattern ? pattern[0].substring(1) : '',\n                    flagLength = flags.length;\n                self.invalidFilterRegEx = undefined;\n                if (filterFor.substring(0, 1) === '/' && pattern) {\n                    try {\n                        filterRegExp = new RegExp(filterFor.substring(1, filterFor.length - (flagLength + 1)), flags);\n                    } catch (e) {\n                        self.invalidFilterRegEx = e;\n                        return;\n                    }\n                    return filterRegExp.test(value);\n                }\n                return value.toString ? value.toString().toLocaleUpperCase()\n                    .indexOf(filterFor.toLocaleUpperCase()) !== -1 : false;\n            };\n            self.filters.number = function (value, filterFor) {\n                if (!filterFor) { return true; }\n                return value === filterFor;\n            };\n            ['formatters', 'filters', 'sorters'].forEach(self.initProp);\n            self.applyComponentStyle(false, self.intf);\n            self.reloadStoredValues();\n            if (self.args.data) {\n                self.intf.data = self.args.data;\n            }\n            if (self.intf.innerText || self.intf.textContent) {\n                if (self.intf.dataType === 'application/x-canvas-datagrid') {\n                    self.intf.dataType = 'application/json+x-canvas-datagrid';\n                }\n                self.intf.data = self.intf.innerText || self.intf.textContent;\n            }\n            if (self.args.schema) {\n                self.intf.schema = self.args.schema;\n            }\n            if (self.isChildGrid || !self.isComponent) {\n                requestAnimationFrame(function () { self.resize(true); });\n            } else {\n                self.resize(true);\n            }\n            self.initialized = true;\n            return self;\n        };\n        /**\n         * Removes focus from the grid.\n         * @memberof canvasDatagrid\n         * @name blur\n         * @method\n         */\n        self.intf.blur = function (e) {\n            self.hasFocus = false;\n        };\n        /**\n         * Focuses on the grid.\n         * @memberof canvasDatagrid\n         * @name focus\n         * @method\n         */\n        self.intf.focus = function () {\n            self.hasFocus = true;\n            self.controlInput.focus();\n        };\n        if (self.shadowRoot || self.isChildGrid) {\n            Object.defineProperty(self.intf, 'height', {\n                get: function () {\n                    if (self.shadowRoot) {\n                        return self.shadowRoot.height;\n                    }\n                    return self.parentNode.height;\n                },\n                set: function (value) {\n                    if (self.shadowRoot) {\n                        self.shadowRoot.height = value;\n                    } else {\n                        self.parentNode.height = value;\n                    }\n                    self.resize(true);\n                }\n            });\n            Object.defineProperty(self.intf, 'width', {\n                get: function () {\n                    if (self.shadowRoot) {\n                        return self.shadowRoot.width;\n                    }\n                    return self.parentNode.width;\n                },\n                set: function (value) {\n                    if (self.shadowRoot) {\n                        self.shadowRoot.width = value;\n                    } else {\n                        self.parentNode.width = value;\n                    }\n                    self.resize(true);\n                }\n            });\n            Object.defineProperty(self.intf, 'parentNode', {\n                get: function () {\n                    return self.parentNode;\n                },\n                set: function (value) {\n                    if (!self.isChildGrid) {\n                        throw new TypeError('Cannot set property parentNode which has only a getter');\n                    }\n                    self.parentNode = value;\n                }\n            });\n        }\n        Object.defineProperty(self.intf, 'visibleRowHeights', {\n            get: function () {\n                return self.visibleRowHeights;\n            }\n        });\n        Object.defineProperty(self.intf, 'openChildren', {\n            get: function () {\n                return self.openChildren;\n            }\n        });\n        Object.defineProperty(self.intf, 'childGrids', {\n            get: function () {\n                return Object.keys(self.childGrids).map(function (gridId) {\n                    return self.childGrids[gridId];\n                });\n            }\n        });\n        Object.defineProperty(self.intf, 'isChildGrid', {\n            get: function () {\n                return self.isChildGrid;\n            }\n        });\n        Object.defineProperty(self, 'cursor', {\n            get: function () {\n                return self.parentNodeStyle.cursor;\n            },\n            set: function (value) {\n                if (value === 'cell') { value = 'default'; }\n                if (self.currentCursor !== value) {\n                    self.parentNodeStyle.cursor = value;\n                    self.currentCursor = value;\n                }\n            }\n        });\n        Object.defineProperty(self.intf, 'orderDirection', {\n            get: function () {\n                return self.orderDirection;\n            },\n            set: function (value) {\n                if (value !== 'desc') {\n                    value = 'asc';\n                }\n                self.orderDirection = value;\n                self.order(self.orderBy, self.orderDirection);\n            }\n        });\n        Object.defineProperty(self.intf, 'orderBy', {\n            get: function () {\n                return self.orderBy;\n            },\n            set: function (value) {\n                if (self.getSchema().find(function (col) {\n                        return col.name === value;\n                    }) === undefined) {\n                    throw new Error('Cannot sort by unknown column name.');\n                }\n                self.orderBy = value;\n                self.order(self.orderBy, self.orderDirection);\n            }\n        });\n        if (self.isComponent) {\n            Object.defineProperty(self.intf, 'offsetHeight', {\n                get: function () {\n                    return self.canvas.offsetHeight;\n                }\n            });\n            Object.defineProperty(self.intf, 'offsetWidth', {\n                get: function () {\n                    return self.canvas.offsetWidth;\n                }\n            });\n        }\n        Object.defineProperty(self.intf, 'scrollHeight', {\n            get: function () {\n                return self.scrollBox.scrollHeight;\n            }\n        });\n        Object.defineProperty(self.intf, 'scrollWidth', {\n            get: function () {\n                return self.scrollBox.scrollWidth;\n            }\n        });\n        Object.defineProperty(self.intf, 'scrollTop', {\n            get: function () {\n                return self.scrollBox.scrollTop;\n            },\n            set: function (value) {\n                self.scrollBox.scrollTop = value;\n            }\n        });\n        Object.defineProperty(self.intf, 'scrollLeft', {\n            get: function () {\n                return self.scrollBox.scrollLeft;\n            },\n            set: function (value) {\n                self.scrollBox.scrollLeft = value;\n            }\n        });\n        Object.defineProperty(self.intf, 'sizes', {\n            get: function () {\n                return self.sizes;\n            }\n        });\n        Object.defineProperty(self.intf, 'parentDOMNode', {\n            get: function () {\n                return self.parentDOMNode;\n            }\n        });\n        Object.defineProperty(self.intf, 'input', {\n            get: function () {\n                return self.input;\n            }\n        });\n        Object.defineProperty(self.intf, 'controlInput', {\n            get: function () {\n                return self.controlInput;\n            }\n        });\n        Object.defineProperty(self.intf, 'currentCell', {\n            get: function () {\n                return self.currentCell;\n            }\n        });\n        Object.defineProperty(self.intf, 'visibleCells', {\n            get: function () {\n                return self.visibleCells;\n            }\n        });\n        Object.defineProperty(self.intf, 'visibleRows', {\n            get: function () {\n                return self.visibleRows;\n            }\n        });\n        Object.defineProperty(self.intf, 'selections', {\n            get: function () {\n                return self.selections;\n            }\n        });\n        Object.defineProperty(self.intf, 'dragMode', {\n            get: function () {\n                return self.dragMode;\n            }\n        });\n        Object.defineProperty(self.intf, 'changes', {\n            get: function () {\n                return self.changes;\n            }\n        });\n        self.intf.formatters = self.formatters;\n        Object.defineProperty(self.intf, 'dataType', {\n            get: function () {\n                return self.dataType;\n            },\n            set: function (value) {\n                if (!self.parsers[value]) {\n                    throw new Error('No parser for MIME type ' + value);\n                }\n                self.dataType = value;\n            }\n        });\n        self.eventNames.forEach(function (eventName) {\n            Object.defineProperty(self.intf, 'on' + eventName, {\n                get: function () {\n                    return self.componentL1Events[eventName];\n                },\n                set: function (value) {\n                    self.events[eventName] = [];\n                    self.componentL1Events[eventName] = value;\n                    if (!value) { return; }\n                    self.addEventListener(eventName, value);\n                }\n            });\n        });\n        Object.defineProperty(self.intf, 'frozenRow', {\n            get: function () {\n                return self.frozenRow;\n            },\n            set: function (val) {\n                if (isNaN(val)) {\n                    throw new TypeError('Expected value for frozenRow to be a number.');\n                }\n                if (self.visibleRows.length < val) {\n                    throw new RangeError('Cannot set a value larger than the number of visible rows.');\n                }\n                self.frozenRow = val;\n            }\n        });\n        Object.defineProperty(self.intf, 'frozenColumn', {\n            get: function () {\n                return self.frozenColumn;\n            },\n            set: function (val) {\n                if (isNaN(val)) {\n                    throw new TypeError('Expected value for frozenRow to be a number.');\n                }\n                if (self.getVisibleSchema().length < val) {\n                    throw new RangeError('Cannot set a value larger than the number of visible columns.');\n                }\n                self.frozenColumn = val;\n            }\n        });\n        Object.defineProperty(self.intf, 'scrollIndexRect', {\n            get: function () {\n                return {\n                    top: self.scrollIndexTop,\n                    right: self.scrollIndexRight,\n                    bottom: self.scrollIndexBottom,\n                    left: self.scrollIndexLeft\n                };\n            }\n        });\n        Object.defineProperty(self.intf, 'scrollPixelRect', {\n            get: function () {\n                return {\n                    top: self.scrollPixelTop,\n                    right: self.scrollPixelRight,\n                    bottom: self.scrollPixelBottom,\n                    left: self.scrollPixelLeft\n                };\n            }\n        });\n        Object.defineProperty(self.intf, 'rowOrder', {\n            get: function () {\n                return self.orders.rows;\n            },\n            set: function (val) {\n                if (!Array.isArray(val)) {\n                    throw new TypeError('Value must be an array.');\n                }\n                if (!self.data || val.length < self.data.length) {\n                    throw new RangeError('Array length must be equal to or greater than number of rows.');\n                }\n                self.orders.rows = val;\n            }\n        });\n        Object.defineProperty(self.intf, 'columnOrder', {\n            get: function () {\n                return self.orders.columns;\n            },\n            set: function (val) {\n                if (!Array.isArray(val)) {\n                    throw new TypeError('Value must be an array.');\n                }\n                if (val.length < self.getSchema().length) {\n                    throw new RangeError('Array length must be equal to or greater than number of columns.');\n                }\n                self.orders.columns = val;\n            }\n        });\n        Object.defineProperty(self.intf, 'selectionBounds', {\n            get: function () {\n                return self.getSelectionBounds();\n            }\n        });\n        Object.defineProperty(self.intf, 'selectedRows', {\n            get: function () {\n                return self.getSelectedData(true);\n            }\n        });\n        Object.defineProperty(self.intf, 'selectedCells', {\n            get: function () {\n                return self.getSelectedData();\n            }\n        });\n        Object.defineProperty(self.intf, 'visibleSchema', {\n            get: function () {\n                return self.getVisibleSchema().map(function eachDataRow(col) {\n                    return col;\n                });\n            }\n        });\n        Object.defineProperty(self.intf, 'treeGridAttributes', {\n            get: function () {\n                return self.treeGridAttributes;\n            },\n            set: function setTreeGridAttributes(value) {\n                self.treeGridAttributes = value;\n            }\n        });\n        Object.defineProperty(self.intf, 'cellGridAttributes', {\n            get: function () {\n                return self.cellGridAttributes;\n            },\n            set: function setCellGridAttributes(value) {\n                self.cellGridAttributes = value;\n            }\n        });\n        Object.defineProperty(self.intf, 'ctx', {\n            get: function () {\n                return self.ctx;\n            }\n        });\n        Object.defineProperty(self.intf, 'schema', {\n            get: function schemaGetter() {\n                return self.getSchema();\n            },\n            set: function schemaSetter(value) {\n                if (value === undefined) {\n                    // Issue #89 - allow schema to be set to initialized state\n                    self.schema = undefined;\n                    self.tempSchema = undefined;\n                    self.dispatchEvent('schemachanged', {schema: undefined});\n                    return;\n                }\n                if (!Array.isArray(value) || typeof value[0] !== 'object') {\n                    throw new Error('Schema must be an array of objects.');\n                }\n                if (value[0].name === undefined) {\n                    throw new Error('Expected schema to contain an object with at least a name property.');\n                }\n                self.schema = value.map(function eachSchemaColumn(column, index) {\n                    column.width = column.width || self.style.cellWidth;\n                    column.filter = column.filter || self.filter(column.type);\n                    column.type = column.type || 'string';\n                    column.index = index;\n                    column.columnIndex = index;\n                    column.rowIndex = -1;\n                    return column;\n                });\n                self.tempSchema = undefined;\n                self.createNewRowData();\n                self.createColumnOrders();\n                self.tryLoadStoredSettings();\n                if (self.storedSettings && typeof self.storedSettings.visibility === 'object') {\n                    self.schema.forEach(function hideEachSchemaColumn(column, index) {\n                        if (self.storedSettings && self.storedSettings.visibility[column.name] !== undefined) {\n                            column.hidden = !self.storedSettings.visibility[column.name];\n                        }\n                    });\n                }\n                self.resize(true);\n                self.dispatchEvent('schemachanged', {schema: self.schema});\n            }\n        });\n        /**\n         * Gets an array of currently registered MIME types.\n         * @memberof canvasDatagrid\n         * @name getDataTypes\n         * @method\n         */\n        self.intf.getTypes = function () {\n            return Object.keys(self.parsers);\n        };\n        self.parseInnerHtml = function (data) {\n            if (!data || /^ +$/.test(data)) {\n                return [];\n            }\n            try {\n                data = JSON.parse(data);\n            } catch (e) {\n                console.warn(Error('Cannot parse application/json+x-canvas-datagrid formated data. '\n                    + e.message + '  \\nNote: canvas-datagrid.innerHTML is for string data only.  '\n                    + 'Use the canvas-datagrid.data property to set object data.'));\n            }\n            return data;\n        };\n        self.parsers['application/json+x-canvas-datagrid'] = function (data, callback) {\n            self.parsers['application/x-canvas-datagrid'](self.parseInnerHtml(data), function (data, schema) {\n                return callback(data, schema);\n            });\n        };\n        self.parsers['application/x-canvas-datagrid'] = function (data, callback) {\n            return callback(data);\n        };\n        self.intf.parsers = self.parsers;\n        // send to dataType ETL function to extract from input data\n        // and transform into native [{}, {}] format\n        self.etl = function (data, callback) {\n            if (!self.intf.parsers[self.dataType]) {\n                throw new Error('Unsupported data type.');\n            }\n            self.intf.parsers[self.dataType](data, function (data, schema) {\n                if (Array.isArray(schema)) {\n                    self.schema = schema;\n                }\n                // Issue #89 - allow schema to be auto-created every time data is set\n                if (self.attributes.autoGenerateSchema) {\n                    self.schema = self.getSchemaFromData(data);\n                }\n                if (!self.schema) {\n                    self.tempSchema = self.getSchemaFromData(data);\n                }\n                if (self.getSchema()) {\n                    self.createColumnOrders();\n                }\n                // set the unfiltered/sorted data array\n                self.originalData = data;\n                // apply filter, sort, etc to incoming dataset\n                self.applyDataTransforms();\n                // empty data was set\n                if (!self.schema && (self.data || []).length === 0) {\n                    self.tempSchema = [{name: ''}];\n                }\n                self.fitColumnToValues('cornerCell', true);\n                if ((self.tempSchema && !self.schema) || self.attributes.autoGenerateSchema) {\n                    self.createColumnOrders();\n                    self.dispatchEvent('schemachanged', {schema: self.tempSchema});\n                }\n                callback();\n            });\n        };\n        Object.defineProperty(self.intf, 'data', {\n            get: function dataGetter() {\n                return self.data;\n            },\n            set: function dataSetter(value) {\n                self.etl(value, function () {\n                    self.changes = [];\n                    self.createNewRowData();\n                    if (self.attributes.autoResizeColumns && self.data.length > 0\n                            && self.storedSettings === undefined) {\n                        self.autosize();\n                    }\n                    // set the header column to fit the numbers in it\n                    self.fitColumnToValues('cornerCell', true);\n                    self.createRowOrders();\n                    self.tryLoadStoredSettings();\n                    self.dispatchEvent('datachanged', {data: self.data});\n                    self.resize(true);\n                });\n            }\n        });\n        self.initScrollBox = function () {\n            var sHeight = 0,\n                sWidth = 0,\n                scrollTop = 0,\n                scrollLeft = 0,\n                scrollHeight = 0,\n                scrollWidth = 0,\n                scrollBoxHeight = 20,\n                scrollBoxWidth = 20;\n            function setScrollTop(value, preventScrollEvent) {\n                if (isNaN(value)) {\n                    throw new Error('ScrollTop value must be a number');\n                }\n                if (value < 0) {\n                    value = 0;\n                }\n                if (value > scrollHeight) {\n                    value = scrollHeight;\n                }\n                if (scrollHeight < 0) {\n                    value = 0;\n                }\n                scrollTop = value;\n                if (!preventScrollEvent) {\n                    self.scroll();\n                }\n            }\n            function setScrollLeft(value, preventScrollEvent) {\n                if (isNaN(value)) {\n                    throw new Error('ScrollLeft value must be a number');\n                }\n                if (value < 0) {\n                    value = 0;\n                }\n                if (value > scrollWidth) {\n                    value = scrollWidth;\n                }\n                if (scrollWidth < 0) {\n                    value = 0;\n                }\n                scrollLeft = value;\n                if (!preventScrollEvent) {\n                    self.scroll();\n                }\n            }\n            self.scrollBox.toString = function () {\n                return '{\"width\": ' + scrollWidth.toFixed(2)\n                    + ', \"height\": ' + scrollHeight.toFixed(2)\n                    + ', \"left\": ' + scrollLeft.toFixed(2)\n                    + ', \"top\": ' + scrollTop.toFixed(2)\n                    + ', \"widthRatio\": ' + self.scrollBox.widthBoxRatio.toFixed(5)\n                    + ', \"heightRatio\": ' + self.scrollBox.heightBoxRatio.toFixed(5) + '}';\n            };\n            self.scrollBox.scrollTo = function (x, y, supressDrawEvent) {\n                setScrollLeft(x, true);\n                setScrollTop(y, supressDrawEvent);\n            };\n            Object.defineProperty(self.scrollBox, 'scrollBoxHeight', {\n                get: function () {\n                    return scrollBoxHeight;\n                },\n                set: function (value) {\n                    scrollBoxHeight = value;\n                }\n            });\n            Object.defineProperty(self.scrollBox, 'scrollBoxWidth', {\n                get: function () {\n                    return scrollBoxWidth;\n                },\n                set: function (value) {\n                    scrollBoxWidth = value;\n                }\n            });\n            Object.defineProperty(self.scrollBox, 'height', {\n                get: function () {\n                    return sHeight;\n                },\n                set: function (value) {\n                    sHeight = value;\n                }\n            });\n            Object.defineProperty(self.scrollBox, 'width', {\n                get: function () {\n                    return sWidth;\n                },\n                set: function (value) {\n                    sWidth = value;\n                }\n            });\n            Object.defineProperty(self.scrollBox, 'scrollTop', {\n                get: function () {\n                    return scrollTop;\n                },\n                set: setScrollTop\n            });\n            Object.defineProperty(self.scrollBox, 'scrollLeft', {\n                get: function () {\n                    return scrollLeft;\n                },\n                set: setScrollLeft\n            });\n            Object.defineProperty(self.scrollBox, 'scrollHeight', {\n                get: function () {\n                    return scrollHeight;\n                },\n                set: function (value) {\n                    if (scrollTop > value) {\n                        scrollTop = Math.max(value, 0);\n                    }\n                    scrollHeight = value;\n                }\n            });\n            Object.defineProperty(self.scrollBox, 'scrollWidth', {\n                get: function () {\n                    return scrollWidth;\n                },\n                set: function (value) {\n                    if (scrollLeft > value) {\n                        scrollLeft = Math.max(value, 0);\n                    }\n                    scrollWidth = value;\n                }\n            });\n        };\n        return;\n    };\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/intf.js\n// module id = 6\n// module chunks = 0","/*jslint browser: true, unparam: true, todo: true*/\n/*globals define: true, MutationObserver: false, requestAnimationFrame: false, performance: false, btoa: false, Event: false*/\ndefine([], function () {\n    'use strict';\n    return function (self) {\n        var zIndexTop, hoverScrollTimeout, autoCompleteContext;\n        function applyContextItemStyle(contextItemContainer) {\n            self.createInlineStyle(contextItemContainer, 'canvas-datagrid-context-menu-item' + (self.mobile ? '-mobile' : ''));\n            contextItemContainer.addEventListener('mouseover', function () {\n                self.createInlineStyle(contextItemContainer, 'canvas-datagrid-context-menu-item:hover');\n            });\n            contextItemContainer.addEventListener('mouseout', function () {\n                self.createInlineStyle(contextItemContainer, 'canvas-datagrid-context-menu-item');\n            });\n        }\n        function createContextMenu(ev, pos, items, parentContextMenu) {\n            var container = document.createElement('div'),\n                upArrow = document.createElement('div'),\n                downArrow = document.createElement('div'),\n                children = [],\n                selectedIndex = -1,\n                intf = {},\n                rect;\n            if (!Array.isArray(items)) { throw new Error('createContextMenu expects an array.'); }\n            function createItems() {\n                items.forEach(function (item) {\n                    var contextItemContainer = document.createElement('div'),\n                        childMenuArrow;\n                    function removeChildContext(e) {\n                        if (e.relatedTarget === container\n                                || item.contextMenu.container === e.relatedTarget\n                                || childMenuArrow === e.relatedTarget\n                                || (contextItemContainer === e.relatedTarget)\n                                || item.contextMenu.container.contains(e.relatedTarget)\n                                ) { return; }\n                        item.contextMenu.dispose();\n                        children.splice(children.indexOf(item.contextMenu), 1);\n                        item.contextMenu = undefined;\n                        contextItemContainer.removeEventListener('mouseout', removeChildContext);\n                        container.removeEventListener('mouseout', removeChildContext);\n                        contextItemContainer.setAttribute('contextOpen', '0');\n                        contextItemContainer.setAttribute('opening', '0');\n                    }\n                    function contextAddCallback(items) {\n                        // check yet again if the user hasn't moved off\n                        if (contextItemContainer.getAttribute('opening') !== '1' ||\n                                contextItemContainer.getAttribute('contextOpen') === '1') {\n                            return;\n                        }\n                        var cPos = contextItemContainer.getBoundingClientRect();\n                        cPos = {\n                            left: cPos.left + self.style.childContextMenuMarginLeft + container.offsetWidth,\n                            top: cPos.top + self.style.childContextMenuMarginTop,\n                            bottom: cPos.bottom,\n                            right: cPos.right\n                        };\n                        item.contextMenu = createContextMenu(ev, cPos, items, intf);\n                        contextItemContainer.setAttribute('contextOpen', '1');\n                        contextItemContainer.addEventListener('mouseout', removeChildContext);\n                        container.addEventListener('mouseout', removeChildContext);\n                        children.push(item.contextMenu);\n                    }\n                    function createChildContext() {\n                        var i;\n                        if (contextItemContainer.getAttribute('contextOpen') === '1') {\n                            return;\n                        }\n                        contextItemContainer.setAttribute('opening', '1');\n                        if (typeof item.items === 'function') {\n                            i  = item.items.apply(intf, [function (items) {\n                                contextAddCallback(items);\n                            }]);\n                            if (i !== undefined && Array.isArray(i)) {\n                                contextAddCallback(i);\n                            }\n                            return;\n                        }\n                        contextAddCallback(item.items);\n                    }\n                    function addItem(item) {\n                        function addContent(content) {\n                            if (content === null) { return; }\n                            if (typeof content === 'function') {\n                                return addContent(content(ev));\n                            }\n                            if (typeof content === 'object') {\n                                contextItemContainer.appendChild(content);\n                                return;\n                            }\n                            applyContextItemStyle(contextItemContainer);\n                            contextItemContainer.innerHTML = content;\n                            return;\n                        }\n                        addContent(item.title);\n                        item.contextItemContainer = contextItemContainer;\n                        if ((item.items && item.items.length > 0) || typeof item.items === 'function') {\n                            childMenuArrow = document.createElement('div');\n                            self.createInlineStyle(childMenuArrow, 'canvas-datagrid-context-child-arrow');\n                            childMenuArrow.innerHTML = self.style.childContextMenuArrowHTML;\n                            contextItemContainer.appendChild(childMenuArrow);\n                            contextItemContainer.addEventListener('mouseover', createChildContext);\n                            contextItemContainer.addEventListener('mouseout', function () {\n                                contextItemContainer.setAttribute('opening', '0');\n                            });\n                        }\n                        if (item.click) {\n                            contextItemContainer.addEventListener('click', function (ev) {\n                                item.click.apply(self, [ev]);\n                            });\n                        }\n                    }\n                    addItem(item);\n                    container.appendChild(contextItemContainer);\n                });\n            }\n            function clickIndex(idx) {\n                items[idx].contextItemContainer.dispatchEvent(new Event('click'));\n            }\n            function checkArrowVisibility() {\n                if (container.scrollTop > 0) {\n                    self.parentDOMNode.appendChild(upArrow);\n                } else if (upArrow.parentNode) {\n                    upArrow.parentNode.removeChild(upArrow);\n                }\n                if (container.scrollTop >= container.scrollHeight - container.offsetHeight && downArrow.parentNode) {\n                    downArrow.parentNode.removeChild(downArrow);\n                } else if (container.scrollHeight - container.offsetHeight > 0\n                        && !(container.scrollTop >= container.scrollHeight - container.offsetHeight)) {\n                    self.parentDOMNode.appendChild(downArrow);\n                }\n            }\n            function startHoverScroll(type) {\n                return function t() {\n                    var a = self.attributes.contextHoverScrollAmount;\n                    if (type === 'up' && container.scrollTop === 0) { return; }\n                    if (type === 'down' && container.scrollTop === container.scrollHeight) { return; }\n                    container.scrollTop += (type === 'up' ? -a : a);\n                    hoverScrollTimeout = setTimeout(t, self.attributes.contextHoverScrollRateMs, type);\n                };\n            }\n            function endHoverScroll(type) {\n                return function () {\n                    clearTimeout(hoverScrollTimeout);\n                };\n            }\n            function init() {\n                var loc = {},\n                    s = self.scrollOffset(self.canvas);\n                if (zIndexTop === undefined) {\n                    zIndexTop = self.style.contextMenuZIndex;\n                }\n                createItems();\n                self.createInlineStyle(container, 'canvas-datagrid-context-menu' + (self.mobile ? '-mobile' : ''));\n                loc.x = pos.left - s.left;\n                loc.y = pos.top - s.top;\n                loc.height = 0;\n                zIndexTop += 1;\n                container.style.position = 'absolute';\n                upArrow.style.color = self.style.contextMenuArrowColor;\n                downArrow.style.color = self.style.contextMenuArrowColor;\n                [upArrow, downArrow].forEach(function (el) {\n                    el.style.textAlign = 'center';\n                    el.style.position = 'absolute';\n                    el.style.zIndex = zIndexTop + 1;\n                });\n                container.style.zIndex = zIndexTop;\n                if (parentContextMenu && parentContextMenu.inputDropdown) {\n                    container.style.maxHeight = window.innerHeight - loc.y - self.style.autocompleteBottomMargin + 'px';\n                    container.style.minWidth = pos.width + 'px';\n                    loc.y += pos.height;\n                }\n                if (self.mobile) {\n                    container.style.width = pos.width + 'px';\n                }\n                container.style.left = loc.x + 'px';\n                container.style.top = loc.y + 'px';\n                container.addEventListener('scroll', checkArrowVisibility);\n                container.addEventListener('wheel', function (e) {\n                    if (self.hasFocus) {\n                        container.scrollTop += e.deltaY;\n                        container.scrollLeft += e.deltaX;\n                    }\n                    checkArrowVisibility();\n                });\n                upArrow.innerHTML = self.style.contextMenuArrowUpHTML;\n                downArrow.innerHTML = self.style.contextMenuArrowDownHTML;\n                container.appendChild(upArrow);\n                document.body.appendChild(downArrow);\n                document.body.appendChild(container);\n                rect = container.getBoundingClientRect();\n                // TODO: fix !(parentContextMenu && parentContextMenu.inputDropdown) state (autocomplete)\n                if (rect.bottom > window.innerHeight) {\n                    if (!(parentContextMenu && parentContextMenu.inputDropdown)) {\n                        loc.y -= (rect.bottom + self.style.contextMenuWindowMargin) - window.innerHeight;\n                    }\n                    if (loc.y < 0) { loc.y = self.style.contextMenuWindowMargin; }\n                    if (container.offsetHeight > window.innerHeight - self.style.contextMenuWindowMargin) {\n                        container.style.height = window.innerHeight - (self.style.contextMenuWindowMargin * 2) + 'px';\n                    }\n                }\n                if (rect.right > window.innerWidth) {\n                    loc.x -= rect.right - window.innerWidth + self.style.contextMenuWindowMargin;\n                }\n                if (loc.x < 0) { loc.x = self.style.contextMenuWindowMargin; }\n                if (loc.y < 0) { loc.y = self.style.contextMenuWindowMargin; }\n                container.style.left = loc.x + 'px';\n                container.style.top = loc.y + 'px';\n                rect = container.getBoundingClientRect();\n                upArrow.style.top = rect.top + 'px';\n                downArrow.style.top = rect.top + rect.height - downArrow.offsetHeight + 'px';\n                upArrow.style.left = rect.left + 'px';\n                downArrow.style.left = rect.left + 'px';\n                downArrow.style.width = container.offsetWidth + 'px';\n                upArrow.style.width = container.offsetWidth + 'px';\n                downArrow.addEventListener('mouseover', startHoverScroll('down'));\n                downArrow.addEventListener('mouseout', endHoverScroll('down'));\n                upArrow.addEventListener('mouseover', startHoverScroll('up'));\n                upArrow.addEventListener('mouseout', endHoverScroll('up'));\n                checkArrowVisibility();\n            }\n            intf.parentGrid = self.intf;\n            intf.parentContextMenu = parentContextMenu;\n            intf.container = container;\n            init();\n            intf.clickIndex = clickIndex;\n            intf.rect = rect;\n            intf.items = items;\n            intf.upArrow = upArrow;\n            intf.downArrow = downArrow;\n            intf.dispose = function () {\n                clearTimeout(hoverScrollTimeout);\n                children.forEach(function (c) {\n                    c.dispose();\n                });\n                [downArrow, upArrow, container].forEach(function (el) {\n                    if (el.parentNode) { el.parentNode.removeChild(el); }\n                });\n            };\n            Object.defineProperty(intf, 'selectedIndex', {\n                get: function () {\n                    return selectedIndex;\n                },\n                set: function (value) {\n                    if (typeof value !== 'number' || isNaN(value || !isFinite(value))) {\n                        throw new Error('Context menu selected index must be a sane number.');\n                    }\n                    selectedIndex = value;\n                    if (selectedIndex > items.length - 1) {\n                        selectedIndex = items.length - 1;\n                    }\n                    if (selectedIndex < 0) {\n                        selectedIndex = 0;\n                    }\n                    items.forEach(function (item, index) {\n                        if (index === selectedIndex) {\n                            return self.createInlineStyle(item.contextItemContainer, 'canvas-datagrid-context-menu-item:hover');\n                        }\n                        self.createInlineStyle(item.contextItemContainer, 'canvas-datagrid-context-menu-item');\n                    });\n                }\n            });\n            return intf;\n        }\n        function createFilterContextMenuItems(e) {\n            var filterContainer = document.createElement('div'),\n                filterLabel = document.createElement('div'),\n                filterAutoCompleteButton = document.createElement('button'),\n                filterInput = document.createElement('input'),\n                n = e.cell && e.cell.header ? e.cell.header.title || e.cell.header.name : '',\n                autoCompleteItems,\n                iRect;\n            function checkRegExpErrorState() {\n                filterInput.style.background = self.style.contextFilterInputBackground;\n                filterInput.style.color = self.style.contextFilterInputColor;\n                if (self.invalidFilterRegEx) {\n                    filterInput.style.background = self.style.contextFilterInvalidRegExpBackground;\n                    filterInput.style.color = self.style.contextFilterInvalidRegExpColor;\n                }\n            }\n            function fillAutoComplete() {\n                var count = 0;\n                autoCompleteItems = {};\n                self.data.forEach(function (row) {\n                    var value = row[e.cell.header.name];\n                    if (autoCompleteItems[value] || count > self.attributes.maxAutoCompleteItems) { return; }\n                    count += 1;\n                    autoCompleteItems[value] = {\n                        title: self.formatters[e.cell.header.type || 'string']({ cell: { value: value }}),\n                        click: function (e) {\n                            filterInput.value = value;\n                            e.stopPropagation();\n                            filterInput.dispatchEvent(new Event('keyup'));\n                            self.disposeAutocomplete();\n                            return;\n                        }\n                    };\n                });\n                autoCompleteItems = Object.keys(autoCompleteItems).map(function (key) {\n                    return autoCompleteItems[key];\n                });\n            }\n            function createAutoCompleteContext(ev) {\n                if (ev && [40, 38, 13, 9].indexOf(ev.keyCode) !== -1) { return; }\n                fillAutoComplete();\n                iRect = filterInput.getBoundingClientRect();\n                if (autoCompleteContext) {\n                    autoCompleteContext.dispose();\n                    autoCompleteContext = undefined;\n                }\n                autoCompleteContext = createContextMenu(e, {\n                    left: iRect.left,\n                    top: iRect.top,\n                    right: iRect.right,\n                    bottom: iRect.bottom,\n                    height: iRect.height,\n                    width: iRect.width\n                }, autoCompleteItems, {inputDropdown: true});\n                autoCompleteContext.selectedIndex = 0;\n            }\n            self.createInlineStyle(filterLabel, 'canvas-datagrid-context-menu-label');\n            self.createInlineStyle(filterAutoCompleteButton, 'canvas-datagrid-context-menu-filter-button');\n            self.createInlineStyle(filterInput, 'canvas-datagrid-context-menu-filter-input');\n            checkRegExpErrorState();\n            filterInput.onclick = self.disposeAutocomplete;\n            filterInput.addEventListener('keydown', function (e) {\n                //down\n                if (e.keyCode === 40) {\n                    autoCompleteContext.selectedIndex += 1;\n                }\n                //up\n                if (e.keyCode === 38) {\n                    autoCompleteContext.selectedIndex -= 1;\n                }\n                //enter\n                if (e.keyCode === 13) {\n                    autoCompleteContext.clickIndex(autoCompleteContext.selectedIndex);\n                    self.disposeContextMenu();\n                }\n                //tab\n                if (e.keyCode === 9) {\n                    autoCompleteContext.clickIndex(autoCompleteContext.selectedIndex);\n                    e.preventDefault();\n                }\n                //esc\n                if (e.keyCode === 27) {\n                    self.disposeContextMenu();\n                }\n            });\n            filterInput.addEventListener('keyup', function () {\n                self.setFilter(e.cell.header.name, filterInput.value);\n            });\n            filterInput.addEventListener('keyup', createAutoCompleteContext);\n            ['focus', 'blur', 'keydown', 'keyup', 'change'].forEach(function (en) {\n                filterInput.addEventListener(en, checkRegExpErrorState);\n            });\n            filterInput.value = e.cell.header ? self.columnFilters[e.cell.header.name] || '' : '';\n            filterLabel.innerHTML = self.attributes.filterOptionText.replace(/%s/g, n);\n            filterAutoCompleteButton.onclick = function () {\n                if (autoCompleteContext) {\n                    return self.disposeAutocomplete();\n                }\n                createAutoCompleteContext();\n            };\n            filterAutoCompleteButton.innerHTML = self.style.contextFilterButtonHTML;\n            filterContainer.addEventListener('click', function (e) {\n                return e.stopPropagation();\n            });\n            filterContainer.appendChild(filterLabel);\n            filterContainer.appendChild(filterInput);\n            filterContainer.appendChild(filterAutoCompleteButton);\n            e.items.push({\n                title: filterContainer\n            });\n            if (Object.keys(self.columnFilters).length) {\n                Object.keys(self.columnFilters).forEach(function (cf) {\n                    var h = self.getHeaderByName(cf);\n                    e.items.push({\n                        title: self.attributes.removeFilterOptionText.replace(/%s/g, h.title || h.name),\n                        click: function removeFilterClick(e) {\n                            e.preventDefault();\n                            self.setFilter(cf, '');\n                            self.controlInput.focus();\n                        }\n                    });\n                });\n            }\n        }\n        function addDefaultContextMenuItem(e) {\n            var isNormalCell = !(e.cell.isBackground || e.cell.isColumnHeaderCellCap\n                    || e.cell.isScrollBar || e.cell.isCorner || e.cell.isRowHeader)\n                    && e.cell.header;\n            if (self.attributes.showFilter && isNormalCell) {\n                createFilterContextMenuItems(e);\n            }\n            if (self.attributes.showCopy\n                    && self.selections.reduce(function (p, r) {\n                        return p + r.length;\n                    }, 0) > 0) {\n                e.items.push({\n                    title: self.attributes.copyText,\n                    click: function () {\n                        document.execCommand('copy');\n                        self.disposeContextMenu();\n                        self.controlInput.focus();\n                    }\n                });\n            }\n            if (self.attributes.showPaste && self.clipBoardData) {\n                e.items.push({\n                    title: self.attributes.pasteText,\n                    click: function () {\n                        self.paste(self.clipBoardData, e.cell.columnIndex, e.cell.rowIndex);\n                        self.draw();\n                    }\n                });\n            }\n            if (self.attributes.showColumnSelector) {\n                e.items.push({\n                    title: self.attributes.columnSelectorText,\n                    items: function () {\n                        var d = [];\n                        self.getSchema().forEach(function (column) {\n                            function toggleColumnVisibility(e) {\n                                column.hidden = !column.hidden;\n                                self.dispatchEvent('togglecolumn', {column: column, hidden: column.hidden});\n                                e.preventDefault();\n                                self.stopPropagation(e);\n                                self.disposeContextMenu();\n                                self.resize(true);\n                                self.setStorageData();\n                            }\n                            var el = document.createElement('div');\n                            applyContextItemStyle(el);\n                            el.addEventListener('touchstart', toggleColumnVisibility);\n                            el.addEventListener('click', toggleColumnVisibility);\n                            el.innerHTML = (column.hidden ? self.attributes.columnSelectorHiddenText\n                                    : self.attributes.columnSelectorVisibleText)\n                                    + (column.title || column.name);\n                            d.push({\n                                title: el\n                            });\n                        });\n                        return d;\n                    }\n                });\n                if (e.cell && e.cell.header && e.cell.columnIndex > -1) {\n                    e.items.push({\n                        title: self.attributes.hideColumnText\n                            .replace(/%s/ig, e.cell.header.title || e.cell.header.name),\n                        click: function (ev) {\n                            self.getSchema()[e.cell.columnIndex].hidden = true;\n                            ev.preventDefault();\n                            self.stopPropagation(ev);\n                            self.disposeContextMenu();\n                            self.setStorageData();\n                            setTimeout(function () { self.resize(true); }, 10);\n                        }\n                    });\n                }\n            }\n            if (self.attributes.saveAppearance && self.attributes.showClearSettingsOption\n                    && (Object.keys(self.sizes.rows).length > 0\n                        || Object.keys(self.sizes.columns).length > 0)) {\n                e.items.push({\n                    title: self.attributes.clearSettingsOptionText,\n                    click: function (e) {\n                        e.preventDefault();\n                        self.sizes.rows = {};\n                        self.sizes.columns = {};\n                        self.createRowOrders();\n                        self.createColumnOrders();\n                        self.storedSettings = undefined;\n                        self.dispatchEvent('resizecolumn', {columnWidth: self.style.cellWidth});\n                        self.dispatchEvent('resizerow', {cellHeight: self.style.cellHeight});\n                        self.setStorageData();\n                        self.resize(true);\n                        self.disposeContextMenu();\n                        self.controlInput.focus();\n                    }\n                });\n            }\n            if (self.attributes.allowSorting && self.attributes.showOrderByOption && isNormalCell) {\n                e.items.push({\n                    title: self.attributes.showOrderByOptionTextAsc.replace('%s', e.cell.header.title || e.cell.header.name),\n                    click: function (ev) {\n                        ev.preventDefault();\n                        self.order(e.cell.header.name, 'asc');\n                        self.controlInput.focus();\n                    }\n                });\n                e.items.push({\n                    title: self.attributes.showOrderByOptionTextDesc.replace('%s', e.cell.header.title || e.cell.header.name),\n                    click: function (ev) {\n                        ev.preventDefault();\n                        self.order(e.cell.header.name, 'desc');\n                        self.disposeContextMenu();\n                        self.controlInput.focus();\n                    }\n                });\n            }\n        }\n        self.disposeAutocomplete = function () {\n            if (autoCompleteContext) {\n                autoCompleteContext.dispose();\n                autoCompleteContext = undefined;\n            }\n        };\n        self.disposeContextMenu = function () {\n            document.removeEventListener('click', self.disposeContextMenu);\n            zIndexTop = self.style.contextMenuZIndex;\n            self.disposeAutocomplete();\n            if (self.contextMenu) {\n                self.contextMenu.dispose();\n            }\n            self.contextMenu = undefined;\n        };\n        self.contextmenuEvent = function (e, overridePos) {\n            if (!self.hasFocus && e.target !== self.canvas) {\n                return;\n            }\n            function createDiposeEvent() {\n                requestAnimationFrame(function () {\n                    document.addEventListener('click', self.disposeContextMenu);\n                    document.removeEventListener('mouseup', createDiposeEvent);\n                });\n            }\n            var contextPosition,\n                items = [],\n                pos = overridePos || self.getLayerPos(e),\n                ev = {\n                    NativeEvent: e,\n                    cell: self.getCellAt(pos.x, pos.y),\n                    items: items\n                };\n            if (!ev.cell.isGrid) {\n                addDefaultContextMenuItem(ev);\n            }\n            if (self.dispatchEvent('contextmenu', ev)) {\n                return;\n            }\n            if (!ev.cell.isGrid) {\n                if (self.contextMenu) {\n                    self.disposeContextMenu();\n                }\n                contextPosition = {\n                    left: pos.x + pos.rect.left\n                        + self.style.contextMenuMarginLeft + self.canvasOffsetLeft,\n                    top: pos.y + pos.rect.top\n                        + self.style.contextMenuMarginTop + self.canvasOffsetTop,\n                    right: ev.cell.width + ev.cell.x + pos.rect.left,\n                    bottom: ev.cell.height + ev.cell.y + pos.rect.top,\n                    height: ev.cell.height,\n                    width: ev.cell.width\n                };\n                if (self.mobile) {\n                    contextPosition.left = self.style.mobileContextMenuMargin + 'px';\n                    contextPosition.width = self.width - (self.style.mobileContextMenuMargin * 2) + 'px';\n                }\n                self.contextMenu = createContextMenu(ev, contextPosition, items);\n                document.addEventListener('mouseup', createDiposeEvent);\n                e.preventDefault();\n            }\n        };\n        return;\n    };\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/contextMenu.js\n// module id = 7\n// module chunks = 0","/*jslint browser: true, unparam: true, todo: true*/\n/*globals define: true, MutationObserver: false, requestAnimationFrame: false, performance: false, btoa: false*/\ndefine([], function () {\n    'use strict';\n    return function (self) {\n        self.getClippingRect = function (ele) {\n            var boundingRect = self.position(self.parentNode),\n                eleRect = self.position(ele),\n                s = self.scrollOffset(self.canvas),\n                clipRect = {\n                    x: 0,\n                    y: 0,\n                    h: 0,\n                    w: 0\n                },\n                parentRect = {\n                    x: -Infinity,\n                    y: -Infinity,\n                    h: Infinity,\n                    w: Infinity\n                },\n                columnHeaderCellHeight = self.getColumnHeaderCellHeight(),\n                rowHeaderCellWidth = self.getRowHeaderCellWidth();\n            boundingRect.top -= s.top;\n            boundingRect.left -= s.left;\n            eleRect.top -= s.top;\n            eleRect.left -= s.left;\n            clipRect.h = boundingRect.top + boundingRect.height - ele.offsetTop - self.style.scrollBarWidth;\n            clipRect.w = boundingRect.left + boundingRect.width - ele.offsetLeft - self.style.scrollBarWidth;\n            clipRect.x = boundingRect.left + (eleRect.left * -1) + rowHeaderCellWidth;\n            clipRect.y = boundingRect.top + (eleRect.top * -1) + columnHeaderCellHeight;\n            return {\n                x: clipRect.x > parentRect.x ? clipRect.x : parentRect.x,\n                y: clipRect.y > parentRect.y ? clipRect.y : parentRect.y,\n                h: clipRect.h < parentRect.h ? clipRect.h : parentRect.h,\n                w: clipRect.w < parentRect.w ? clipRect.w : parentRect.w\n            };\n        };\n        self.clipElement = function (ele) {\n            var clipRect = self.getClippingRect(ele);\n            if (clipRect.w < 0) { clipRect.w = 0; }\n            if (clipRect.h < 0) { clipRect.h = 0; }\n            ele.style.clip = 'rect('\n                + clipRect.y + 'px,'\n                + clipRect.w + 'px,'\n                + clipRect.h + 'px,'\n                + clipRect.x + 'px'\n                + ')';\n            // INFO https://developer.mozilla.org/en-US/docs/Web/CSS/clip\n            // clip has been \"deprecated\" for clipPath.  Of course nothing but chrome\n            // supports clip path, so we'll keep using clip until someday clipPath becomes\n            // more widely support.  The code below works correctly, but setting clipPath and clip\n            // at the same time has undesirable results.\n            // ele.style.clipPath = 'polygon('\n            //     + clipRect.x + 'px ' + clipRect.y + 'px,'\n            //     + clipRect.x + 'px ' + clipRect.h + 'px,'\n            //     + clipRect.w + 'px ' + clipRect.h + 'px,'\n            //     + clipRect.w + 'px ' + clipRect.y + 'px'\n            //     + ')';\n        };\n        self.scrollOffset = function (e) {\n            var x = 0, y = 0, scrollingElement = document.scrollingElement || { scrollLeft: 0, scrollTop: 0 };\n            while (e.parentNode && e.nodeName !== 'CANVAS-DATAGRID' && e !== self.intf) {\n                if (e.nodeType !== 'canvas-datagrid-tree'\n                        && e.nodeType !== 'canvas-datagrid-cell') {\n                    x -= e.scrollLeft;\n                    y -= e.scrollTop;\n                }\n                e = e.parentNode;\n            }\n            return {\n                left: x - scrollingElement.scrollLeft,\n                top: y - scrollingElement.scrollTop\n            };\n        };\n        self.resizeEditInput = function () {\n            if (self.input && self.input.editCell) {\n                var pos = self.canvas.getBoundingClientRect(),\n                    s = self.scrollOffset(self.intf),\n                    bm = self.style.gridBorderCollapse === 'collapse' ? 1 : 2,\n                    borderWidth = (self.style.cellBorderWidth * bm),\n                    cell = self.getVisibleCellByIndex(self.input.editCell.columnIndex, self.input.editCell.rowIndex)\n                        || {x: -100, y: -100, height: 0, width: 0};\n                if (self.mobile) {\n                    self.input.style.left = '0';\n                    self.input.style.top = (self.height - self.style.mobileEditInputHeight) - borderWidth - 1 + 'px';\n                    self.input.style.height = self.style.mobileEditInputHeight + 'px';\n                    self.input.style.width = self.width - borderWidth - 1 + 'px';\n                    return;\n                }\n                self.input.style.left = pos.left + cell.x + self.canvasOffsetLeft - s.left + 'px';\n                self.input.style.top = pos.top + cell.y - self.style.cellBorderWidth + self.canvasOffsetTop - s.top + 'px';\n                self.input.style.height = cell.height - borderWidth + 'px';\n                self.input.style.width = cell.width - self.style.cellPaddingLeft + 'px';\n                self.clipElement(self.input);\n            }\n        };\n        self.position = function (e, ignoreScrollOffset) {\n            var x = 0, y = 0, s = e, h, w;\n            while (e.offsetParent && e.nodeName !== 'CANVAS-DATAGRID') {\n                x += e.offsetLeft;\n                y += e.offsetTop;\n                h = e.offsetHeight;\n                w = e.offsetWidth;\n                e = e.offsetParent;\n            }\n            if (ignoreScrollOffset) {\n                return {left: x, top: y, height: h, width: w};\n            }\n            e = s;\n            s = self.scrollOffset(e);\n            return { left: x + s.left, top: y + s.top, height: h, width: w };\n        };\n        self.getLayerPos = function (e) {\n            var rect = self.canvas.getBoundingClientRect(),\n                pos = {\n                    x: e.clientX - rect.left,\n                    y: e.clientY - rect.top\n                };\n            if (self.isChildGrid) {\n                pos.x -= self.canvasOffsetLeft;\n                pos.y -= self.canvasOffsetTop;\n            }\n            return {\n                x: pos.x,\n                y: pos.y,\n                rect: rect\n            };\n        };\n        /**\n         * Ends editing, optionally aborting the edit.\n         * @memberof canvasDatagrid\n         * @name endEdit\n         * @method\n         * @param {boolean} abort When true, abort the edit.\n         */\n        self.endEdit = function (abort) {\n            var cell = self.input.editCell,\n                y = cell.rowIndex;\n            function abortEdit() {\n                abort = true;\n            }\n            if (self.dispatchEvent('beforeendedit', {\n                    cell: cell,\n                    newValue: self.input.value,\n                    oldValue: cell.value,\n                    abort: abortEdit,\n                    input: self.input\n                })) { return false; }\n            if (self.input.value !== cell.value && !abort) {\n                self.changes[y] = self.changes[y] || {};\n                self.changes[y][cell.header.name] = self.input.value;\n                if (!cell.data) {\n                    self.data[cell.rowIndex] = {};\n                    cell.data = self.data[cell.rowIndex];\n                }\n                cell.data[cell.header.name] = self.input.value;\n                if (y === self.data.length) {\n                    if (self.dispatchEvent('newrow', {\n                            value: self.input.value,\n                            defaultValue: cell.value,\n                            aborted: abort,\n                            cell: cell,\n                            input: self.input\n                        })) { return false; }\n                    self.addRow(cell.data);\n                    self.createNewRowData();\n                }\n                self.draw(true);\n            }\n            if (self.input.parentNode) {\n                self.input.parentNode.removeChild(self.input);\n            }\n            self.intf.focus();\n            self.dispatchEvent('endedit', {\n                cell: cell,\n                value: self.input.value,\n                aborted: abort,\n                input: self.input\n            });\n            self.input = undefined;\n            return true;\n        };\n        /**\n         * Begins editing at cell x, row y.\n         * @memberof canvasDatagrid\n         * @name beginEditAt\n         * @method\n         * @param {number} x The column index of the cell to edit.\n         * @param {number} y The row index of the cell to edit.\n         */\n        self.beginEditAt = function (x, y, NativeEvent) {\n            if (!self.attributes.editable) { return; }\n            if (self.input) {\n                self.endEdit();\n            }\n            var cell = self.getVisibleCellByIndex(x, y),\n                s = self.getSchema(),\n                adjacentCells,\n                enumItems,\n                enu,\n                option,\n                valueInEnum;\n            if (!(cell && cell.header)) { return; }\n            //HACK for IE10, does not like literal enum\n            enu = cell.header['enum'];\n            if (self.dispatchEvent('beforebeginedit', {cell: cell, NativeEvent: NativeEvent})) { return false; }\n            self.scrollIntoView(x, y);\n            self.setActiveCell(x, y);\n            adjacentCells = self.getAdjacentCells();\n            if (enu) {\n                self.input = document.createElement('select');\n            } else {\n                self.input = document.createElement(self.attributes.multiLine\n                    ? 'textarea' : 'input');\n            }\n            cell = self.getVisibleCellByIndex(x, y);\n            //HACK on mobile devices sometimes edit can begin without the cell being in view, I don't know how.\n            if (!cell) { return; }\n            if (enu) {\n                // add enums\n                if (typeof enu === 'function') {\n                    enumItems = enu.apply(self.intf, [{cell: cell}]);\n                } else if (Array.isArray(enu)) {\n                    enumItems = enu;\n                }\n                enumItems.forEach(function (e) {\n                    var i = document.createElement('option'),\n                        val,\n                        title;\n                    if (Array.isArray(e)) {\n                        val = e[0];\n                        title = e[1];\n                    } else {\n                        val = e;\n                        title = e;\n                    }\n                    if (val === cell.value) { valueInEnum = true; }\n                    i.value = val;\n                    i.innerHTML = title;\n                    self.input.appendChild(i);\n                });\n                if (!valueInEnum) {\n                    option = document.createElement('option');\n                    option.value = cell.value;\n                    option.innerHTML = cell.value;\n                    self.input.appendChild(option);\n                }\n                self.input.addEventListener('change', function () {\n                    self.endEdit();\n                    self.draw(true);\n                });\n            }\n            // if the user has not prevented the default action, append to the body\n            if (!self.dispatchEvent('appendeditinput', {cell: cell, input:self.input})) { \n                document.body.appendChild(self.input);\n            }\n            self.createInlineStyle(self.input, self.mobile ? 'canvas-datagrid-edit-mobile-input' : 'canvas-datagrid-edit-input');\n            self.input.style.position = 'absolute';\n            self.input.editCell = cell;\n            self.resizeEditInput();\n            self.input.style.zIndex = self.style.editCellZIndex;\n            self.input.style.fontSize = (parseInt(self.style.editCellFontSize, 10) * self.scale) + 'px';\n            self.input.value = [null, undefined].indexOf(cell.value) !== -1 ? '' : cell.value;\n            self.input.focus();\n            self.input.addEventListener('click', self.stopPropagation);\n            self.input.addEventListener('dblclick', self.stopPropagation);\n            self.input.addEventListener('mouseup', self.stopPropagation);\n            self.input.addEventListener('mousedown', self.stopPropagation);\n            self.input.addEventListener('keydown', function (e) {\n                var nx = cell.columnIndex,\n                    ny = cell.rowIndex;\n                // esc\n                if (e.keyCode === 27) {\n                    self.endEdit(true);\n                    self.draw(true);\n                // enter\n                } else if (e.keyCode === 13\n                        && (!self.attributes.multiLine\n                            || (self.attributes.multiLine && e.shiftKey))) {\n                    self.endEdit();\n                    self.draw(true);\n                } else if (e.keyCode === 9) {\n                    e.preventDefault();\n                    if (!self.endEdit()) {\n                        return;\n                    }\n                    if (e.shiftKey) {\n                        nx = adjacentCells.left;\n                    } else {\n                        nx = adjacentCells.right;\n                    }\n                    if (adjacentCells.left === x && e.shiftKey) {\n                        nx = adjacentCells.last;\n                        ny -= 1;\n                    }\n                    if (adjacentCells.right === x && !e.shiftKey) {\n                        nx = adjacentCells.first;\n                        ny += 1;\n                    }\n                    if (ny < 0) {\n                        ny = self.data.length - 1;\n                    }\n                    if (ny > self.data.length - 1) {\n                        ny = 0;\n                    }\n                    self.scrollIntoView(nx, ny);\n                    self.beginEditAt(nx, ny, e);\n                }\n            });\n            self.dispatchEvent('beginedit', {cell: cell, input: self.input});\n        };\n        self.createInlineStyle = function (el, className) {\n            var css = {\n                'canvas-datagrid-context-menu-filter-input': {\n                    height: '19px',\n                    verticalAlign: 'bottom',\n                    marginLeft: '2px',\n                    padding: '0',\n                    background: self.style.contextFilterInputBackground,\n                    color: self.style.contextFilterInputColor,\n                    border: self.style.contextFilterInputBorder,\n                    borderRadius: self.style.contextFilterInputBorderRadius,\n                    lineHeight: 'normal',\n                    fontWeight: 'normal',\n                    fontFamily: self.style.contextFilterInputFontFamily,\n                    fontSize: self.style.contextFilterInputFontSize\n                },\n                'canvas-datagrid-context-menu-filter-button': {\n                    height: '19px',\n                    verticalAlign: 'bottom',\n                    marginLeft: '2px',\n                    padding: '0',\n                    background: self.style.contextMenuBackground,\n                    color: self.style.contextMenuColor,\n                    border: self.style.contextFilterButtonBorder,\n                    borderRadius: self.style.contextFilterButtonBorderRadius,\n                    lineHeight: 'normal',\n                    fontWeight: 'normal',\n                    fontFamily: self.style.contextMenuFilterButtonFontFamily,\n                    fontSize: self.style.contextMenuFilterButtonFontSize\n                },\n                'canvas-datagrid-context-child-arrow': {\n                    cssFloat: 'right',\n                    color: self.style.childContextMenuArrowColor,\n                    fontSize: self.style.contextMenuChildArrowFontSize,\n                    fontFamily: self.style.contextMenuFontFamily,\n                    verticalAlign: 'middle'\n                },\n                'canvas-datagrid-autocomplete': {\n                    fontFamily: self.style.contextMenuFontFamily,\n                    fontSize: self.style.contextMenuFontSize,\n                    background: self.style.contextMenuBackground,\n                    color: self.style.contextMenuColor,\n                    border: self.style.contextMenuBorder,\n                    padding: self.style.contextMenuPadding,\n                    borderRadius: self.style.contextMenuBorderRadius,\n                    opacity: self.style.contextMenuOpacity,\n                    position: 'absolute',\n                    zIndex: 9999,\n                    overflow: 'hidden'\n                },\n                'canvas-datagrid-autocomplete-item': {\n                    background: self.style.contextMenuBackground,\n                    color: self.style.contextMenuColor\n                },\n                'canvas-datagrid-autocomplete-item:hover': {\n                    background: self.style.contextMenuHoverBackground,\n                    color: self.style.contextMenuHoverColor\n                },\n                'canvas-datagrid-canvas': {\n                    position: 'absolute',\n                    zIndex: '-1'\n                },\n                'canvas-datagrid': {\n                    display: 'block'\n                },\n                'canvas-datagrid-control-input': {\n                    position: 'fixed',\n                    top: '-5px',\n                    left: '-5px',\n                    border: 'none',\n                    opacity: '0',\n                    cursor: 'pointer',\n                    width: '1px',\n                    height: '1px',\n                    lineHeight: 'normal',\n                    fontWeight: 'normal',\n                    fontFamily: self.style.contextMenuFontFamily,\n                    fontSize: self.style.contextMenuFontSize\n                },\n                'canvas-datagrid-edit-mobile-input': {\n                    boxSizing: 'content-box',\n                    outline: 'none',\n                    margin: '0',\n                    padding: '0 0 0 0',\n                    lineHeight: 'normal',\n                    fontWeight: 'normal',\n                    fontFamily: self.style.mobileEditFontFamily,\n                    fontSize: self.style.mobileEditFontSize,\n                    border: self.style.editCellBorder,\n                    color: self.style.editCellColor,\n                    background: self.style.editCellBackgroundColor,\n                    appearance: 'none',\n                    webkitAppearance: 'none',\n                    mozAppearance: 'none',\n                    borderRadius: '0'\n                },\n                'canvas-datagrid-edit-input': {\n                    boxSizing: 'content-box',\n                    outline: 'none',\n                    margin: '0',\n                    padding: '0 0 0 ' + self.style.editCellPaddingLeft + 'px',\n                    lineHeight: 'normal',\n                    fontWeight: 'normal',\n                    fontFamily: self.style.editCellFontFamily,\n                    fontSize: self.style.editCellFontSize,\n                    boxShadow: self.style.editCellBoxShadow,\n                    border: self.style.editCellBorder,\n                    color: self.style.editCellColor,\n                    background: self.style.editCellBackgroundColor,\n                    appearance: 'none',\n                    webkitAppearance: 'none',\n                    mozAppearance: 'none',\n                    borderRadius: '0'\n                },\n                'canvas-datagrid-context-menu-item-mobile': {\n                    lineHeight: 'normal',\n                    fontWeight: 'normal',\n                    fontFamily: self.style.contextMenuFontFamily,\n                    fontSize: self.style.contextMenuFontSize,\n                    color: 'inherit',\n                    background: 'inherit',\n                    margin: self.style.contextMenuItemMargin,\n                    borderRadius: self.style.contextMenuItemBorderRadius,\n                    verticalAlign: 'middle'\n                },\n                'canvas-datagrid-context-menu-item': {\n                    lineHeight: 'normal',\n                    fontWeight: 'normal',\n                    fontFamily: self.style.contextMenuFontFamily,\n                    fontSize: self.style.contextMenuFontSize,\n                    color: 'inherit',\n                    background: 'inherit',\n                    margin: self.style.contextMenuItemMargin,\n                    borderRadius: self.style.contextMenuItemBorderRadius,\n                    verticalAlign: 'middle'\n                },\n                'canvas-datagrid-context-menu-item:hover': {\n                    background: self.style.contextMenuHoverBackground,\n                    color: self.style.contextMenuHoverColor\n                },\n                'canvas-datagrid-context-menu-label': {\n                    margin: self.style.contextMenuLabelMargin,\n                    display: self.style.contextMenuLabelDisplay,\n                    minWidth: self.style.contextMenuLabelMinWidth,\n                    maxWidth: self.style.contextMenuLabelMaxWidth\n                },\n                'canvas-datagrid-context-menu-mobile': {\n                    lineHeight: 'normal',\n                    fontWeight: 'normal',\n                    fontFamily: self.style.contextMenuFontFamily,\n                    fontSize: self.style.contextMenuFontSize,\n                    background: self.style.contextMenuBackground,\n                    color: self.style.contextMenuColor,\n                    border: self.style.contextMenuBorder,\n                    padding: self.style.contextMenuPadding,\n                    borderRadius: self.style.contextMenuBorderRadius,\n                    opacity: self.style.contextMenuOpacity,\n                    overflow: 'hidden',\n                    whiteSpace: 'nowrap'\n                },\n                'canvas-datagrid-context-menu': {\n                    lineHeight: 'normal',\n                    fontWeight: 'normal',\n                    fontFamily: self.style.contextMenuFontFamily,\n                    fontSize: self.style.contextMenuFontSize,\n                    background: self.style.contextMenuBackground,\n                    color: self.style.contextMenuColor,\n                    border: self.style.contextMenuBorder,\n                    padding: self.style.contextMenuPadding,\n                    borderRadius: self.style.contextMenuBorderRadius,\n                    opacity: self.style.contextMenuOpacity,\n                    overflow: 'hidden',\n                    whiteSpace: 'nowrap',\n                    cursor: self.style.contextMenuCursor\n                },\n                'canvas-datagrid-invalid-search-regExp': {\n                    background: self.style.contextMenuFilterInvalidExpresion\n                }\n            };\n            if (css[className]) {\n                Object.keys(css[className]).map(function (prop) {\n                    el.style[prop] = css[className][prop];\n                });\n            }\n            return;\n        };\n        self.appendTo = function (e) {\n            self.parentNode = e;\n            self.setDom();\n        };\n        self.setDom = function () {\n            if (self.isChildGrid) {\n                self.parentGrid = self.parentNode.parentGrid;\n                self.ctx = self.parentGrid.context;\n                self.canvas = self.parentGrid.canvas;\n                self.controlInput = self.parentGrid.controlInput;\n                self.eventParent = self.canvas;\n            } else {\n                self.controlInput = self.controlInput || document.createElement('input');\n                self.controlInput.onblur = self.intf.blur;\n                self.createInlineStyle(self.controlInput, 'canvas-datagrid-control-input');\n                self.isChildGrid = false;\n                self.parentDOMNode = self.parentNode;\n                self.parentIsCanvas = /^canvas$/i.test(self.parentDOMNode.tagName);\n                if (self.parentIsCanvas) {\n                    self.canvas = self.parentDOMNode;\n                } else {\n                    self.canvas = document.createElement('canvas');\n                    self.parentDOMNode.appendChild(self.canvas);\n                }\n                document.body.appendChild(self.controlInput);\n                self.createInlineStyle(self.canvas, 'canvas-datagrid');\n                self.ctx = self.canvas.getContext('2d');\n                self.ctx.textBaseline = 'alphabetic';\n                self.eventParent = self.canvas;\n            }\n            self.parentNodeStyle = self.canvas.style;\n            self.controlInput.setAttribute('readonly', true);\n            self.controlInput.addEventListener('blur', function (e) {\n                if (e.target !== self.canvas) {\n                    self.hasFocus = false;\n                }\n            });\n            self.eventParent.addEventListener('scroll', self.resize, false);\n            self.eventParent.addEventListener('touchstart', self.touchstart, false);\n            self.eventParent.addEventListener('mouseup', self.mouseup, false);\n            self.eventParent.addEventListener('mousedown', self.mousedown, false);\n            self.eventParent.addEventListener('dblclick', self.dblclick, false);\n            self.eventParent.addEventListener('click', self.click, false);\n            self.eventParent.addEventListener('mousemove', self.mousemove);\n            self[self.isChildGrid ? 'parentGrid' : 'eventParent'].addEventListener('wheel', self.scrollWheel, false);\n            self.canvas.addEventListener('contextmenu', self.contextmenuEvent, false);\n            self.controlInput.addEventListener('copy', self.copy);\n            self.controlInput.addEventListener('cut', self.cut);\n            self.controlInput.addEventListener('paste', self.paste);\n            self.controlInput.addEventListener('keypress', self.keypress, false);\n            self.controlInput.addEventListener('keyup', self.keyup, false);\n            self.controlInput.addEventListener('keydown', self.keydown, false);\n            window.addEventListener('resize', self.resize);\n        };\n    };\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/dom.js\n// module id = 8\n// module chunks = 0","/*jslint browser: true, unparam: true, todo: true*/\n/*globals define: true, MutationObserver: false, requestAnimationFrame: false, performance: false, btoa: false*/\ndefine([], function () {\n    'use strict';\n    return function (self) {\n        /**\n         * Converts a integer into a letter A - ZZZZZ...\n         * @memberof canvasDatagrid\n         * @name integerToAlpha\n         * @method\n         * @param {column} n The number to convert.\n         */\n        self.integerToAlpha = function (n) {\n            var ordA = 'a'.charCodeAt(0),\n                ordZ = 'z'.charCodeAt(0),\n                len = ordZ - ordA + 1,\n                s = '';\n            while (n >= 0) {\n                s = String.fromCharCode(n % len + ordA) + s;\n                n = Math.floor(n / len) - 1;\n            }\n            return s;\n        };\n        /**\n         * Inserts a new column before the specified index into the schema.\n         * @tutorial schema\n         * @memberof canvasDatagrid\n         * @name insertColumn\n         * @method\n         * @param {column} c The column to insert into the schema.\n         * @param {number} index The index of the column to insert before.\n         */\n        self.insertColumn = function (c, index) {\n            var s = self.getSchema();\n            if (s.length < index) {\n                throw new Error('Index is beyond the length of the schema.');\n            }\n            self.validateColumn(c, s);\n            s.splice(index, 0, c);\n            self.data.forEach(function (row) {\n                self.applyDefaultValue(row, c);\n            });\n            self.intf.schema = s;\n        };\n        /**\n         * Deletes a column from the schema at the specified index.\n         * @memberof canvasDatagrid\n         * @name deleteColumn\n         * @tutorial schema\n         * @method\n         * @param {number} index The index of the column to delete.\n         */\n        self.deleteColumn = function (index) {\n            var s = self.getSchema();\n            // remove data matching this column name from data\n            self.data.forEach(function (row) {\n                delete row[s[index].name];\n            });\n            s.splice(index, 1);\n            self.intf.schema = s;\n        };\n        /**\n         * Adds a new column into the schema.\n         * @tutorial schema\n         * @memberof canvasDatagrid\n         * @name addColumn\n         * @method\n         * @param {column} c The column to add to the schema.\n         */\n        self.addColumn = function (c) {\n            var s = self.getSchema();\n            self.validateColumn(c, s);\n            s.push(c);\n            self.data.forEach(function (row) {\n                self.applyDefaultValue(row, c);\n            });\n            self.intf.schema = s;\n        };\n        /**\n         * Deletes a row from the dataset at the specified index.\n         * @memberof canvasDatagrid\n         * @name deleteRow\n         * @method\n         * @param {number} index The index of the row to delete.\n         */\n        self.deleteRow = function (index) {\n            self.originalData.splice(index, 1);\n            self.setFilter();\n            self.resize(true);\n        };\n        /**\n         * Inserts a new row into the dataset before the specified index.\n         * @memberof canvasDatagrid\n         * @name insertRow\n         * @method\n         * @param {object} d data.\n         * @param {number} index The index of the row to insert before.\n         */\n        self.insertRow = function (d, index) {\n            if (self.originalData.length < index) {\n                throw new Error('Index is beyond the length of the dataset.');\n            }\n            self.originalData.splice(index, 0, d);\n            self.getSchema().forEach(function (c) {\n                if (d[c.name] === undefined) {\n                    self.applyDefaultValue(self.originalData[index], c);\n                }\n            });\n            self.setFilter();\n            self.resize(true);\n        };\n        /**\n         * Adds a new row into the dataset.\n         * @memberof canvasDatagrid\n         * @name addRow\n         * @method\n         * @param {object} d data.\n         */\n        self.addRow = function (d) {\n            self.originalData.push(d);\n            self.getSchema().forEach(function (c) {\n                if (d[c.name] === undefined) {\n                    self.applyDefaultValue(self.originalData[self.originalData.length - 1], c);\n                }\n            });\n            self.setFilter();\n            self.resize(true);\n        };\n        /**\n         * Sets the height of a given row by index number.\n         * @memberof canvasDatagrid\n         * @name setRowHeight\n         * @method\n         * @param {number} rowIndex The index of the row to set.\n         * @param {number} height Height to set the row to.\n         */\n        self.setRowHeight = function (rowIndex, height) {\n            self.sizes.rows[rowIndex] = height;\n            self.draw(true);\n        };\n        /**\n         * Sets the width of a given column by index number.\n         * @memberof canvasDatagrid\n         * @name setColumnWidth\n         * @method\n         * @param {number} colIndex The index of the column to set.\n         * @param {number} width Width to set the column to.\n         */\n        self.setColumnWidth = function (colIndex, width) {\n            self.sizes.columns[colIndex] = width;\n            self.draw(true);\n        };\n        /**\n         * Removes any changes to the width of the columns due to user or api interaction, setting them back to the schema or style default.\n         * @memberof canvasDatagrid\n         * @name resetColumnWidths\n         * @tutorial schema\n         * @method\n         */\n        self.resetColumnWidths = function () {\n            self.sizes.columns = {};\n            self.draw(true);\n        };\n        /**\n         * Removes any changes to the height of the rows due to user or api interaction, setting them back to the schema or style default.\n         * @memberof canvasDatagrid\n         * @name resetRowHeights\n         * @tutorial schema\n         * @method\n         */\n        self.resetRowHeights = function () {\n            self.sizes.rows = {};\n            self.draw(true);\n        };\n        /**\n         * Sets the value of the filter.\n         * @memberof canvasDatagrid\n         * @name setFilter\n         * @method\n         * @param {string} column Name of the column to filter.\n         * @param {string} value The value to filter for.\n         */\n        self.setFilter = function (column, value) {\n            if (column === undefined && value === undefined) {\n                self.columnFilters = {};\n            } else if (column && (value === '' || value === undefined)) {\n                delete self.columnFilters[column];\n            } else {\n                self.columnFilters[column] = value;\n            }\n            self.applyDataTransforms();\n        };\n        /**\n         * Returns the number of pixels to scroll down to line up with row rowIndex.\n         * @memberof canvasDatagrid\n         * @name findRowScrollTop\n         * @method\n         * @param {number} rowIndex The row index of the row to scroll find.\n         */\n        self.findRowScrollTop = function (rowIndex) {\n            if (self.scrollCache.y[rowIndex] === undefined) { throw new RangeError('Row index out of range.'); }\n            return self.scrollCache.y[rowIndex];\n        };\n        /**\n         * Returns the number of pixels to scroll to the left to line up with column columnIndex.\n         * @memberof canvasDatagrid\n         * @name findColumnScrollLeft\n         * @method\n         * @param {number} columnIndex The column index of the column to find.\n         */\n        self.findColumnScrollLeft = function (columnIndex) {\n            var i = Math.max(columnIndex - 1, 0);\n            if (self.scrollCache.x[i] === undefined) { throw new Error('Column index out of range.'); }\n            return self.scrollCache.x[i] - self.getColummnWidth(self.orders.columns[columnIndex]);\n        };\n        /**\n         * Scrolls to the cell at columnIndex x, and rowIndex y.  If you define both rowIndex and columnIndex additional calculations can be made to center the cell using the target cell's height and width.  Defining only one rowIndex or only columnIndex will result in simpler calculations.\n         * @memberof canvasDatagrid\n         * @name gotoCell\n         * @method\n         * @param {number} x The column index of the cell to scroll to.\n         * @param {number} y The row index of the cell to scroll to.\n         * @param {number} [offsetX=0] Percentage offset the cell should be from the left edge (not including headers).  The default is 0, meaning the cell will appear at the left edge. Valid values are 0 through 1. 1 = Left, 0 = Right, 0.5 = Center.\n         * @param {number} [offsetY=0] Percentage offset the cell should be from the top edge (not including headers).  The default is 0, meaning the cell will appear at the top edge. Valid values are 0 through 1. 1 = Bottom, 0 = Top, 0.5 = Center.\n         */\n        self.gotoCell = function (x, y, offsetX, offsetY) {\n            var targetX = x === undefined ? undefined : self.findColumnScrollLeft(x),\n                targetY = y === undefined ? undefined : self.findRowScrollTop(y),\n                cell,\n                sbw = self.scrollBox.width - (self.scrollBox.verticalBarVisible ? self.style.scrollBarWidth : 0),\n                sbh = self.scrollBox.height - (self.scrollBox.horizontalBarVisible ? self.style.scrollBarWidth : 0);\n            offsetX = offsetX === undefined ? 0 : offsetX;\n            offsetY = offsetY === undefined ? 0 : offsetY;\n            targetX -= sbw * offsetX;\n            targetY -= sbh * offsetY;\n            if (x !== undefined && y !== undefined) {\n                self.scrollBox.scrollTo(targetX, targetY);\n                requestAnimationFrame(function () {\n                    cell = self.getVisibleCellByIndex(x, y);\n                    // HACK: just don't offset if the target cell cannot be seen\n                    // TODO: offset does not work on very small grids, not sure why\n                    if (!cell) { return; }\n                    targetX += cell.width * offsetX;\n                    targetY += cell.height * offsetY;\n                    self.scrollBox.scrollTo(targetX, targetY);\n                });\n            } else if (x !== undefined) {\n                self.scrollBox.scrollLeft = targetX;\n            } else if (y !== undefined) {\n                self.scrollBox.scrollTop = targetY;\n            }\n        };\n        /**\n         * Scrolls the row y.\n         * @memberof canvasDatagrid\n         * @name gotoRow\n         * @method\n         * @param {number} y The row index of the cell to scroll to.\n         */\n        self.gotoRow = function (y) {\n            self.gotoCell(0, y);\n        };\n        /**\n         * Scrolls the cell at cell x, row y into view if it is not already.\n         * @memberof canvasDatagrid\n         * @name scrollIntoView\n         * @method\n         * @param {number} x The column index of the cell to scroll into view.\n         * @param {number} y The row index of the cell to scroll into view.\n         * @param {number} [offsetX=0] Percentage offset the cell should be from the left edge (not including headers).  The default is 0, meaning the cell will appear at the left edge. Valid values are 0 through 1. 1 = Left, 0 = Right, 0.5 = Center.\n         * @param {number} [offsetY=0] Percentage offset the cell should be from the top edge (not including headers).  The default is 0, meaning the cell will appear at the top edge. Valid values are 0 through 1. 1 = Bottom, 0 = Top, 0.5 = Center.\n         */\n        self.scrollIntoView = function (x, y, offsetX, offsetY) {\n            if (self.visibleCells.filter(function (cell) {\n                    return (cell.rowIndex === y || y === undefined)\n                        && (cell.columnIndex === x || x === undefined)\n                        && cell.x > 0\n                        && cell.y > 0\n                        && cell.x + cell.width < self.width\n                        && cell.y + cell.height < self.height;\n                }).length === 0) {\n                self.gotoCell(x, y, offsetX, offsetY);\n            }\n        };\n        /**\n         * Sets the active cell. Requires redrawing.\n         * @memberof canvasDatagrid\n         * @name setActiveCell\n         * @method\n         * @param {number} x The column index of the cell to set active.\n         * @param {number} y The row index of the cell to set active.\n         */\n        self.setActiveCell = function (x, y) {\n            if (x < 0) { x = 0; }\n            if (y < 0) { y = 0; }\n            self.activeCell = {\n                rowIndex: y,\n                columnIndex: x\n            };\n        };\n        /**\n         * Removes the selection.\n         * @memberof canvasDatagrid\n         * @name selectNone\n         * @param {boolean} dontDraw Suppress the draw method after the selection change.\n         * @method\n         */\n        self.selectNone = function (dontDraw) {\n            self.selections = [];\n            self.dispatchEvent('selectionchanged', {\n                selectedData: self.getSelectedData(),\n                selections: self.selections,\n                selectionBounds: self.selectionBounds\n            });\n            if (dontDraw) { return; }\n            self.draw();\n        };\n        /**\n         * Selects every visible cell.\n         * @memberof canvasDatagrid\n         * @name selectAll\n         * @param {boolean} dontDraw Suppress the draw method after the selection change.\n         * @method\n         */\n        self.selectAll = function (dontDraw) {\n            self.selectArea({\n                top: 0,\n                left: -1,\n                right: self.getSchema().length - 1,\n                bottom: self.data.length - 1\n            });\n            if (dontDraw) { return; }\n            self.draw();\n        };\n        /**\n         * Returns true if the selected columnIndex is selected on every row.\n         * @memberof canvasDatagrid\n         * @name isColumnSelected\n         * @method\n         * @param {number} columnIndex The column index to check.\n         */\n        self.isColumnSelected = function (columnIndex) {\n            var colIsSelected = true;\n            self.data.forEach(function (row, rowIndex) {\n                if (!self.selections[rowIndex] || self.selections[rowIndex].indexOf(self.orders.columns[columnIndex]) === -1) {\n                    colIsSelected = false;\n                }\n            });\n            return colIsSelected;\n        };\n        /**\n         * Runs the defined method on each selected cell.\n         * @memberof canvasDatagrid\n         * @name forEachSelectedCell\n         * @method\n         * @param {number} fn The function to execute.  The signature of the function is: (data, rowIndex, columnName).\n         * @param {number} expandToRow When true the data in the array is expanded to the entire row.\n         */\n        self.forEachSelectedCell = function (fn, expandToRow) {\n            var d = [], s = expandToRow ? self.getSchema() : self.getVisibleSchema(), l = self.data.length;\n            self.selections.forEach(function (row, index) {\n                if (index === l) { return; }\n                if (row.length === 0) {\n                    d[index] = null;\n                    return;\n                }\n                d[index] = {};\n                row.forEach(function (col) {\n                    if (col === -1 || !s[col]) { return; }\n                    fn(self.data, index, s[col].name);\n                });\n            });\n        };\n        /**\n         * Selects a column.\n         * @memberof canvasDatagrid\n         * @name selectColumn\n         * @method\n         * @param {number} columnIndex The column index to select.\n         * @param {boolean} toggleSelectMode When true, behaves as if you were holding control/command when you clicked the column.\n         * @param {boolean} shift When true, behaves as if you were holding shift when you clicked the column.\n         * @param {boolean} supressSelectionchangedEvent When true, prevents the selectionchanged event from firing.\n         */\n        self.selectColumn = function (columnIndex, ctrl, shift, supressEvent) {\n            var s, e, x;\n            function addCol(i) {\n                self.data.forEach(function (row, rowIndex) {\n                    self.selections[rowIndex] = self.selections[rowIndex] || [];\n                    if (self.selections[rowIndex].indexOf(i) === -1) {\n                        self.selections[rowIndex].push(i);\n                    }\n                });\n            }\n            function removeCol(i) {\n                self.data.forEach(function (row, rowIndex) {\n                    self.selections[rowIndex] = self.selections[rowIndex] || [];\n                    if (self.selections[rowIndex].indexOf(i) !== -1) {\n                        self.selections[rowIndex].splice(self.selections[rowIndex].indexOf(i), 1);\n                    }\n                });\n            }\n            if (shift) {\n                if (!self.activeCell) { return; }\n                s = Math.min(self.activeCell.columnIndex, columnIndex);\n                e = Math.max(self.activeCell.columnIndex, columnIndex);\n                for (x = s; e > x; x += 1) {\n                    addCol(x);\n                }\n            }\n            if (!ctrl && !shift) {\n                self.selections = [];\n                self.activeCell.columnIndex = columnIndex;\n                self.activeCell.rowIndex = self.scrollIndexTop;\n            }\n            if (ctrl && self.isColumnSelected(columnIndex)) {\n                removeCol(columnIndex);\n            } else {\n                addCol(columnIndex);\n            }\n            if (supressEvent) { return; }\n            self.dispatchEvent('selectionchanged', {\n                selectedData: self.getSelectedData(),\n                selections: self.selections,\n                selectionBounds: self.getSelectionBounds()\n            });\n        };\n        /**\n         * Selects a row.\n         * @memberof canvasDatagrid\n         * @name selectRow\n         * @method\n         * @param {number} rowIndex The row index to select.\n         * @param {boolean} ctrl When true, behaves as if you were holding control/command when you clicked the row.\n         * @param {boolean} shift When true, behaves as if you were holding shift when you clicked the row.\n         * @param {boolean} supressSelectionchangedEvent When true, prevents the selectionchanged event from firing.\n         */\n        self.selectRow = function (rowIndex, ctrl, shift, supressEvent) {\n            var x, st, en, s = self.getVisibleSchema();\n            function de() {\n                if (supressEvent) { return; }\n                self.dispatchEvent('selectionchanged', {\n                    selectedData: self.getSelectedData(),\n                    selections: self.selections,\n                    selectionBounds: self.selectionBounds\n                });\n            }\n            function addRow(ri) {\n                self.selections[ri] = [];\n                self.selections[ri].push(-1);\n                s.forEach(function (col, index) {\n                    self.selections[ri].push(self.orders.columns.indexOf(col.index));\n                });\n            }\n            if (self.dragAddToSelection === false || self.dragObject === undefined) {\n                if (self.selections[rowIndex] && self.selections[rowIndex].length - 1 === s.length) {\n                    if (ctrl) {\n                        self.selections[rowIndex] = [];\n                        de();\n                        return;\n                    }\n                }\n            }\n            if (self.dragAddToSelection === true || self.dragObject === undefined) {\n                if (shift && self.dragObject === undefined) {\n                    if (!self.activeCell) { return; }\n                    st = Math.min(self.activeCell.rowIndex, rowIndex);\n                    en = Math.max(self.activeCell.rowIndex, rowIndex);\n                    for (x = st; en >= x; x += 1) {\n                        addRow(x);\n                    }\n                } else {\n                    addRow(rowIndex);\n                }\n            }\n            de();\n        };\n        /**\n         * Collapse a tree grid by row index.\n         * @memberof canvasDatagrid\n         * @name collapseTree\n         * @method\n         * @param {number} index The index of the row to collapse.\n         */\n        self.collapseTree = function (rowIndex) {\n            self.dispatchEvent('collapsetree', {\n                childGrid: self.childGrids[rowIndex],\n                data: self.data[rowIndex],\n                rowIndex: rowIndex\n            });\n            self.openChildren[rowIndex].blur();\n            self.openChildren[rowIndex].dispose();\n            delete self.openChildren[rowIndex];\n            delete self.sizes.trees[rowIndex];\n            delete self.childGrids[rowIndex];\n            self.dispatchEvent('resizerow', {\n                cellHeight: self.style.cellHeight\n            });\n            self.resize(true);\n            self.draw(true);\n        };\n        /**\n         * Expands a tree grid by row index.\n         * @memberof canvasDatagrid\n         * @name expandTree\n         * @method\n         * @param {number} index The index of the row to expand.\n         */\n        self.expandTree = function (rowIndex) {\n            var trArgs = self.args.treeGridAttributes || {},\n                columnHeaderCellHeight = self.getColumnHeaderCellHeight(),\n                rowHeaderCellWidth = self.sizes.columns.cornerCell || self.style.rowHeaderCellWidth,\n                h = self.sizes.trees[rowIndex] || self.style.treeGridHeight,\n                treeGrid;\n            if (!self.childGrids[rowIndex]) {\n                trArgs.debug = self.attributes.debug;\n                trArgs.name = self.attributes.saveAppearance ? self.attributes.name + 'tree' + rowIndex : undefined;\n                trArgs.style = trArgs.style || self.style;\n                trArgs.parentNode = {\n                    parentGrid: self.intf,\n                    nodeType: 'canvas-datagrid-tree',\n                    offsetHeight: h,\n                    offsetWidth: self.width - rowHeaderCellWidth,\n                    header: { width: self.width - rowHeaderCellWidth },\n                    offsetLeft: rowHeaderCellWidth,\n                    offsetTop: columnHeaderCellHeight,\n                    offsetParent: self.intf.parentNode,\n                    parentNode: self.intf.parentNode,\n                    style: 'tree',\n                    data: self.data[rowIndex]\n                };\n                treeGrid = self.createGrid(trArgs);\n                self.childGrids[rowIndex] = treeGrid;\n            }\n            treeGrid = self.childGrids[rowIndex];\n            treeGrid.visible = true;\n            self.dispatchEvent('expandtree', {\n                treeGrid: treeGrid,\n                data: self.data[rowIndex],\n                rowIndex: rowIndex\n            });\n            self.openChildren[rowIndex] = treeGrid;\n            self.sizes.trees[rowIndex] = h;\n            self.dispatchEvent('resizerow', {height: self.style.cellHeight});\n            self.resize(true);\n        };\n        /**\n         * Toggles tree grid open and close by row index.\n         * @memberof canvasDatagrid\n         * @name toggleTree\n         * @method\n         * @param {number} index The index of the row to toggle.\n         */\n        self.toggleTree = function (rowIndex) {\n            var i = self.openChildren[rowIndex];\n            if (i) {\n                return self.collapseTree(rowIndex);\n            }\n            self.expandTree(rowIndex);\n        };\n        /**\n         * Returns a header from the schema by name.\n         * @memberof canvasDatagrid\n         * @name getHeaderByName\n         * @tutorial schema\n         * @method\n         * @returns {header} header with the selected name, or undefined.\n         * @param {string} name The name of the column to resize.\n         */\n        self.getHeaderByName = function (name) {\n            var x, i = self.getSchema();\n            for (x = 0; x < i.length; x += 1) {\n                if (i[x].name === name) {\n                    return i[x];\n                }\n            }\n        };\n        /**\n         * Resizes a column to fit the longest value in the column. Call without a value to resize all columns.\n         * Warning, can be slow on very large record sets (1m records ~3-5 seconds on an i7).\n         * @memberof canvasDatagrid\n         * @name fitColumnToValues\n         * @method\n         * @param {string} name The name of the column to resize.\n         */\n        self.fitColumnToValues = function (name, internal) {\n            if (!self.canvas) { return; }\n            self.sizes.columns[name === 'cornerCell' ? -1 : self.getHeaderByName(name).index]\n                = Math.max(self.findColumnMaxTextLength(name), self.style.minColumnWidth);\n            if (!internal) {\n                self.resize();\n                self.draw(true);\n            }\n        };\n        /**\n         * Checks if a cell is currently visible.\n         * @memberof canvasDatagrid\n         * @name isCellVisible\n         * @overload\n         * @method\n         * @returns {boolean} when true, the cell is visible, when false the cell is not currently drawn.\n         * @param {number} columnIndex The column index of the cell to check.\n         * @param {number} rowIndex The row index of the cell to check.\n         */\n        self.isCellVisible = function (cell, rowIndex) {\n            // overload\n            if (rowIndex !== undefined) {\n                return self.visibleCells.filter(function (c) {\n                    return c.columnIndex === cell && c.rowIndex === rowIndex;\n                }).length > 0;\n            }\n            var x, l = self.visibleCells.length;\n            for (x = 0; x < l; x += 1) {\n                if (cell.x === self.visibleCells[x].x && cell.y === self.visibleCells[x].y) {\n                    return true;\n                }\n            }\n            return false;\n        };\n        /**\n         * Sets the order of the data.\n         * @memberof canvasDatagrid\n         * @name order\n         * @method\n         * @param {number} columnName Name of the column to be sorted.\n         * @param {string} direction `asc` for ascending or `desc` for descending.\n         * @param {function} [sortFunction] When defined, override the default sorting method defined in the column's schema and use this one.\n         * @param {bool} [dontSetStorageData] Don't store this setting for future use.\n         */\n        self.order = function (columnName, direction, sortFunction, dontSetStorageData) {\n            var f,\n                c = self.getSchema().filter(function (col) {\n                    return col.name === columnName;\n                });\n            if (self.dispatchEvent('beforesortcolumn', {name: columnName, direction: direction})) { return; }\n            self.orderBy = columnName;\n            self.orderDirection = direction;\n            if (!self.data || self.data.length === 0) { return; }\n            if (c.length === 0) {\n                throw new Error('Cannot sort.  No such column name');\n            }\n            f = sortFunction || c[0].sorter || self.sorters[c[0].type];\n            if (!f && c[0].type !== undefined) {\n                console.warn('Cannot sort type \"%s\" falling back to string sort.', c[0].type);\n            }\n            self.orderings.add(columnName, direction, (typeof f === 'function' ? f : self.sorters.string));\n            self.orderings.sort();\n            self.dispatchEvent('sortcolumn', {name: columnName, direction: direction});\n            self.draw(true);\n            if (dontSetStorageData) { return; }\n            self.setStorageData();\n        };\n        self.isInGrid = function (e) {\n            if (e.x < 0\n                    || e.x > self.width\n                    || e.y < 0\n                    || e.y > self.height) {\n                return false;\n            }\n            return true;\n        };\n        /**\n         * Moves the current selection relative to the its current position.  Note: this method does not move the selected data, just the selection itself.\n         * @memberof canvasDatagrid\n         * @name moveSelection\n         * @method\n         * @param {number} offsetX The number of columns to offset the selection.\n         * @param {number} offsetY The number of rows to offset the selection.\n         */\n        self.moveSelection = function (offsetX, offsetY) {\n            var sel = [];\n            self.selections.forEach(function (row, rowIndex) {\n                sel[rowIndex + offsetY] = [];\n                row.forEach(function (colIndex) {\n                    sel[rowIndex + offsetY].push(colIndex + offsetX);\n                });\n            });\n            self.selections = sel;\n        };\n        /**\n         * Moves data in the provided selection to another position in the grid.  Moving data off the edge of the schema (columns/x) will truncate data.\n         * @memberof canvasDatagrid\n         * @name moveTo\n         * @method\n         * @param {array} sel 2D array representing selected rows and columns.  `canvasDatagrid.selections` is in this format and can be used here.\n         * @param {number} x The column index to start inserting the selection at.\n         * @param {number} y The row index to start inserting the selection at.\n         */\n        self.moveTo = function (sel, x, y) {\n            var d = self.getSelectedData(),\n                s = self.getVisibleSchema(),\n                l = sel.length,\n                xi,\n                maxRowLength = -Infinity,\n                minXi = Infinity,\n                yi = y - 1;\n            sel.forEach(function (row, index) {\n                if (index === l) { return; }\n                if (row.length === 0) { return; }\n                minXi = Math.min(self.getVisibleColumnIndexOf(x), minXi);\n                maxRowLength = Math.max(maxRowLength, row.length);\n                row.forEach(function (colIndex) {\n                    // intentional redef of colIndex\n                    colIndex = self.getVisibleColumnIndexOf(colIndex);\n                    if (!s[colIndex]) { return; }\n                    if (!self.data[index]) { self.data[index] = {}; }\n                    self.data[index][s[colIndex].name] = null;\n                });\n            });\n            sel.forEach(function (row, index) {\n                var lastSourceIndex;\n                yi += 1;\n                xi = self.getVisibleColumnIndexOf(x);\n                row.forEach(function (colIndex, cidx) {\n                    colIndex = self.getVisibleColumnIndexOf(colIndex);\n                    if (cidx > 0) {\n                        // this confusing bit of nonsense figures out\n                        // if the selection has skipped cells\n                        xi += colIndex - lastSourceIndex;\n                    }\n                    lastSourceIndex = colIndex;\n                    if (colIndex === -1\n                            || !s[xi]\n                            || !s[colIndex]\n                            || self.data.length - 1 < yi\n                            || yi < 0) { return; }\n                    if (!self.data[yi]) { self.data[yi] = {}; }\n                    self.data[yi][s[xi].name] = d[index][s[colIndex].name];\n                });\n            });\n        };\n        /**\n         * Checks if a given column is visible.\n         * @memberof canvasDatagrid\n         * @name isColumnVisible\n         * @method\n         * @returns {boolean} When true, the column is visible.\n         * @param {number} columnIndex Column index.\n         */\n        self.isColumnVisible = function (columnIndex) {\n            return self.visibleCells.filter(function (c) {\n                return c.columnIndex === columnIndex;\n            }).length > 0;\n        };\n        /**\n         * Checks if a given row is visible.\n         * @memberof canvasDatagrid\n         * @name isRowVisible\n         * @method\n         * @returns {boolean} When true, the row is visible.\n         * @param {number} rowIndex Row index.\n         */\n        self.isRowVisible = function (rowIndex) {\n            return self.visibleCells.filter(function (c) {\n                return c.rowIndex === rowIndex;\n            }).length > 0;\n        };\n        /**\n         * Gets the cell at columnIndex and rowIndex.\n         * @memberof canvasDatagrid\n         * @name getVisibleCellByIndex\n         * @method\n         * @returns {cell} cell at the selected location.\n         * @param {number} x Column index.\n         * @param {number} y Row index.\n         */\n        self.getVisibleCellByIndex = function (x, y) {\n            return self.visibleCells.filter(function (c) {\n                return c.columnIndex === x && c.rowIndex === y;\n            })[0];\n        };\n        /**\n         * Gets the cell at grid pixel coordinate x and y.  Author's note.  This function ties drawing and events together.  This is a very complex function and is core to the component.\n         * @memberof canvasDatagrid\n         * @name getCellAt\n         * @method\n         * @returns {cell} cell at the selected location.\n         * @param {number} x Number of pixels from the left.\n         * @param {number} y Number of pixels from the top.\n         */\n        self.getCellAt = function (x, y, useTouchScrollZones) {\n            function getBorder(entitiy) {\n                if (entitiy.x + entitiy.width - (self.attributes.borderResizeZone * 0.4) < x && entitiy.x + entitiy.width + (self.attributes.borderResizeZone * 0.6) > x) {\n                    return 'r';\n                }\n                if (entitiy.x - (self.attributes.borderResizeZone * 0.4) < x && entitiy.x + (self.attributes.borderResizeZone * 0.6) > x) {\n                    return 'l';\n                }\n                if (entitiy.y + entitiy.height - (self.attributes.borderResizeZone * 0.4) < y && entitiy.y + entitiy.height + (self.attributes.borderResizeZone * 0.6) > y) {\n                    return 'b';\n                }\n                if (entitiy.y - (self.attributes.borderResizeZone * 0.4) < y && entitiy.y + (self.attributes.borderResizeZone * 0.6) > y) {\n                    return 't';\n                }\n            }\n            if (!self.visibleCells) { return; }\n            var border,\n                tsz = useTouchScrollZones ? self.attributes.touchScrollZone : 0,\n                moveMode = self.attributes.borderDragBehavior === 'move',\n                i,\n                l = self.visibleCells.length,\n                moveBorder,\n                xBorderBehavior = moveMode ? self.cursorGrab : 'ew-resize',\n                yBorderBehavior = moveMode ? self.cursorGrab : 'ns-resize',\n                cell,\n                entitiy;\n            if (!self.visibleCells || !self.visibleCells.length) { return; }\n            self.hasFocus = true;\n            if (!(y < self.height\n                && y > 0\n                && x < self.width\n                && x > 0)) {\n                self.hasFocus = false;\n                return {\n                    dragContext: 'inherit',\n                    context: 'inherit'\n                };\n            }\n            for (i = 0; i < l; i += 1) {\n                cell = self.visibleCells[i];\n                // interactive dimensions of the cell.  used for touch \"over size\" zones\n                entitiy = {\n                    x: cell.x,\n                    y: cell.y,\n                    height: cell.height,\n                    width: cell.width\n                };\n                if (useTouchScrollZones && /(vertical|horizontal)-scroll-/.test(cell.style)) {\n                    entitiy.x -= tsz;\n                    entitiy.y -= tsz;\n                    entitiy.height += tsz;\n                    entitiy.width += tsz;\n                }\n                if (entitiy.x - self.style.cellBorderWidth < x\n                        && entitiy.x + entitiy.width + self.style.cellBorderWidth > x\n                        && entitiy.y - self.style.cellBorderWidth < y\n                        && entitiy.y + entitiy.height + self.style.cellBorderWidth > y) {\n                    if (/frozen-row-marker/.test(cell.style)) {\n                        cell.dragContext = cell.style;\n                        cell.context = 'row-resize';\n                        return cell;\n                    }\n                    if (/frozen-column-marker/.test(cell.style)) {\n                        cell.dragContext = cell.style;\n                        cell.context = 'col-resize';\n                        return cell;\n                    }\n                    if (/selection-handle-/.test(cell.style)) {\n                        cell.dragContext = cell.style;\n                        cell.context = 'crosshair';\n                        return cell;\n                    }\n                    if (/vertical-scroll-(bar|box)/.test(cell.style)) {\n                        cell.dragContext = 'vertical-scroll-box';\n                        cell.context = 'vertical-scroll-box';\n                        cell.isScrollBar = true;\n                        cell.isVerticalScrollBar = true;\n                        if (y > self.scrollBox.box.v.y + self.scrollBox.scrollBoxHeight) {\n                            cell.dragContext = 'vertical-scroll-bottom';\n                            cell.context = 'vertical-scroll-bottom';\n                        } else if (y < self.scrollBox.box.v.y) {\n                            cell.dragContext = 'vertical-scroll-top';\n                            cell.context = 'vertical-scroll-top';\n                        }\n                        self.cursor = 'default';\n                        return cell;\n                    }\n                    if (/horizontal-scroll-(bar|box)/.test(cell.style)) {\n                        cell.dragContext = 'horizontal-scroll-box';\n                        cell.context = 'horizontal-scroll-box';\n                        cell.isScrollBar = true;\n                        cell.isHorizontalScrollBar = true;\n                        if (x > self.scrollBox.box.h.x + self.scrollBox.scrollBoxWidth) {\n                            cell.dragContext = 'horizontal-scroll-right';\n                            cell.context = 'horizontal-scroll-right';\n                        } else if (x < self.scrollBox.box.h.x) {\n                            cell.dragContext = 'horizontal-scroll-left';\n                            cell.context = 'horizontal-scroll-left';\n                        }\n                        self.cursor = 'default';\n                        return cell;\n                    }\n                    border = getBorder(entitiy);\n                    // check if the border of this cell is the border of the selection and if so show move cursor in move mode\n                    moveBorder = moveMode && cell.selectionBorder && cell.selectionBorder.indexOf(border) !== -1;\n                    if (['l', 'r'].indexOf(border) !== -1\n                            && (self.attributes.allowColumnResize || moveBorder)\n                            && ((self.attributes.allowColumnResizeFromCell && cell.isNormal) || !cell.isNormal || moveBorder)\n                            && ((self.attributes.allowRowHeaderResize && (cell.isRowHeader || cell.isCorner)) || !(cell.isRowHeader && cell.isCorner))) {\n                        if (((cell.isColumnHeader || cell.isCorner) || (self.attributes.allowColumnResizeFromCell && cell.isNormal)) && border === 'r') {\n                            cell.context = 'ew-resize';\n                            cell.dragContext = 'ew-resize';\n                            return cell;\n                        }\n                        if (!(cell.isColumnHeader || cell.isCorner) && moveBorder) {\n                            cell.context = xBorderBehavior;\n                            cell.dragContext = border + '-move';\n                            return cell;\n                        }\n                    }\n                    if (['t', 'b'].indexOf(border) !== -1\n                            && cell.rowIndex > -1\n                            && (self.attributes.allowRowResize || moveBorder)\n                            && ((self.attributes.allowRowResizeFromCell && cell.isNormal) || !cell.isNormal || moveBorder)\n                            && !cell.isColumnHeader) {\n                        if (((cell.isRowHeader || cell.isCorner) || (self.attributes.allowRowResizeFromCell && cell.isNormal)) && border === 'b') {\n                            cell.context = 'ns-resize';\n                            cell.dragContext = 'ns-resize';\n                            return cell;\n                        }\n                        if (!(cell.isRowHeader || cell.isCorner) && moveBorder) {\n                            cell.context = yBorderBehavior;\n                            cell.dragContext = border + '-move';\n                            return cell;\n                        }\n                    }\n                    if (cell.style === 'columnHeaderCell') {\n                        cell.context = 'cell';\n                        cell.dragContext = 'column-reorder';\n                        return cell;\n                    }\n                    if (cell.style === 'rowHeaderCell') {\n                        if ((self.attributes.rowGrabZoneSize + (cell.y - self.style.cellBorderWidth) < y)\n                                || !self.attributes.allowRowReordering) {\n                            cell.dragContext = 'cell';\n                            cell.context = 'cell';\n                        } else {\n                            cell.context = self.cursorGrab;\n                            cell.dragContext = 'row-reorder';\n                        }\n                        return cell;\n                    }\n                    if (cell.isGrid) {\n                        self.hasFocus = false;\n                        cell.dragContext = 'cell-grid';\n                        cell.context = 'cell-grid';\n                        return cell;\n                    }\n                    if (cell.style === 'tree-grid') {\n                        self.hasFocus = false;\n                        cell.dragContext = 'tree';\n                        cell.context = 'tree';\n                        return cell;\n                    }\n                    cell.dragContext = 'cell';\n                    cell.context = 'cell';\n                    return cell;\n                }\n            }\n            self.hasFocus = true;\n            self.cursor = 'default';\n            return {\n                dragContext: 'background',\n                context: 'background',\n                style: 'background',\n                isBackground: true\n            };\n        };\n        /**\n         * Gets the bounds of current selection. \n         * @returns {rect} selection.\n         * @memberof canvasDatagrid\n         * @name getSelectionBounds\n         * @method\n         */\n        self.getSelectionBounds = function () {\n            var low = {x: Infinity, y: Infinity},\n                high = {x: -Infinity, y: -Infinity};\n            self.selections.forEach(function (row, rowIndex) {\n                var maxCol, minCol;\n                low.y = rowIndex < low.y ? rowIndex : low.y;\n                high.y = rowIndex > high.y ? rowIndex : high.y;\n                maxCol = Math.max.apply(null, row);\n                minCol = Math.min.apply(null, row);\n                low.x = minCol < low.x ? minCol : low.x;\n                high.x = maxCol > high.x ? maxCol : high.x;\n            });\n            return {\n                top: low.y,\n                left: low.x,\n                bottom: high.y,\n                right: high.x\n            };\n        };\n        /**\n         * Returns an auto generated schema based on data structure.\n         * @memberof canvasDatagrid\n         * @name getSchemaFromData\n         * @method\n         * @tutorial schema\n         * @returns {schema} schema A schema based on the first item in the data array.\n         */\n        self.getSchemaFromData = function (d) {\n            d = d || self.data;\n            return Object.keys(d[0] || {' ': ''}).map(function mapEachSchemaColumn(key, index) {\n                var type = self.getBestGuessDataType(key, d),\n                    i = {\n                        name: key,\n                        title: isNaN(parseInt(key, 10)) ? key : self.integerToAlpha(key).toUpperCase(),\n                        index: index,\n                        columnIndex: index,\n                        type: type,\n                        filter: self.filter(type)\n                    };\n                if (self.storedSettings\n                        && self.storedSettings.visibility\n                        && self.storedSettings.visibility[i.name] !== undefined) {\n                    i.hidden = !self.storedSettings.visibility[i.name];\n                }\n                return i;\n            });\n        };\n        /**\n         * Clears the change log grid.changes that keeps track of changes to the data set.\n         * This does not undo changes or alter data it is simply a convince array to keep\n         * track of changes made to the data since last this method was called.\n         * @memberof canvasDatagrid\n         * @name clearChangeLog\n         * @method\n         */\n        self.clearChangeLog = function () {\n            self.changes = [];\n        };\n        /**\n         * Selects an area of the grid.\n         * @memberof canvasDatagrid\n         * @name selectArea\n         * @method\n         * @param {rect} bounds A rect object representing the selected values.\n         */\n        self.selectArea = function (bounds, ctrl) {\n            self.selectionBounds = bounds || self.selectionBounds;\n            var ev, x, y, s = self.getSchema();\n            if (!ctrl) {\n                self.selections = [];\n            }\n            if (self.selectionBounds.top < -1\n                    || self.selectionBounds.bottom > self.data.length\n                    || self.selectionBounds.left < -1\n                    || self.selectionBounds.right > s.length) {\n                throw new Error('Impossible selection area');\n            }\n            for (x = self.selectionBounds.top; x <= self.selectionBounds.bottom; x += 1) {\n                self.selections[x] = [];\n                for (y = self.selectionBounds.left; y <= self.selectionBounds.right; y += 1) {\n                    if (self.selections[x].indexOf(y) === -1) {\n                        self.selections[x].push(y);\n                    }\n                }\n            }\n            ev = {\n                selections: self.selections,\n                selectionBounds: self.selectionBounds\n            };\n            Object.defineProperty(ev, 'selectedData', {\n                get: function () {\n                    return self.getSelectedData();\n                }\n            });\n            self.dispatchEvent('selectionchanged', ev);\n        };\n        /**\n         * Returns the maximum text width for a given column by column name.\n         * @memberof canvasDatagrid\n         * @name findColumnMaxTextLength\n         * @method\n         * @returns {number} The number of pixels wide the maximum width value in the selected column.\n         * @param {string} name The name of the column to calculate the value's width of.\n         */\n        self.findColumnMaxTextLength = function (name) {\n            var m = -Infinity;\n            if (name === 'cornerCell') {\n                self.ctx.font = self.style.rowHeaderCellFont;\n                return self.ctx.measureText((self.data.length + (self.attributes.showNewRow ? 1 : 0)).toString()).width\n                    + self.style.autosizePadding + self.style.autosizeHeaderCellPadding\n                    + self.style.rowHeaderCellPaddingRight\n                    + self.style.rowHeaderCellPaddingLeft\n                    + (self.attributes.tree ? self.style.treeArrowWidth\n                        + self.style.treeArrowMarginLeft + self.style.treeArrowMarginRight : 0);\n            }\n            self.getSchema().forEach(function (col) {\n                if (col.name !== name) { return; }\n                self.ctx.font = self.style.columnHeaderCellFont;\n                var t = self.ctx.measureText(col.title || col.name).width\n                    + self.style.headerCellPaddingRight\n                    + self.style.headerCellPaddingLeft;\n                m = t > m ? t : m;\n            });\n            self.data.forEach(function (row) {\n                self.ctx.font = self.style.cellFont;\n                var t = self.ctx.measureText(row[name]).width\n                    + self.style.cellPaddingRight\n                    + self.style.cellPaddingLeft + self.style.cellAutoResizePadding;\n                m = t > m ? t : m;\n            });\n            return m;\n        };\n        /**\n         * Gets the total width of all header columns.\n         * @memberof canvasDatagrid\n         * @name getHeaderWidth\n         * @method\n         */\n        self.getHeaderWidth = function () {\n            return self.getVisibleSchema().reduce(function (total, header) {\n                return total + (header.width || self.style.cellWidth);\n            }, 0);\n        };\n        /**\n         * Gets the height of a row by index.\n         * @memberof canvasDatagrid\n         * @name getRowHeight\n         * @method\n         * @param {number} rowIndex The row index to lookup.\n         */\n        self.getRowHeight = function (rowIndex) {\n            return ((self.sizes.rows[rowIndex]\n                    || self.style.cellHeight) * self.scale);\n        };\n        /**\n         * Gets the width of a column by index.\n         * @memberof canvasDatagrid\n         * @name getColummnWidth\n         * @method\n         * @param {number} columnIndex The column index to lookup.\n         */\n        self.getColummnWidth = function (columnIndex) {\n            return ((self.sizes.columns[columnIndex]\n                    || self.getSchema()[columnIndex].width\n                    || self.style.cellWidth) * self.scale);\n        };\n        self.formatters.string = function cellFormatterString(e) {\n            return e.cell.value !== undefined ? e.cell.value : '';\n        };\n        self.formatters.rowHeaderCell = self.formatters.string;\n        self.formatters.headerCell = self.formatters.string;\n        self.formatters.number = self.formatters.string;\n        self.formatters.int = self.formatters.string;\n        self.formatters.html = self.formatters.string;\n        self.sorters.string = function (columnName, direction) {\n            var asc = direction === 'asc';\n            return function (a, b) {\n                if (a[columnName] === undefined || a[columnName] === null) {\n                    return 1;\n                }\n                if (b[columnName] === undefined || b[columnName] === null) {\n                    return 0;\n                }\n                if (asc) {\n                    if (!a[columnName].localeCompare) { return 1; }\n                    return a[columnName].localeCompare(b[columnName]);\n                }\n                if (!b[columnName].localeCompare) { return 1; }\n                return b[columnName].localeCompare(a[columnName]);\n            };\n        };\n        self.sorters.number = function (columnName, direction) {\n            var asc = direction === 'asc';\n            return function (a, b) {\n                if (asc) {\n                    return a[columnName] - b[columnName];\n                }\n                return b[columnName] - a[columnName];\n            };\n        };\n        self.sorters.date = function (columnName, direction) {\n            var asc = direction === 'asc';\n            return function (a, b) {\n                if (asc) {\n                    return new Date(a[columnName]).getTime()\n                        - new Date(b[columnName]).getTime();\n                }\n                return new Date(b[columnName]).getTime()\n                        - new Date(a[columnName]).getTime();\n            };\n        };\n    };\n});\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./lib/publicMethods.js\n// module id = 9\n// module chunks = 0"],"sourceRoot":""}