diff --git a/CHANGELOG.md b/CHANGELOG.md index 3845640..9a9b623 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +Version 0.2.0 (November 17th 2020) +----------------------------- + * Added support for array of different objects + +Version 0.1.11 (April 10th 2020) +----------------------------- + * Fixed csv export with custom labels on Firefox + Version 0.1.10 (April 10th 2019) ----------------------------- * Fixed csv export with better filename checking diff --git a/README.md b/README.md index 30a3a22..6cbc1e6 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,17 @@ The main purpose of this library is to provide an easy way to export your data a ## Installation +### npm + +```bash +$ npm i @lcluber/csvxjs +``` + +### yarn + ```bash -$ npm install @lcluber/csvxjs +$ yarn add @lcluber/csvxjs ``` -Or download it **[here](http://csvxjs.lcluber.com/#download)**. ## Usage @@ -29,27 +36,34 @@ import { Export, Convert } from '@lcluber/csvxjs'; let array = [ { firstname:'Galileo', - lastname:'Galilei', + lastname:'Galiléi', born:1564, died:1642 }, { firstname:'Nikola', lastname:'Tesla', + city:'Smiljan', born:1856, died:1943 }, { firstname:'Albert', - lastname:'Einstein', born:1879, + lastname:'Einstein', died:1955 } ]; - +let customLabels = { + firstname: 'First name', + lastname: 'Last name', + city: 'City', + born: 'Born', + died: 'Died' +}; let exportButton = document.getElementById('csv'); exportButton.addEventListener('click', function() { - Export.data('scientists',array,{separator: ';'});// ; separator for excel friendly imports + Export.data('scientists',array,{separator: ';', customLabels: customLabels});// ; separator for excel friendly imports }); // Convert CSV data to HTML table @@ -73,29 +87,36 @@ document.getElementById("table").innerHTML = Convert.table(data,{separator: ';'} // Convert an array to CSV file var array = [ - { + { firstname:'Galileo', - lastname:'Galilei', + lastname:'Galiléi', born:1564, died:1642 }, { firstname:'Nikola', lastname:'Tesla', + city:'Smiljan', born:1856, died:1943 }, { firstname:'Albert', - lastname:'Einstein', born:1879, + lastname:'Einstein', died:1955 } ]; - +var customLabels = { + firstname: 'First name', + lastname: 'Last name', + city: 'City', + born: 'Born', + died: 'Died' +}; var exportButton = document.getElementById('csv'); exportButton.addEventListener('click', function() { - CSVx.Export.data('scientists',array,{separator: ';'});// ; separator for excel friendly imports + CSVx.Export.data('scientists',array,{separator: ';', customLabels: customLabels});// ; separator for excel friendly imports }); // Convert CSV data to HTML table @@ -110,6 +131,8 @@ document.getElementById("table").innerHTML = CSVx.Convert.table(data,{separator: ### Options ```javascript +interface Data { [key: string]: number|string }[] + interface Options { data?: string; // default : 'text/csv' charset?: string; // default : 'utf-8' @@ -117,7 +140,7 @@ interface Options { quote?: string; // default : '"' separator?: string; // default : ',' CRLF?: string; // default : '\r\n' - customLabels?: string[]; // default : [] + customLabels: { [key: string]: string }; // default : {} } interface CSS { @@ -126,18 +149,6 @@ interface CSS { } ``` -## Demo - -See a basic example **[here](http://csvxjs.lcluber.com/#example)**. - -## API Reference - -Read the documentation **[here](http://csvxjs.lcluber.com/doc/)**. - -## Tests - -No tests to run yet - ## Contributors CSVx.js is still in early development and I would be glad to get all the help you can provide for this project. diff --git a/dist/csvx.iife.js b/dist/csvx.iife.js index 5a89bc3..190e815 100644 --- a/dist/csvx.iife.js +++ b/dist/csvx.iife.js @@ -508,175 +508,6 @@ var CSVx = (function (exports) { * http://aiasjs.lcluber.com */ - /** MIT License - * - * Copyright (c) 2015 Ludovic CLUBER - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * http://mouettejs.lcluber.com - */ - var LEVELS$2 = [{ - id: 1, - name: 'info' - }, { - id: 2, - name: 'trace' - }, { - id: 3, - name: 'warn' - }, { - id: 4, - name: 'error' - }, { - id: 99, - name: 'off' - }]; - - var Message$2 = - /*#__PURE__*/ - function () { - function Message(levelName, content) { - this.setLevel(levelName); - this.content = content; - } - - var _proto = Message.prototype; - - _proto.setLevel = function setLevel(name) { - this.level = this.findLevel(name); - }; - - _proto.getLevelId = function getLevelId() { - return this.level.id; - }; - - _proto.display = function display() { - console[this.level.name](this.content); - }; - - _proto.findLevel = function findLevel(name) { - for (var _iterator = LEVELS$2, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { - var _ref; - - if (_isArray) { - if (_i >= _iterator.length) break; - _ref = _iterator[_i++]; - } else { - _i = _iterator.next(); - if (_i.done) break; - _ref = _i.value; - } - - var level = _ref; - - if (level.name === name) { - return level; - } - } - - return this.level ? this.level : LEVELS$2[0]; - }; - - return Message; - }(); - - var Logger$2 = - /*#__PURE__*/ - function () { - function Logger() {} - - Logger.info = function info(text) { - Logger.log('info', text); - }; - - Logger.trace = function trace(text) { - Logger.log('trace', text); - }; - - Logger.time = function time(text) { - Logger.log('time', text); - }; - - Logger.warn = function warn(text) { - Logger.log('warn', text); - }; - - Logger.error = function error(text) { - Logger.log('error', text); - }; - - Logger.log = function log(levelName, content) { - Logger.addMessage(levelName, content); - var message = this.messages[this.nbMessages - 1]; - - if (this._level.id <= message.getLevelId()) { - message.display(); - } - }; - - Logger.addMessage = function addMessage(levelName, content) { - this.messages.push(new Message$2(levelName, content)); - this.nbMessages++; - }; - - Logger.findLevel = function findLevel(name) { - for (var _iterator2 = LEVELS$2, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { - var _ref2; - - if (_isArray2) { - if (_i2 >= _iterator2.length) break; - _ref2 = _iterator2[_i2++]; - } else { - _i2 = _iterator2.next(); - if (_i2.done) break; - _ref2 = _i2.value; - } - - var level = _ref2; - - if (level.name === name) { - return level; - } - } - - return this._level ? this._level : LEVELS$2[0]; - }; - - _createClass(Logger, [{ - key: "level", - set: function set(name) { - Logger._level = Logger.findLevel(name); - }, - get: function get() { - return Logger._level.name; - } - }]); - - return Logger; - }(); - - Logger$2._level = Logger$2.findLevel(LEVELS$2[0].name); - Logger$2.messages = []; - Logger$2.nbMessages = 0; - Logger$2.target = document.getElementById('Mouette'); - /** MIT License * * Copyright (c) 2018 Ludovic CLUBER @@ -832,147 +663,46 @@ var CSVx = (function (exports) { }(); /** MIT License - * - * Copyright (c) 2015 Ludovic CLUBER - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * http://mouettejs.lcluber.com - */ - var LEVELS$3 = { - info: { - id: 1, - name: 'info', - color: '#28a745' - }, - trace: { - id: 2, - name: 'trace', - color: '#17a2b8' - }, - warn: { - id: 3, - name: 'warn', - color: '#ffc107' - }, - error: { - id: 4, - name: 'error', - color: '#dc3545' - }, - off: { - id: 99, - name: 'off', - color: null - } - }; - - function addZero(value) { - return value < 10 ? '0' + value : value; + * + * Copyright (c) 2009 Ludovic CLUBER + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * https://github.com/LCluber/Ch.js + */ + function isObject(object) { + return object !== null && typeof object === "object" && !isArray(object); } - function formatDate() { - var now = new Date(); - var date = [addZero(now.getMonth() + 1), addZero(now.getDate()), now.getFullYear().toString().substr(-2)]; - var time = [addZero(now.getHours()), addZero(now.getMinutes()), addZero(now.getSeconds())]; - return date.join("/") + " " + time.join(":"); + function isArray(array) { + return array !== null && array.constructor === Array; } - var Message$3 = - /*#__PURE__*/ - function () { - function Message(level, content) { - this.id = level.id; - this.name = level.name; - this.color = level.color; - this.content = content; - this.date = formatDate(); - } - - var _proto = Message.prototype; - - _proto.display = function display(groupName) { - console[this.name]('%c[' + groupName + '] ' + this.date + ' : ', 'color:' + this.color + ';', this.content); - }; - - return Message; - }(); - - var Group = - /*#__PURE__*/ - function () { - function Group(name) { - this.messages = []; - this.name = name; - this.messages = []; - this._level = LEVELS$3.info; - } - - var _proto2 = Group.prototype; - - _proto2.info = function info(message) { - this.log(LEVELS$3.info, message); - }; - - _proto2.trace = function trace(message) { - this.log(LEVELS$3.trace, message); - }; - - _proto2.warn = function warn(message) { - this.log(LEVELS$3.warn, message); - }; - - _proto2.error = function error(message) { - this.log(LEVELS$3.error, message); - }; - - _proto2.log = function log(level, messageContent) { - var message = new Message$3(level, messageContent); - this.messages.push(message); - - if (this._level.id <= message.id) { - message.display(this.name); - } - }; - - _createClass(Group, [{ - key: "level", - set: function set(name) { - this._level = LEVELS$3.hasOwnProperty(name) ? LEVELS$3[name] : this._level; - }, - get: function get() { - return this._level.name; - } - }]); - - return Group; - }(); - - var Logger$3 = + var Export = /*#__PURE__*/ function () { - function Logger() {} - - Logger.setLevel = function setLevel(name) { - Logger.level = LEVELS$3.hasOwnProperty(name) ? LEVELS$3[name] : Logger.level; + function Export() {} - for (var _iterator = Logger.groups, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { + Export.data = function data(filename, _data, options) { + // check data consistency + for (var _iterator = _data, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { var _ref; if (_isArray) { @@ -984,60 +714,13 @@ var CSVx = (function (exports) { _ref = _i.value; } - var group = _ref; - group.level = Logger.level.name; - } - }; - - Logger.getLevel = function getLevel() { - return Logger.level.name; - }; - - Logger.getGroup = function getGroup(name) { - for (var _iterator2 = Logger.groups, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { - var _ref2; - - if (_isArray2) { - if (_i2 >= _iterator2.length) break; - _ref2 = _iterator2[_i2++]; - } else { - _i2 = _iterator2.next(); - if (_i2.done) break; - _ref2 = _i2.value; - } - - var group = _ref2; + var row = _ref; - if (group.name === name) { - return group; + if (!isObject(row)) { + return false; } } - return null; - }; - - Logger.addGroup = function addGroup(name) { - var group = new Group(name); - Logger.groups.push(group); - return group; - }; - - return Logger; - }(); - - Logger$3.level = LEVELS$3.info; - Logger$3.groups = []; - - var Export = - /*#__PURE__*/ - function () { - function Export() {} - - Export.data = function data(filename, _data, options) { - if (!Is.object(_data[0]) && !Is.json(_data[0])) { - return false; - } - if (!filename) { filename = 'export'; } @@ -1047,19 +730,21 @@ var CSVx = (function (exports) { } var table = 'data:' + this.options.data + ';charset=' + this.options.charset + ",\uFEFF"; + var labels = []; - if (this.options.labels) { - if (this.options.customLabels.length > 0) { - table += this.createCustomLabels(this.options.customLabels); - } else { - table += this.createLabels(_data); - } + if (!this.options.customLabels) { + labels = this.createLabels(_data); + } else { + labels = this.createCustomLabels(this.options.customLabels); + } - this.log.info(filename + ' labels ready'); + if (this.options.labels) { + table += this.createLabelsRow(labels); // this.log.info(filename + ' labels ready'); } - table += this.createTable(_data); - this.log.info(filename + ' table ready'); + table += this.createTable(_data); // console.log('table', table); + // this.log.info(filename + ' table ready'); + this.download(table, filename); return true; }; @@ -1083,76 +768,113 @@ var CSVx = (function (exports) { download: filename + '.csv' }); link.click(); - document.body.removeChild(link); - this.log.info(filename + ' downloading'); + document.body.removeChild(link); // this.log.info(filename + ' downloading'); } }; Export.createTable = function createTable(data) { var table = ''; - for (var _iterator = data, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { - var _ref; + for (var _iterator2 = data, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { + var _ref2; - if (_isArray) { - if (_i >= _iterator.length) break; - _ref = _iterator[_i++]; + if (_isArray2) { + if (_i2 >= _iterator2.length) break; + _ref2 = _iterator2[_i2++]; } else { - _i = _iterator.next(); - if (_i.done) break; - _ref = _i.value; - } - - var row = _ref; - var obj = Is.json(row) || row; - - if (!Is.object(obj)) { - return table; + _i2 = _iterator2.next(); + if (_i2.done) break; + _ref2 = _i2.value; } + var row = _ref2; var parsedRow = ''; - for (var property in obj) { - if (obj.hasOwnProperty(property)) { - parsedRow += this.createField(obj[property]); - } + for (var property in this.options.customLabels) { + parsedRow += this.createField(row[property] || ''); } table += this.createRow(parsedRow); } - return encodeURIComponent(table); + return table; }; Export.createLabels = function createLabels(data) { - var labels = Is.json(data[0]) || data[0]; - var parsedRow = ''; + var params = []; + + for (var _iterator3 = data, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) { + var _ref3; - for (var label in labels) { - if (labels.hasOwnProperty(label)) { - parsedRow += this.createField(label); + if (_isArray3) { + if (_i3 >= _iterator3.length) break; + _ref3 = _iterator3[_i3++]; + } else { + _i3 = _iterator3.next(); + if (_i3.done) break; + _ref3 = _i3.value; + } + + var row = _ref3; + var i = 0; + + var _loop = function _loop(property) { + if (row.hasOwnProperty(property)) { + var newProperty = params.find(function (value) { + return value === property; + }); + + if (!newProperty) { + params.splice(i, 0, property); + } + + i++; + } + }; + + for (var property in row) { + _loop(property); } } - return this.createRow(parsedRow); + this.options.customLabels = {}; + + for (var _i4 = 0, _params = params; _i4 < _params.length; _i4++) { + var param = _params[_i4]; + this.options.customLabels[param] = param; + } + + return params; }; Export.createCustomLabels = function createCustomLabels(customLabels) { + var params = []; + + for (var property in customLabels) { + if (customLabels.hasOwnProperty(property)) { + params.push(customLabels[property]); + } + } + + return params; + }; + + Export.createLabelsRow = function createLabelsRow(labels) { var parsedRow = ''; - for (var _iterator2 = customLabels, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { - var _ref2; + for (var _iterator4 = labels, _isArray4 = Array.isArray(_iterator4), _i5 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) { + var _ref4; - if (_isArray2) { - if (_i2 >= _iterator2.length) break; - _ref2 = _iterator2[_i2++]; + if (_isArray4) { + if (_i5 >= _iterator4.length) break; + _ref4 = _iterator4[_i5++]; } else { - _i2 = _iterator2.next(); - if (_i2.done) break; - _ref2 = _i2.value; + _i5 = _iterator4.next(); + if (_i5.done) break; + _ref4 = _i5.value; } - var label = _ref2; + var label = _ref4; parsedRow += this.createField(label); } @@ -1160,6 +882,7 @@ var CSVx = (function (exports) { }; Export.createRow = function createRow(row) { + // console.log(row.slice(0, -1) + this.options.CRLF); return row.slice(0, -1) + this.options.CRLF; }; @@ -1168,8 +891,8 @@ var CSVx = (function (exports) { }; return Export; - }(); - Export.log = Logger$3.addGroup('CSVx Exporter'); // default option values + }(); // static log = Logger.addGroup('CSVx Exporter'); + // default option values Export.options = { data: 'text/csv', @@ -1178,7 +901,7 @@ var CSVx = (function (exports) { quote: '"', separator: ',', CRLF: '\r\n', - customLabels: [] + customLabels: null }; var Convert = @@ -1206,7 +929,7 @@ var CSVx = (function (exports) { var rows = data.trim().split(this.options.CRLF).filter(Boolean); if (!rows.length) { - this.log.warn(this.options.CRLF + ' CRLF not found'); + // this.log.warn(this.options.CRLF + ' CRLF not found'); return false; } @@ -1286,8 +1009,8 @@ var CSVx = (function (exports) { }; return Convert; - }(); - Convert.log = Logger$3.addGroup('CSVx Converter'); // static html: string = null; + }(); // static log = Logger.addGroup('CSVx Converter'); + // static html: string = null; // default option values Convert.options = { diff --git a/dist/csvx.iife.min.js b/dist/csvx.iife.min.js index d191ee9..520eb73 100644 --- a/dist/csvx.iife.min.js +++ b/dist/csvx.iife.min.js @@ -23,4 +23,4 @@ * http://csvxjs.lcluber.com */ -var CSVx=function(e){"use strict";function r(e,t){for(var n=0;n=t.length)break;i=t[r++]}else{if((r=t.next()).done)break;i=r.value}var o=i;if(o.name===e)return o}return this.level?this.level:s[0]},e}(),a=function(){function r(){}return r.info=function(e){r.log("info",e)},r.trace=function(e){r.log("trace",e)},r.time=function(e){r.log("time",e)},r.warn=function(e){r.log("warn",e)},r.error=function(e){r.log("error",e)},r.log=function(e,t){r.addMessage(e,t);var n=this.messages[this.nbMessages-1];this._level.id<=n.getLevelId()&&n.display()},r.addMessage=function(e,t){this.messages.push(new i(e,t)),this.nbMessages++},r.findLevel=function(e){var t=s,n=Array.isArray(t),r=0;for(t=n?t:t[Symbol.iterator]();;){var i;if(n){if(r>=t.length)break;i=t[r++]}else{if((r=t.next()).done)break;i=r.value}var o=i;if(o.name===e)return o}return this._level?this._level:s[0]},n(r,[{key:"level",set:function(e){r._level=r.findLevel(e)},get:function(){return r._level.name}}]),r}();a._level=a.findLevel(s[0].name),a.messages=[],a.nbMessages=0,a.target=document.getElementById("Mouette");var c=function(){function e(){}return e.json=function(e){if(!this.string(e))return!1;var t=e.replace(/(\r\n|\n|\r|\t)/gm,"");try{t=JSON.parse(e)}catch(e){return a.error(e),!1}return t},e.function=function(e){return e&&"[object Function]"==={}.toString.call(e)},e.object=function(e){return null!==e&&"object"==typeof e},e.array=function(e){return null!==e&&e.constructor===Array},e.ascii=function(e,t){return(t?/^[\x00-\xFF]*$/:/^[\x00-\x7F]*$/).test(e)},e.integer=function(e){return e===parseInt(e,10)},e.float=function(e){return Number(e)===e&&e%1!=0},e.string=function(e){return"string"==typeof e},e}(),l=[{id:1,name:"info"},{id:2,name:"trace"},{id:3,name:"warn"},{id:4,name:"error"},{id:99,name:"off"}],u=function(){function e(e,t){this.setLevel(e),this.content=t}var t=e.prototype;return t.setLevel=function(e){this.level=this.findLevel(e)},t.getLevelId=function(){return this.level.id},t.display=function(){console[this.level.name](this.content)},t.findLevel=function(e){var t=l,n=Array.isArray(t),r=0;for(t=n?t:t[Symbol.iterator]();;){var i;if(n){if(r>=t.length)break;i=t[r++]}else{if((r=t.next()).done)break;i=r.value}var o=i;if(o.name===e)return o}return this.level?this.level:l[0]},e}(),t=function(){function r(){}return r.info=function(e){r.log("info",e)},r.trace=function(e){r.log("trace",e)},r.time=function(e){r.log("time",e)},r.warn=function(e){r.log("warn",e)},r.error=function(e){r.log("error",e)},r.log=function(e,t){r.addMessage(e,t);var n=this.messages[this.nbMessages-1];this._level.id<=n.getLevelId()&&n.display()},r.addMessage=function(e,t){this.messages.push(new u(e,t)),this.nbMessages++},r.findLevel=function(e){var t=l,n=Array.isArray(t),r=0;for(t=n?t:t[Symbol.iterator]();;){var i;if(n){if(r>=t.length)break;i=t[r++]}else{if((r=t.next()).done)break;i=r.value}var o=i;if(o.name===e)return o}return this._level?this._level:l[0]},n(r,[{key:"level",set:function(e){r._level=r.findLevel(e)},get:function(){return r._level.name}}]),r}();t._level=t.findLevel(l[0].name),t.messages=[],t.nbMessages=0,t.target=document.getElementById("Mouette");var f=[{id:1,name:"info"},{id:2,name:"trace"},{id:3,name:"warn"},{id:4,name:"error"},{id:99,name:"off"}],h=function(){function e(e,t){this.setLevel(e),this.content=t}var t=e.prototype;return t.setLevel=function(e){this.level=this.findLevel(e)},t.getLevelId=function(){return this.level.id},t.display=function(){console[this.level.name](this.content)},t.findLevel=function(e){var t=f,n=Array.isArray(t),r=0;for(t=n?t:t[Symbol.iterator]();;){var i;if(n){if(r>=t.length)break;i=t[r++]}else{if((r=t.next()).done)break;i=r.value}var o=i;if(o.name===e)return o}return this.level?this.level:f[0]},e}(),v=function(){function r(){}return r.info=function(e){r.log("info",e)},r.trace=function(e){r.log("trace",e)},r.time=function(e){r.log("time",e)},r.warn=function(e){r.log("warn",e)},r.error=function(e){r.log("error",e)},r.log=function(e,t){r.addMessage(e,t);var n=this.messages[this.nbMessages-1];this._level.id<=n.getLevelId()&&n.display()},r.addMessage=function(e,t){this.messages.push(new h(e,t)),this.nbMessages++},r.findLevel=function(e){var t=f,n=Array.isArray(t),r=0;for(t=n?t:t[Symbol.iterator]();;){var i;if(n){if(r>=t.length)break;i=t[r++]}else{if((r=t.next()).done)break;i=r.value}var o=i;if(o.name===e)return o}return this._level?this._level:f[0]},n(r,[{key:"level",set:function(e){r._level=r.findLevel(e)},get:function(){return r._level.name}}]),r}();v._level=v.findLevel(f[0].name),v.messages=[],v.nbMessages=0,v.target=document.getElementById("Mouette");var d=function(){function e(){}return e.scrollToBottom=function(e){e.scrollTop=e.scrollHeight},e.scrollToTop=function(e){e.scrollTop=0},e.findById=function(e){return document.getElementById(e)},e.findByClass=function(e){return this.arrayFrom(document.getElementsByClassName(e))},e.findByTag=function(e){return this.arrayFrom(document.getElementsByTagName(e))},e.showElement=function(e){return this.styleElement(e,"display","block")},e.hideElement=function(e){return this.styleElement(e,"display","none")},e.styleElement=function(e,t,n){return(e=this.checkElement(e))&&(e.style[t]=n),e},e.showOverflow=function(){document.body.style.overflow="visible"},e.hideOverflow=function(){document.body.style.overflow="hidden"},e.getInputValue=function(e){return(e=this.checkElement(e))?e.value:null},e.clearInputValue=function(e){return(e=this.checkElement(e))&&(e.value=""),e},e.focusOn=function(e){return(e=this.checkElement(e))&&e.focus(),e},e.addHTMLElement=function(e,t,n){e=this.checkElement(e);var r=document.createElement(t);return n&&Object.keys(n).forEach(function(e){"textContent"===e||"innerHTML"===e?r[e]=n[e]:r.setAttribute(e,n[e])}),e.appendChild(r),r},e.clearHTMLElement=function(e){return(e=this.checkElement(e))&&(e.innerHTML=""),e},e.arrayFrom=function(e){for(var t=[],n=0;n=t.length)break;i=t[r++]}else{if((r=t.next()).done)break;i=r.value}i.level=s.level.name}},s.getLevel=function(){return s.level.name},s.getGroup=function(e){var t=s.groups,n=Array.isArray(t),r=0;for(t=n?t:t[Symbol.iterator]();;){var i;if(n){if(r>=t.length)break;i=t[r++]}else{if((r=t.next()).done)break;i=r.value}var o=i;if(o.name===e)return o}return null},s.addGroup=function(e){var t=new y(e);return s.groups.push(t),t},s}();p.level=m.info,p.groups=[];var b=function(){function e(){}return e.data=function(e,t,n){if(!c.object(t[0])&&!c.json(t[0]))return!1;e||(e="export"),n&&this.setOptions(n);var r="data:"+this.options.data+";charset="+this.options.charset+",\ufeff";return this.options.labels&&(0=n.length)break;o=n[i++]}else{if((i=n.next()).done)break;o=i.value}var s=o,a=c.json(s)||s;if(!c.object(a))return t;var l="";for(var u in a)a.hasOwnProperty(u)&&(l+=this.createField(a[u]));t+=this.createRow(l)}return encodeURIComponent(t)},e.createLabels=function(e){var t=c.json(e[0])||e[0],n="";for(var r in t)t.hasOwnProperty(r)&&(n+=this.createField(r));return this.createRow(n)},e.createCustomLabels=function(e){var t="",n=e,r=Array.isArray(n),i=0;for(n=r?n:n[Symbol.iterator]();;){var o;if(r){if(i>=n.length)break;o=n[i++]}else{if((i=n.next()).done)break;o=i.value}var s=o;t+=this.createField(s)}return this.createRow(t)},e.createRow=function(e){return console.log(e.slice(0,-1)+this.options.CRLF),e.slice(0,-1)+this.options.CRLF},e.createField=function(e){return this.options.quote+e+this.options.quote+this.options.separator},e}();b.log=p.addGroup("CSVx Exporter"),b.options={data:"text/csv",charset:"utf-8",labels:!0,quote:'"',separator:",",CRLF:"\r\n",customLabels:[]};var L=function(){function e(){}return e.setOptions=function(e){this.setObject("options",e)},e.setCSS=function(e){this.setObject("css",e)},e.array=function(e,t,n){t&&this.setOptions(t),n&&this.setCSS(n);var r=e.trim().split(this.options.CRLF).filter(Boolean);if(!r.length)return this.log.warn(this.options.CRLF+" CRLF not found"),!1;var i=[],o=r,s=Array.isArray(o),a=0;for(o=s?o:o[Symbol.iterator]();;){var l;if(s){if(a>=o.length)break;l=o[a++]}else{if((a=o.next()).done)break;l=a.value}var u=l.split(this.options.separator);if(this.options.quote)for(var c=0;c"):o.push(this.createTr(r[s],a,""))}if(i||o.length)return""+i+""+o.join("")+"
"}return!1},e.createTr=function(e,t,n){return"<"+t+n+">"+e.join("<"+t+n+">")+""},e.setObject=function(e,t){for(var n in t)t.hasOwnProperty(n)&&this[e].hasOwnProperty(n)&&(this[e][n]=t[n])},e}();return L.log=p.addGroup("CSVx Converter"),L.options={labels:!0,quote:'"',separator:",",CRLF:"\r\n"},L.css={table:"",th:""},e.Export=b,e.Convert=L,e}({}); \ No newline at end of file +var CSVx=function(e){"use strict";function r(e,t){for(var n=0;n=t.length)break;i=t[r++]}else{if((r=t.next()).done)break;i=r.value}var o=i;if(o.name===e)return o}return this.level?this.level:s[0]},e}(),i=function(){function r(){}return r.info=function(e){r.log("info",e)},r.trace=function(e){r.log("trace",e)},r.time=function(e){r.log("time",e)},r.warn=function(e){r.log("warn",e)},r.error=function(e){r.log("error",e)},r.log=function(e,t){r.addMessage(e,t);var n=this.messages[this.nbMessages-1];this._level.id<=n.getLevelId()&&n.display()},r.addMessage=function(e,t){this.messages.push(new n(e,t)),this.nbMessages++},r.findLevel=function(e){var t=s,n=Array.isArray(t),r=0;for(t=n?t:t[Symbol.iterator]();;){var i;if(n){if(r>=t.length)break;i=t[r++]}else{if((r=t.next()).done)break;i=r.value}var o=i;if(o.name===e)return o}return this._level?this._level:s[0]},t(r,[{key:"level",set:function(e){r._level=r.findLevel(e)},get:function(){return r._level.name}}]),r}();i._level=i.findLevel(s[0].name),i.messages=[],i.nbMessages=0,i.target=document.getElementById("Mouette");var o=function(){function e(){}return e.json=function(e){if(!this.string(e))return!1;var t=e.replace(/(\r\n|\n|\r|\t)/gm,"");try{t=JSON.parse(e)}catch(e){return i.error(e),!1}return t},e.function=function(e){return e&&"[object Function]"==={}.toString.call(e)},e.object=function(e){return null!==e&&"object"==typeof e},e.array=function(e){return null!==e&&e.constructor===Array},e.ascii=function(e,t){return(t?/^[\x00-\xFF]*$/:/^[\x00-\x7F]*$/).test(e)},e.integer=function(e){return e===parseInt(e,10)},e.float=function(e){return Number(e)===e&&e%1!=0},e.string=function(e){return"string"==typeof e},e}(),a=[{id:1,name:"info"},{id:2,name:"trace"},{id:3,name:"warn"},{id:4,name:"error"},{id:99,name:"off"}],l=function(){function e(e,t){this.setLevel(e),this.content=t}var t=e.prototype;return t.setLevel=function(e){this.level=this.findLevel(e)},t.getLevelId=function(){return this.level.id},t.display=function(){console[this.level.name](this.content)},t.findLevel=function(e){var t=a,n=Array.isArray(t),r=0;for(t=n?t:t[Symbol.iterator]();;){var i;if(n){if(r>=t.length)break;i=t[r++]}else{if((r=t.next()).done)break;i=r.value}var o=i;if(o.name===e)return o}return this.level?this.level:a[0]},e}(),c=function(){function r(){}return r.info=function(e){r.log("info",e)},r.trace=function(e){r.log("trace",e)},r.time=function(e){r.log("time",e)},r.warn=function(e){r.log("warn",e)},r.error=function(e){r.log("error",e)},r.log=function(e,t){r.addMessage(e,t);var n=this.messages[this.nbMessages-1];this._level.id<=n.getLevelId()&&n.display()},r.addMessage=function(e,t){this.messages.push(new l(e,t)),this.nbMessages++},r.findLevel=function(e){var t=a,n=Array.isArray(t),r=0;for(t=n?t:t[Symbol.iterator]();;){var i;if(n){if(r>=t.length)break;i=t[r++]}else{if((r=t.next()).done)break;i=r.value}var o=i;if(o.name===e)return o}return this._level?this._level:a[0]},t(r,[{key:"level",set:function(e){r._level=r.findLevel(e)},get:function(){return r._level.name}}]),r}();c._level=c.findLevel(a[0].name),c.messages=[],c.nbMessages=0,c.target=document.getElementById("Mouette");var f=function(){function e(){}return e.scrollToBottom=function(e){e.scrollTop=e.scrollHeight},e.scrollToTop=function(e){e.scrollTop=0},e.findById=function(e){return document.getElementById(e)},e.findByClass=function(e){return this.arrayFrom(document.getElementsByClassName(e))},e.findByTag=function(e){return this.arrayFrom(document.getElementsByTagName(e))},e.showElement=function(e){return this.styleElement(e,"display","block")},e.hideElement=function(e){return this.styleElement(e,"display","none")},e.styleElement=function(e,t,n){return(e=this.checkElement(e))&&(e.style[t]=n),e},e.showOverflow=function(){document.body.style.overflow="visible"},e.hideOverflow=function(){document.body.style.overflow="hidden"},e.getInputValue=function(e){return(e=this.checkElement(e))?e.value:null},e.clearInputValue=function(e){return(e=this.checkElement(e))&&(e.value=""),e},e.focusOn=function(e){return(e=this.checkElement(e))&&e.focus(),e},e.addHTMLElement=function(e,t,n){e=this.checkElement(e);var r=document.createElement(t);return n&&Object.keys(n).forEach(function(e){"textContent"===e||"innerHTML"===e?r[e]=n[e]:r.setAttribute(e,n[e])}),e.appendChild(r),r},e.clearHTMLElement=function(e){return(e=this.checkElement(e))&&(e.innerHTML=""),e},e.arrayFrom=function(e){for(var t=[],n=0;n=r.length)break;s=r[o++]}else{if((o=r.next()).done)break;s=o.value}if(!u(s))return!1}e||(e="export"),n&&this.setOptions(n);var a="data:"+this.options.data+";charset="+this.options.charset+",\ufeff",l=[];return l=this.options.customLabels?this.createCustomLabels(this.options.customLabels):this.createLabels(t),this.options.labels&&(a+=this.createLabelsRow(l)),a+=this.createTable(t),this.download(a,e),!0},e.setOptions=function(e){for(var t in e)e.hasOwnProperty(t)&&this.options.hasOwnProperty(t)&&(this.options[t]=e[t]||this.options[t])},e.download=function(e,t){if(window.navigator.msSaveOrOpenBlob)window.navigator.msSaveOrOpenBlob(e,t);else{var n=f.addHTMLElement(document.body,"a",{href:e,download:t+".csv"});n.click(),document.body.removeChild(n)}},e.createTable=function(e){var t="",n=e,r=Array.isArray(n),i=0;for(n=r?n:n[Symbol.iterator]();;){var o;if(r){if(i>=n.length)break;o=n[i++]}else{if((i=n.next()).done)break;o=i.value}var s=o,a="";for(var l in this.options.customLabels)a+=this.createField(s[l]||"");t+=this.createRow(a)}return t},e.createLabels=function(e){var n=[],t=e,r=Array.isArray(t),i=0;for(t=r?t:t[Symbol.iterator]();;){var o;if(r){if(i>=t.length)break;o=t[i++]}else{if((i=t.next()).done)break;o=i.value}var s=o,a=0,l=function(t){s.hasOwnProperty(t)&&(n.find(function(e){return e===t})||n.splice(a,0,t),a++)};for(var u in s)l(u)}this.options.customLabels={};for(var c=0,f=n;c=n.length)break;o=n[i++]}else{if((i=n.next()).done)break;o=i.value}var s=o;t+=this.createField(s)}return this.createRow(t)},e.createRow=function(e){return e.slice(0,-1)+this.options.CRLF},e.createField=function(e){return this.options.quote+e+this.options.quote+this.options.separator},e}();h.options={data:"text/csv",charset:"utf-8",labels:!0,quote:'"',separator:",",CRLF:"\r\n",customLabels:null};var v=function(){function e(){}return e.setOptions=function(e){this.setObject("options",e)},e.setCSS=function(e){this.setObject("css",e)},e.array=function(e,t,n){t&&this.setOptions(t),n&&this.setCSS(n);var r=e.trim().split(this.options.CRLF).filter(Boolean);if(!r.length)return!1;var i=[],o=r,s=Array.isArray(o),a=0;for(o=s?o:o[Symbol.iterator]();;){var l;if(s){if(a>=o.length)break;l=o[a++]}else{if((a=o.next()).done)break;l=a.value}var u=l.split(this.options.separator);if(this.options.quote)for(var c=0;c"):o.push(this.createTr(r[s],a,""))}if(i||o.length)return""+i+""+o.join("")+"
"}return!1},e.createTr=function(e,t,n){return"<"+t+n+">"+e.join("<"+t+n+">")+""},e.setObject=function(e,t){for(var n in t)t.hasOwnProperty(n)&&this[e].hasOwnProperty(n)&&(this[e][n]=t[n])},e}();return v.options={labels:!0,quote:'"',separator:",",CRLF:"\r\n"},v.css={table:"",th:""},e.Export=h,e.Convert=v,e}({}); \ No newline at end of file diff --git a/dist/csvx.js b/dist/csvx.js index af3f2b2..db4d89f 100644 --- a/dist/csvx.js +++ b/dist/csvx.js @@ -24,13 +24,16 @@ */ import { Dom } from '@lcluber/weejs'; -import { Is } from '@lcluber/chjs'; -import { Logger } from '@lcluber/mouettejs'; +import { isObject } from '@lcluber/chjs'; +// import { Logger } from '@lcluber/mouettejs'; class Export { static data(filename, data, options) { - if (!Is.object(data[0]) && !Is.json(data[0])) { - return false; + // check data consistency + for (let row of data) { + if (!isObject(row)) { + return false; + } } if (!filename) { filename = 'export'; @@ -39,17 +42,20 @@ class Export { this.setOptions(options); } let table = 'data:' + this.options.data + ';charset=' + this.options.charset + ',\uFEFF'; + let labels = []; + if (!this.options.customLabels) { + labels = this.createLabels(data); + } + else { + labels = this.createCustomLabels(this.options.customLabels); + } if (this.options.labels) { - if (this.options.customLabels.length > 0) { - table += this.createCustomLabels(this.options.customLabels); - } - else { - table += this.createLabels(data); - } - this.log.info(filename + ' labels ready'); + table += this.createLabelsRow(labels); + // this.log.info(filename + ' labels ready'); } table += this.createTable(data); - this.log.info(filename + ' table ready'); + // console.log('table', table); + // this.log.info(filename + ' table ready'); this.download(table, filename); return true; } @@ -70,52 +76,65 @@ class Export { let link = Dom.addHTMLElement(document.body, 'a', { href: table, download: filename + '.csv' }); link.click(); document.body.removeChild(link); - this.log.info(filename + ' downloading'); + // this.log.info(filename + ' downloading'); } } static createTable(data) { let table = ''; - for (const row of data) { - let obj = Is.json(row) || row; - if (!Is.object(obj)) { - return table; - } + for (let row of data) { let parsedRow = ''; - for (const property in obj) { - if (obj.hasOwnProperty(property)) { - parsedRow += this.createField(obj[property]); - } + for (let property in this.options.customLabels) { + parsedRow += this.createField(row[property] || ''); } table += this.createRow(parsedRow); } - return encodeURIComponent(table); + return table; } static createLabels(data) { - let labels = Is.json(data[0]) || data[0]; - let parsedRow = ''; - for (const label in labels) { - if (labels.hasOwnProperty(label)) { - parsedRow += this.createField(label); + let params = []; + for (let row of data) { + let i = 0; + for (let property in row) { + if (row.hasOwnProperty(property)) { + const newProperty = params.find(value => value === property); + if (!newProperty) { + params.splice(i, 0, property); + } + i++; + } } } - return this.createRow(parsedRow); + this.options.customLabels = {}; + for (let param of params) { + this.options.customLabels[param] = param; + } + return params; } static createCustomLabels(customLabels) { + let params = []; + for (let property in customLabels) { + if (customLabels.hasOwnProperty(property)) { + params.push(customLabels[property]); + } + } + return params; + } + static createLabelsRow(labels) { let parsedRow = ''; - for (const label of customLabels) { + for (let label of labels) { parsedRow += this.createField(label); } return this.createRow(parsedRow); } static createRow(row) { - console.log(row.slice(0, -1) + this.options.CRLF); + // console.log(row.slice(0, -1) + this.options.CRLF); return row.slice(0, -1) + this.options.CRLF; } static createField(content) { return this.options.quote + content + this.options.quote + this.options.separator; } } -Export.log = Logger.addGroup('CSVx Exporter'); +// static log = Logger.addGroup('CSVx Exporter'); // default option values Export.options = { data: 'text/csv', @@ -124,7 +143,7 @@ Export.options = { quote: '"', separator: ',', CRLF: '\r\n', - customLabels: [] + customLabels: null }; class Convert { @@ -143,7 +162,7 @@ class Convert { } let rows = data.trim().split(this.options.CRLF).filter(Boolean); if (!rows.length) { - this.log.warn(this.options.CRLF + ' CRLF not found'); + // this.log.warn(this.options.CRLF + ' CRLF not found'); return false; } let array = []; @@ -195,7 +214,7 @@ class Convert { } } } -Convert.log = Logger.addGroup('CSVx Converter'); +// static log = Logger.addGroup('CSVx Converter'); // static html: string = null; // default option values Convert.options = { diff --git a/package.json b/package.json index 5bf34f7..6a06f33 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lcluber/csvxjs", - "version": "0.1.10", + "version": "0.2.0", "description": "CSV Export library written in TypeScript.", "keywords": [], "homepage": "http://csvxjs.lcluber.com", @@ -39,8 +39,7 @@ "pug": "2.0.3", "serve-favicon": "2.5.0", "@lcluber/weejs": "0.2.7", - "@lcluber/chjs": "0.1.1", - "@lcluber/mouettejs": "0.3.0" + "@lcluber/chjs": "2.12.0" }, "devDependencies": { "@babel/core": "7.2.2", @@ -64,13 +63,13 @@ "grunt-nodemon": "0.4.2", "grunt-open": "0.2.3", "grunt-rollup": "9.0.0", - "grunt-sass": "3.0.2", + "grunt-sass": "3.1.0", "grunt-strip-code": "1.0.6", "grunt-ts": "6.0.0-beta.22", "grunt-typedoc": "0.2.4", "jquery": "3.2.1", "jquery-easing": "0.0.1", - "node-sass": "4.11.0", + "node-sass": "4.13.1", "rollup-plugin-babel": "4.1.0", "rollup-plugin-node-resolve": "4.0.0", "semantic-release": "15.13.24", diff --git a/src/ts/convert.ts b/src/ts/convert.ts index 58e8f8a..073557c 100644 --- a/src/ts/convert.ts +++ b/src/ts/convert.ts @@ -1,11 +1,11 @@ import { Options, CSS } from './interfaces'; -import { Logger } from '@lcluber/mouettejs'; +// import { Logger } from '@lcluber/mouettejs'; export type CellTypes = 'td'|'th'; export class Convert { - static log = Logger.addGroup('CSVx Converter'); + // static log = Logger.addGroup('CSVx Converter'); // static html: string = null; // default option values static options: Partial = { @@ -41,7 +41,7 @@ export class Convert { let rows:Array = data.trim().split(this.options.CRLF).filter(Boolean); if (!rows.length) { - this.log.warn(this.options.CRLF + ' CRLF not found'); + // this.log.warn(this.options.CRLF + ' CRLF not found'); return false; } diff --git a/src/ts/export.ts b/src/ts/export.ts index 844304c..0887a21 100644 --- a/src/ts/export.ts +++ b/src/ts/export.ts @@ -1,11 +1,11 @@ -import { Options } from './interfaces'; -import { Dom } from '@lcluber/weejs'; -import { Is } from '@lcluber/chjs'; -import { Logger } from '@lcluber/mouettejs'; +import { Options, Data } from './interfaces'; +import { Dom } from '@lcluber/weejs'; +import { isObject } from '@lcluber/chjs'; +// import { Logger } from '@lcluber/mouettejs'; export class Export { - static log = Logger.addGroup('CSVx Exporter'); + // static log = Logger.addGroup('CSVx Exporter'); // default option values static options: Options = { data: 'text/csv', @@ -14,16 +14,21 @@ export class Export { quote: '"', separator: ',', CRLF : '\r\n', - customLabels: [] + customLabels: null } public static data( filename: string, - data: Object[]|string[], - options?: Partial): boolean { - - if (!Is.object(data[0]) && !Is.json(data[0])) { - return false; + data: Data[], + options?: Partial + ): boolean { + + // check data consistency + for (let row of data) { + if (!isObject(row)) { + return false; + } } + if (!filename) { filename = 'export'; } @@ -31,16 +36,19 @@ export class Export { this.setOptions(options); } let table: string = 'data:' + this.options.data + ';charset=' + this.options.charset + ',\uFEFF'; + let labels: string[] = []; + if (!this.options.customLabels) { + labels = this.createLabels(data); + } else { + labels = this.createCustomLabels(this.options.customLabels); + } if(this.options.labels) { - if (this.options.customLabels.length > 0) { - table += this.createCustomLabels(this.options.customLabels); - } else { - table += this.createLabels(data); - } - this.log.info(filename + ' labels ready'); + table += this.createLabelsRow(labels); + // this.log.info(filename + ' labels ready'); } table += this.createTable(data); - this.log.info(filename + ' table ready'); + // console.log('table', table); + // this.log.info(filename + ' table ready'); this.download(table, filename); return true; } @@ -62,53 +70,67 @@ export class Export { let link = Dom.addHTMLElement(document.body, 'a', {href:table,download:filename+'.csv'}) link.click(); document.body.removeChild(link); - this.log.info(filename + ' downloading'); + // this.log.info(filename + ' downloading'); } } - private static createTable( data: Object[]|string[] ): string { + private static createTable( data: Data[] ): string { let table: string = ''; - for (const row of data) { - let obj:any = Is.json(row)||row; - if (!Is.object(obj)){ - return table; - } + for (let row of data) { let parsedRow: string = ''; - for(const property in obj) { - if (obj.hasOwnProperty(property)) { - parsedRow += this.createField(obj[property]); - } + for (let property in this.options.customLabels) { + parsedRow += this.createField(row[property] || ''); } table += this.createRow(parsedRow); } - return encodeURIComponent(table); + return table; } - private static createLabels( data: Object[]|string[] ): string { - let labels:Object = Is.json(data[0])||data[0]; - let parsedRow: string = ''; - for(const label in labels) { - if (labels.hasOwnProperty(label)) { - parsedRow += this.createField(label); + private static createLabels (data: Data[]): string[] { + let params: string[] = []; + for (let row of data) { + let i = 0; + for (let property in row) { + if (row.hasOwnProperty(property)) { + const newProperty = params.find(value => value === property); + if (!newProperty) { + params.splice(i, 0, property); + } + i++; + } } } - return this.createRow(parsedRow); + this.options.customLabels = {}; + for (let param of params) { + this.options.customLabels[param] = param; + } + return params; + } + + private static createCustomLabels (customLabels: { [key: string]: string }): string[] { + let params: string[] = []; + for (let property in customLabels) { + if (customLabels.hasOwnProperty(property)) { + params.push(customLabels[property]); + } + } + return params; } - private static createCustomLabels(customLabels: string[]): string { + private static createLabelsRow(labels: string[]): string { let parsedRow: string = ''; - for(const label of customLabels) { + for(let label of labels) { parsedRow += this.createField(label); } return this.createRow(parsedRow); } private static createRow(row: string): string { - console.log(row.slice(0, -1) + this.options.CRLF); + // console.log(row.slice(0, -1) + this.options.CRLF); return row.slice(0, -1) + this.options.CRLF; } - private static createField(content:string): string { + private static createField(content:string|number): string { return this.options.quote + content + this.options.quote + this.options.separator; } diff --git a/src/ts/interfaces.ts b/src/ts/interfaces.ts index 571804c..ead4dcc 100644 --- a/src/ts/interfaces.ts +++ b/src/ts/interfaces.ts @@ -6,8 +6,8 @@ export interface Options { quote: string; separator: string; CRLF: string; - customLabels: string[]; - [key: string]: string[]|String|boolean; + customLabels: { [key: string]: string }|null; + [key: string]: string[]|String|boolean|{ [key: string]: string }|null; } export interface CSS { @@ -15,3 +15,5 @@ export interface CSS { th: string; [key: string]: String; } + +export interface Data { [key: string]: number|string } \ No newline at end of file diff --git a/web/js/example.js b/web/js/example.js index 60c9d7c..7c0bf52 100644 --- a/web/js/example.js +++ b/web/js/example.js @@ -1,4 +1,4 @@ - +var customLabels = ['First name', 'Last name', 'city', 'Born', 'Died']; var array = [ { firstname:'Galileo', @@ -9,20 +9,27 @@ var array = [ { firstname:'Nikola', lastname:'Tesla', + city:'Smiljan', born:1856, died:1943 }, { firstname:'Albert', - lastname:'Einstein', born:1879, + lastname:'Einstein', died:1955 } ]; -var customLabels = ['First name', 'Last name', 'Born', 'Died']; +var customLabels = { + firstname: 'First name', + lastname: 'Last name', + city: 'City', + born: 'Born', + died: 'Died' +}; var exportButton = Wee.Dom.findById('csv'); exportButton.addEventListener('click', function() { - CSVx.Export.data('scientists',array, {separator:';', customLabels: customLabels}); + CSVx.Export.data('scientists',array, {separator:';', customLabels: customLabels }); }); var data = '"Firstname";"Lastname";"Born";"Died"\r\n\ diff --git a/web/public/js/main.min.js b/web/public/js/main.min.js index b490238..67e9f6b 100644 --- a/web/public/js/main.min.js +++ b/web/public/js/main.min.js @@ -12,4 +12,4 @@ null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio" * Licensed under the MIT license */ if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>3)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){if(a(b.target).is(this))return b.handleObj.handler.apply(this,arguments)}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.7",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a("#"===f?[]:f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.7",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c).prop(c,!0)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c).prop(c,!1))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target).closest(".btn");b.call(d,"toggle"),a(c.target).is('input[type="radio"], input[type="checkbox"]')||(c.preventDefault(),d.is("input,button")?d.trigger("focus"):d.find("input:visible,button:visible").first().trigger("focus"))}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));if(!(a>this.$items.length-1||a<0))return this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){if(!this.sliding)return this.slide("next")},c.prototype.prev=function(){if(!this.sliding)return this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.7",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.7",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);if(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),!c.isInStateTrue())return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null,a.$element=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.7",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.7",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.7",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return e=a-d&&"bottom"},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);var Wee=function(e){"use strict";function i(e,n){for(var t=0;t=t.length)break;o=t[i++]}else{if((i=t.next()).done)break;o=i.value}if(e===o)return!0}return!1},e}(),f=function(){function e(){}return e.load=function(r){return new Promise(function(e,n){var t=new Image;t.src=r,t.name=l.getName(r),s.info("xhr processing starting ("+r+")"),t.addEventListener("load",function(){s.info("xhr done successfully ("+r+")"),e(t)}),t.addEventListener("error",function(){s.error("xhr failed ("+r+")"),n(new Error("xhr failed ("+r+")"))})})},e}(),h=function(){function e(){}return e.load=function(r){return new Promise(function(e,n){var t=new Audio;t.src=r,s.info("xhr processing starting ("+r+")"),t.addEventListener("canplaythrough",function(){s.info("xhr done successfully ("+r+")"),e(t)},!1),t.addEventListener("canplay",function(){s.info("xhr done successfully ("+r+")"),e(t)},!1),t.addEventListener("error",function(){s.error("xhr failed ("+r+")"),n(new Error("xhr failed ("+r+")"))},!1)})},e}();return e.Dom=n,e.Bind=t,e.String=r,e.File=l,e.Img=f,e.Sound=h,e}({});function collapseNavbar(){50<$(".navbar").offset().top?$(".navbar-fixed-top").addClass("top-nav-collapse"):$(".navbar-fixed-top").removeClass("top-nav-collapse")}jQuery.easing.jswing=jQuery.easing.swing,jQuery.extend(jQuery.easing,{def:"easeOutQuad",swing:function(e,t,n,a,r){return jQuery.easing[jQuery.easing.def](e,t,n,a,r)},easeInQuad:function(e,t,n,a,r){return a*(t/=r)*t+n},easeOutQuad:function(e,t,n,a,r){return-a*(t/=r)*(t-2)+n},easeInOutQuad:function(e,t,n,a,r){return(t/=r/2)<1?a/2*t*t+n:-a/2*(--t*(t-2)-1)+n},easeInCubic:function(e,t,n,a,r){return a*(t/=r)*t*t+n},easeOutCubic:function(e,t,n,a,r){return a*((t=t/r-1)*t*t+1)+n},easeInOutCubic:function(e,t,n,a,r){return(t/=r/2)<1?a/2*t*t*t+n:a/2*((t-=2)*t*t+2)+n},easeInQuart:function(e,t,n,a,r){return a*(t/=r)*t*t*t+n},easeOutQuart:function(e,t,n,a,r){return-a*((t=t/r-1)*t*t*t-1)+n},easeInOutQuart:function(e,t,n,a,r){return(t/=r/2)<1?a/2*t*t*t*t+n:-a/2*((t-=2)*t*t*t-2)+n},easeInQuint:function(e,t,n,a,r){return a*(t/=r)*t*t*t*t+n},easeOutQuint:function(e,t,n,a,r){return a*((t=t/r-1)*t*t*t*t+1)+n},easeInOutQuint:function(e,t,n,a,r){return(t/=r/2)<1?a/2*t*t*t*t*t+n:a/2*((t-=2)*t*t*t*t+2)+n},easeInSine:function(e,t,n,a,r){return-a*Math.cos(t/r*(Math.PI/2))+a+n},easeOutSine:function(e,t,n,a,r){return a*Math.sin(t/r*(Math.PI/2))+n},easeInOutSine:function(e,t,n,a,r){return-a/2*(Math.cos(Math.PI*t/r)-1)+n},easeInExpo:function(e,t,n,a,r){return 0==t?n:a*Math.pow(2,10*(t/r-1))+n},easeOutExpo:function(e,t,n,a,r){return t==r?n+a:a*(1-Math.pow(2,-10*t/r))+n},easeInOutExpo:function(e,t,n,a,r){return 0==t?n:t==r?n+a:(t/=r/2)<1?a/2*Math.pow(2,10*(t-1))+n:a/2*(2-Math.pow(2,-10*--t))+n},easeInCirc:function(e,t,n,a,r){return-a*(Math.sqrt(1-(t/=r)*t)-1)+n},easeOutCirc:function(e,t,n,a,r){return a*Math.sqrt(1-(t=t/r-1)*t)+n},easeInOutCirc:function(e,t,n,a,r){return(t/=r/2)<1?-a/2*(Math.sqrt(1-t*t)-1)+n:a/2*(Math.sqrt(1-(t-=2)*t)+1)+n},easeInElastic:function(e,t,n,a,r){var u=1.70158,i=0,s=a;if(0==t)return n;if(1==(t/=r))return n+a;if(i||(i=.3*r),s .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.7",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return e=a-d&&"bottom"},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);var Wee=function(e){"use strict";function i(e,n){for(var t=0;t=t.length)break;o=t[i++]}else{if((i=t.next()).done)break;o=i.value}if(e===o)return!0}return!1},e}(),f=function(){function e(){}return e.load=function(r){return new Promise(function(e,n){var t=new Image;t.src=r,t.name=l.getName(r),s.info("xhr processing starting ("+r+")"),t.addEventListener("load",function(){s.info("xhr done successfully ("+r+")"),e(t)}),t.addEventListener("error",function(){s.error("xhr failed ("+r+")"),n(new Error("xhr failed ("+r+")"))})})},e}(),h=function(){function e(){}return e.load=function(r){return new Promise(function(e,n){var t=new Audio;t.src=r,s.info("xhr processing starting ("+r+")"),t.addEventListener("canplaythrough",function(){s.info("xhr done successfully ("+r+")"),e(t)},!1),t.addEventListener("canplay",function(){s.info("xhr done successfully ("+r+")"),e(t)},!1),t.addEventListener("error",function(){s.error("xhr failed ("+r+")"),n(new Error("xhr failed ("+r+")"))},!1)})},e}();return e.Dom=n,e.Bind=t,e.String=r,e.File=l,e.Img=f,e.Sound=h,e}({});function collapseNavbar(){50<$(".navbar").offset().top?$(".navbar-fixed-top").addClass("top-nav-collapse"):$(".navbar-fixed-top").removeClass("top-nav-collapse")}jQuery.easing.jswing=jQuery.easing.swing,jQuery.extend(jQuery.easing,{def:"easeOutQuad",swing:function(e,t,n,a,r){return jQuery.easing[jQuery.easing.def](e,t,n,a,r)},easeInQuad:function(e,t,n,a,r){return a*(t/=r)*t+n},easeOutQuad:function(e,t,n,a,r){return-a*(t/=r)*(t-2)+n},easeInOutQuad:function(e,t,n,a,r){return(t/=r/2)<1?a/2*t*t+n:-a/2*(--t*(t-2)-1)+n},easeInCubic:function(e,t,n,a,r){return a*(t/=r)*t*t+n},easeOutCubic:function(e,t,n,a,r){return a*((t=t/r-1)*t*t+1)+n},easeInOutCubic:function(e,t,n,a,r){return(t/=r/2)<1?a/2*t*t*t+n:a/2*((t-=2)*t*t+2)+n},easeInQuart:function(e,t,n,a,r){return a*(t/=r)*t*t*t+n},easeOutQuart:function(e,t,n,a,r){return-a*((t=t/r-1)*t*t*t-1)+n},easeInOutQuart:function(e,t,n,a,r){return(t/=r/2)<1?a/2*t*t*t*t+n:-a/2*((t-=2)*t*t*t-2)+n},easeInQuint:function(e,t,n,a,r){return a*(t/=r)*t*t*t*t+n},easeOutQuint:function(e,t,n,a,r){return a*((t=t/r-1)*t*t*t*t+1)+n},easeInOutQuint:function(e,t,n,a,r){return(t/=r/2)<1?a/2*t*t*t*t*t+n:a/2*((t-=2)*t*t*t*t+2)+n},easeInSine:function(e,t,n,a,r){return-a*Math.cos(t/r*(Math.PI/2))+a+n},easeOutSine:function(e,t,n,a,r){return a*Math.sin(t/r*(Math.PI/2))+n},easeInOutSine:function(e,t,n,a,r){return-a/2*(Math.cos(Math.PI*t/r)-1)+n},easeInExpo:function(e,t,n,a,r){return 0==t?n:a*Math.pow(2,10*(t/r-1))+n},easeOutExpo:function(e,t,n,a,r){return t==r?n+a:a*(1-Math.pow(2,-10*t/r))+n},easeInOutExpo:function(e,t,n,a,r){return 0==t?n:t==r?n+a:(t/=r/2)<1?a/2*Math.pow(2,10*(t-1))+n:a/2*(2-Math.pow(2,-10*--t))+n},easeInCirc:function(e,t,n,a,r){return-a*(Math.sqrt(1-(t/=r)*t)-1)+n},easeOutCirc:function(e,t,n,a,r){return a*Math.sqrt(1-(t=t/r-1)*t)+n},easeInOutCirc:function(e,t,n,a,r){return(t/=r/2)<1?-a/2*(Math.sqrt(1-t*t)-1)+n:a/2*(Math.sqrt(1-(t-=2)*t)+1)+n},easeInElastic:function(e,t,n,a,r){var u=1.70158,i=0,s=a;if(0==t)return n;if(1==(t/=r))return n+a;if(i||(i=.3*r),s