alasql 2.2.5 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
- //! AlaSQL v2.2.4-develop-d97ae856 | © 2014-2022 Andrey Gershun & Mathias Wulff | License: MIT
1
+ //! AlaSQL v2.2.5-develop-63c84c04 | © 2014-2022 Andrey Gershun & Mathias Wulff | License: MIT
2
2
  /*
3
3
  @module alasql
4
- @version 2.2.4-develop-d97ae856
4
+ @version 2.2.5-develop-63c84c04
5
5
 
6
6
  AlaSQL - JavaScript SQL database
7
7
  © 2014-2016 Andrey Gershun & Mathias Rangel Wulff
@@ -1,2 +1,2 @@
1
- //! AlaSQL v2.2.4-develop-d97ae856 | © 2014-2022 Andrey Gershun & Mathias Wulff | License: MIT
1
+ //! AlaSQL v2.2.5-develop-63c84c04 | © 2014-2022 Andrey Gershun & Mathias Wulff | License: MIT
2
2
  !function(r,e){"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?module.exports=e():r.alasql=e()}(this,function(){function i(r,e,o){"function"==typeof(e=e||[])&&(scope=o,o=e,e=[]),"object"!=typeof e&&(e=[e]);var t=i.lastid++;i.buffer[t]=o,i.webworker.postMessage({id:t,sql:r,params:e})}var a;if(i.options={},i.options.progress=function(){},isArray=function(r){return"[object Array]"===Object.prototype.toString.call(r)},i.promise=function(){throw new Error("Please include a Promise/A+ library")},"undefined"!=typeof Promise&&(a=function(r,e,n,s){return new Promise(function(o,t){i(r,e,function(r,e){e?t(e):(n&&s&&!1!==i.options.progress&&i.options.progress(n,s),o(r))})})},i.promise=function(r,e){if("undefined"==typeof Promise)throw new Error("Please include a Promise/A+ library");if("string"==typeof r)return a(r,e);if(!isArray(r)||r.length<1||void 0!==e)throw new Error("Error in .promise parameters");var o=r;if(!(o.length<1)){for(var t,n,s=[],i=0;i<o.length;i++){if("string"==typeof(n=o[i])&&(n=[n]),!isArray(n)||n.length<1||2<n.length)throw new Error("Error in .promise parameter");t=n[0],n=n[1]||void 0,s.push(a(t,n,i,o.length))}return Promise.all(s)}}),i=i||!1)return i.worker=function(){throw new Error("Can find webworker in this enviroment")},"undefined"!=typeof Worker&&(i.worker=function(r,e,o){if(void 0===(r=!0===r?void 0:r))for(var t=document.getElementsByTagName("script"),n=0;n<t.length;n++){if("alasql-worker.js"===t[n].src.substr(-16).toLowerCase()){r=t[n].src.substr(0,t[n].src.length-16)+"alasql.js";break}if("alasql-worker.min.js"===t[n].src.substr(-20).toLowerCase()){r=t[n].src.substr(0,t[n].src.length-20)+"alasql.min.js";break}if("alasql.js"===t[n].src.substr(-9).toLowerCase()){r=t[n].src;break}if("alasql.min.js"===t[n].src.substr(-13).toLowerCase()){r=t[n].src.substr(0,t[n].src.length-13)+"alasql.min.js";break}}if(void 0===r)throw new Error("Path to alasql.js is not specified");var s;!1!==r?(s=(s="importScripts('")+r+"');self.onmessage = function(event) {alasql(event.data.sql,event.data.params, function(data){postMessage({id:event.data.id, data:data});});}",s=new Blob([s],{type:"text/plain"}),i.webworker=new Worker(URL.createObjectURL(s)),i.webworker.onmessage=function(r){var e=r.data.id;i.buffer[e](r.data.data),delete i.buffer[e]},i.webworker.onerror=function(r){throw r},1<arguments.length&&i("REQUIRE "+e.map(function(r){return'"'+r+'"'}).join(","),[],o)):!1===r&&delete i.webworker}),i.lastid=0,i.buffer={},i.worker(),i;throw new Error("alasql was not found")});
package/dist/alasql.fs.js CHANGED
@@ -1,7 +1,7 @@
1
- //! AlaSQL v2.2.4-develop-d97ae856 | © 2014-2022 Andrey Gershun & Mathias Wulff | License: MIT
1
+ //! AlaSQL v2.2.5-develop-63c84c04 | © 2014-2022 Andrey Gershun & Mathias Wulff | License: MIT
2
2
  /*
3
3
  @module alasql
4
- @version 2.2.4-develop-d97ae856
4
+ @version 2.2.5-develop-63c84c04
5
5
 
6
6
  AlaSQL - JavaScript SQL database
7
7
  © 2014-2016 Andrey Gershun & Mathias Rangel Wulff
@@ -142,7 +142,7 @@ var alasql = function(sql, params, cb, scope) {
142
142
  Current version of alasql
143
143
  @constant {string}
144
144
  */
145
- alasql.version = '2.2.4-develop-d97ae856';
145
+ alasql.version = '2.2.5-develop-63c84c04';
146
146
 
147
147
  /**
148
148
  Debug flag
@@ -3484,19 +3484,7 @@ var loadFile = (utils.loadFile = function (path, asy, success, error) {
3484
3484
  });
3485
3485
  } else {
3486
3486
  if (/^[a-z]+:\/\//i.test(path)) {
3487
- var fetch = require('node-fetch');
3488
- fetch(path)
3489
- .then((response) => response.arrayBuffer())
3490
- .then((buf) => {
3491
- var a = new Uint8Array(buf);
3492
- var b = [...a].map((e) => String.fromCharCode(e)).join('');
3493
- success(cutbom(b));
3494
- })
3495
- .catch((e) => {
3496
- if (error) return error(e);
3497
- console.error(e);
3498
- throw e;
3499
- });
3487
+ fetchData(path, (x) => success(cutbom(x)), error, asy);
3500
3488
  } else {
3501
3489
  //If async callthen call async
3502
3490
  if (asy) {
@@ -3559,21 +3547,7 @@ var loadFile = (utils.loadFile = function (path, asy, success, error) {
3559
3547
  Simply read file from HTTP request, like:
3560
3548
  SELECT * FROM TXT('http://alasql.org/README.md');
3561
3549
  */
3562
- var xhr = new XMLHttpRequest();
3563
- xhr.onreadystatechange = function () {
3564
- if (xhr.readyState === 4) {
3565
- if (xhr.status === 200) {
3566
- if (success) {
3567
- success(cutbom(xhr.responseText));
3568
- }
3569
- } else if (error) {
3570
- return error(xhr);
3571
- }
3572
- // Todo: else...?
3573
- }
3574
- };
3575
- xhr.open('GET', path, asy); // Async
3576
- xhr.send();
3550
+ fetchData(path, (x) => success(cutbom(x)), error, asy);
3577
3551
  }
3578
3552
  } else if (path instanceof Event) {
3579
3553
  /*
@@ -3600,6 +3574,33 @@ var loadFile = (utils.loadFile = function (path, asy, success, error) {
3600
3574
  }
3601
3575
  });
3602
3576
 
3577
+ let _fetch = typeof fetch !== 'undefined' ? fetch : null;
3578
+ //*not-for-browser/*
3579
+ _fetch = typeof fetch !== 'undefined' ? fetch : require('cross-fetch');
3580
+ //*/
3581
+
3582
+ async function fetchData(path, success, error, async) {
3583
+ if (async) {
3584
+ return getData(path, success, error);
3585
+ }
3586
+ return await getData(path, success, error);
3587
+ }
3588
+
3589
+ function getData(path, success, error) {
3590
+ return _fetch(path)
3591
+ .then((response) => response.arrayBuffer())
3592
+ .then((buf) => {
3593
+ var a = new Uint8Array(buf);
3594
+ var b = [...a].map((e) => String.fromCharCode(e)).join('');
3595
+ success(b);
3596
+ })
3597
+ .catch((e) => {
3598
+ if (error) return error(e);
3599
+ console.error(e);
3600
+ throw e;
3601
+ });
3602
+ }
3603
+
3603
3604
  /**
3604
3605
  @function Load binary file from anywhere
3605
3606
  @param {string} path File path
@@ -3625,19 +3626,7 @@ var loadBinaryFile = (utils.loadBinaryFile = function (
3625
3626
  fs = require('fs');
3626
3627
 
3627
3628
  if (/^[a-z]+:\/\//i.test(path)) {
3628
- var fetch = require('node-fetch');
3629
- fetch(path)
3630
- .then((response) => response.arrayBuffer())
3631
- .then((buf) => {
3632
- var a = new Uint8Array(buf);
3633
- var b = [...a].map((e) => String.fromCharCode(e)).join('');
3634
- success(b);
3635
- })
3636
- .catch((e) => {
3637
- if (error) return error(e);
3638
- console.error(e);
3639
- throw e;
3640
- });
3629
+ fetchData(path, success, error, runAsync);
3641
3630
  } else {
3642
3631
  if (runAsync) {
3643
3632
  fs.readFile(path, function (err, data) {
@@ -3870,30 +3859,14 @@ var saveFile = (utils.saveFile = function (path, data, cb, opts) {
3870
3859
  // });
3871
3860
  // });
3872
3861
  } else {
3873
- if (isIE() === 9) {
3874
- // Solution was taken from
3875
- // http://megatuto.com/formation-JAVASCRIPT.php?JAVASCRIPT_Example=Javascript+Save+CSV+file+in+IE+8/IE+9+without+using+window.open()+Categorie+javascript+internet-explorer-8&category=&article=7993
3876
- // var URI = 'data:text/plain;charset=utf-8,';
3877
-
3878
- // Prepare data
3879
- var ndata = data.replace(/\r\n/g, '&#A;&#D;');
3880
- ndata = ndata.replace(/\n/g, '&#D;');
3881
- ndata = ndata.replace(/\t/g, '&#9;');
3882
- var testlink = utils.global.open('about:blank', '_blank');
3883
- testlink.document.write(ndata); //fileData has contents for the file
3884
- testlink.document.close();
3885
- testlink.document.execCommand('SaveAs', false, path);
3886
- testlink.close();
3887
- } else {
3888
- var opt = {
3889
- disableAutoBom: false,
3890
- };
3891
- alasql.utils.extend(opt, opts);
3892
- var blob = new Blob([data], {type: 'text/plain;charset=utf-8'});
3893
- saveAs(blob, path, opt.disableAutoBom);
3894
- if (cb) {
3895
- res = cb(res);
3896
- }
3862
+ var opt = {
3863
+ disableAutoBom: false,
3864
+ };
3865
+ alasql.utils.extend(opt, opts);
3866
+ var blob = new Blob([data], {type: 'text/plain;charset=utf-8'});
3867
+ saveAs(blob, path, opt.disableAutoBom);
3868
+ if (cb) {
3869
+ res = cb(res);
3897
3870
  }
3898
3871
  }
3899
3872
  }
@@ -3901,17 +3874,6 @@ var saveFile = (utils.saveFile = function (path, data, cb, opts) {
3901
3874
  return res;
3902
3875
  });
3903
3876
 
3904
- /**
3905
- @function Is this IE9
3906
- @return {boolean} True for IE9 and false for other browsers
3907
-
3908
- For IE9 compatibility issues
3909
- */
3910
- function isIE() {
3911
- var myNav = navigator.userAgent.toLowerCase();
3912
- return myNav.indexOf('msie') !== -1 ? parseInt(myNav.split('msie')[1]) : false;
3913
- }
3914
-
3915
3877
  /**
3916
3878
  @function Hash a string to signed integer
3917
3879
  @param {string} source string
@@ -11389,9 +11351,9 @@ yy.FuncValue = function (params) {
11389
11351
  return Object.assign(this, params);
11390
11352
  };
11391
11353
 
11392
- var re_invalidFnNameChars = /[^0-9A-Z_$]+/i;
11354
+ let re_invalidFnNameChars = /[^0-9A-Z_$]+/i;
11393
11355
  yy.FuncValue.prototype.toString = function () {
11394
- var s = '';
11356
+ let s = '';
11395
11357
 
11396
11358
  if (alasql.fn[this.funcid]) s += this.funcid;
11397
11359
  else if (alasql.aggr[this.funcid]) s += this.funcid;
@@ -11413,10 +11375,10 @@ yy.FuncValue.prototype.toString = function () {
11413
11375
  };
11414
11376
 
11415
11377
  yy.FuncValue.prototype.execute = function (databaseid, params, cb) {
11416
- var res = 1;
11378
+ let res = 1;
11417
11379
  alasql.precompile(this, databaseid, params); // Precompile queries
11418
11380
 
11419
- var expr = new Function('params,alasql', 'var y;return ' + this.toJS('', '', null));
11381
+ let expr = new Function('params,alasql', 'var y;return ' + this.toJS('', '', null));
11420
11382
  expr(params, alasql);
11421
11383
  if (cb) res = cb(res);
11422
11384
  return res;
@@ -11495,7 +11457,7 @@ stdlib.EXP = function (a) {
11495
11457
  };
11496
11458
 
11497
11459
  stdlib.IIF = function (a, b, c) {
11498
- if (arguments.length == 3) {
11460
+ if (arguments.length === 3) {
11499
11461
  return '((' + a + ')?(' + b + '):(' + c + '))';
11500
11462
  } else {
11501
11463
  throw new Error('Number of arguments of IFF is not equals to 3');
@@ -16994,16 +16956,7 @@ alasql.into.XLSX = function (filename, opts, data, columns, cb) {
16994
16956
  // saveAs(new Blob([s2ab(wbout)],{type:"application/octet-stream"}), '"'+filename+'"')
16995
16957
  // saveAs(new Blob([s2ab(wbout)],{type:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}), filename)
16996
16958
  // saveAs(new Blob([s2ab(wbout)],{type:"application/vnd.ms-excel"}), '"'+filename+'"');
16997
- if (isIE() == 9) {
16998
- throw new Error('Cannot save XLSX files in IE9. Please use XLS() export function');
16999
- // var URI = 'data:text/plain;charset=utf-8,';
17000
-
17001
- /** @todo Check if this code is required */
17002
-
17003
- // alert('ie9');
17004
- } else {
17005
- saveAs(new Blob([s2ab(wbout)], {type: 'application/octet-stream'}), filename);
17006
- }
16959
+ saveAs(new Blob([s2ab(wbout)], {type: 'application/octet-stream'}), filename);
17007
16960
  }
17008
16961
  }
17009
16962
 
package/dist/alasql.js CHANGED
@@ -1,7 +1,7 @@
1
- //! AlaSQL v2.2.4-develop-d97ae856 | © 2014-2022 Andrey Gershun & Mathias Wulff | License: MIT
1
+ //! AlaSQL v2.2.5-develop-63c84c04 | © 2014-2022 Andrey Gershun & Mathias Wulff | License: MIT
2
2
  /*
3
3
  @module alasql
4
- @version 2.2.4-develop-d97ae856
4
+ @version 2.2.5-develop-63c84c04
5
5
 
6
6
  AlaSQL - JavaScript SQL database
7
7
  © 2014-2016 Andrey Gershun & Mathias Rangel Wulff
@@ -142,7 +142,7 @@ var alasql = function(sql, params, cb, scope) {
142
142
  Current version of alasql
143
143
  @constant {string}
144
144
  */
145
- alasql.version = '2.2.4-develop-d97ae856';
145
+ alasql.version = '2.2.5-develop-63c84c04';
146
146
 
147
147
  /**
148
148
  Debug flag
@@ -3484,19 +3484,7 @@ var loadFile = (utils.loadFile = function (path, asy, success, error) {
3484
3484
  });
3485
3485
  } else {
3486
3486
  if (/^[a-z]+:\/\//i.test(path)) {
3487
- var fetch = require('node-fetch');
3488
- fetch(path)
3489
- .then((response) => response.arrayBuffer())
3490
- .then((buf) => {
3491
- var a = new Uint8Array(buf);
3492
- var b = [...a].map((e) => String.fromCharCode(e)).join('');
3493
- success(cutbom(b));
3494
- })
3495
- .catch((e) => {
3496
- if (error) return error(e);
3497
- console.error(e);
3498
- throw e;
3499
- });
3487
+ fetchData(path, (x) => success(cutbom(x)), error, asy);
3500
3488
  } else {
3501
3489
  //If async callthen call async
3502
3490
  if (asy) {
@@ -3559,21 +3547,7 @@ var loadFile = (utils.loadFile = function (path, asy, success, error) {
3559
3547
  Simply read file from HTTP request, like:
3560
3548
  SELECT * FROM TXT('http://alasql.org/README.md');
3561
3549
  */
3562
- var xhr = new XMLHttpRequest();
3563
- xhr.onreadystatechange = function () {
3564
- if (xhr.readyState === 4) {
3565
- if (xhr.status === 200) {
3566
- if (success) {
3567
- success(cutbom(xhr.responseText));
3568
- }
3569
- } else if (error) {
3570
- return error(xhr);
3571
- }
3572
- // Todo: else...?
3573
- }
3574
- };
3575
- xhr.open('GET', path, asy); // Async
3576
- xhr.send();
3550
+ fetchData(path, (x) => success(cutbom(x)), error, asy);
3577
3551
  }
3578
3552
  } else if (path instanceof Event) {
3579
3553
  /*
@@ -3600,6 +3574,33 @@ var loadFile = (utils.loadFile = function (path, asy, success, error) {
3600
3574
  }
3601
3575
  });
3602
3576
 
3577
+ let _fetch = typeof fetch !== 'undefined' ? fetch : null;
3578
+ /*not-for-browser/*
3579
+ _fetch = typeof fetch !== 'undefined' ? fetch : require('cross-fetch');
3580
+ //*/
3581
+
3582
+ async function fetchData(path, success, error, async) {
3583
+ if (async) {
3584
+ return getData(path, success, error);
3585
+ }
3586
+ return await getData(path, success, error);
3587
+ }
3588
+
3589
+ function getData(path, success, error) {
3590
+ return _fetch(path)
3591
+ .then((response) => response.arrayBuffer())
3592
+ .then((buf) => {
3593
+ var a = new Uint8Array(buf);
3594
+ var b = [...a].map((e) => String.fromCharCode(e)).join('');
3595
+ success(b);
3596
+ })
3597
+ .catch((e) => {
3598
+ if (error) return error(e);
3599
+ console.error(e);
3600
+ throw e;
3601
+ });
3602
+ }
3603
+
3603
3604
  /**
3604
3605
  @function Load binary file from anywhere
3605
3606
  @param {string} path File path
@@ -3625,19 +3626,7 @@ var loadBinaryFile = (utils.loadBinaryFile = function (
3625
3626
  fs = require('fs');
3626
3627
 
3627
3628
  if (/^[a-z]+:\/\//i.test(path)) {
3628
- var fetch = require('node-fetch');
3629
- fetch(path)
3630
- .then((response) => response.arrayBuffer())
3631
- .then((buf) => {
3632
- var a = new Uint8Array(buf);
3633
- var b = [...a].map((e) => String.fromCharCode(e)).join('');
3634
- success(b);
3635
- })
3636
- .catch((e) => {
3637
- if (error) return error(e);
3638
- console.error(e);
3639
- throw e;
3640
- });
3629
+ fetchData(path, success, error, runAsync);
3641
3630
  } else {
3642
3631
  if (runAsync) {
3643
3632
  fs.readFile(path, function (err, data) {
@@ -3870,30 +3859,14 @@ var saveFile = (utils.saveFile = function (path, data, cb, opts) {
3870
3859
  // });
3871
3860
  // });
3872
3861
  } else {
3873
- if (isIE() === 9) {
3874
- // Solution was taken from
3875
- // http://megatuto.com/formation-JAVASCRIPT.php?JAVASCRIPT_Example=Javascript+Save+CSV+file+in+IE+8/IE+9+without+using+window.open()+Categorie+javascript+internet-explorer-8&category=&article=7993
3876
- // var URI = 'data:text/plain;charset=utf-8,';
3877
-
3878
- // Prepare data
3879
- var ndata = data.replace(/\r\n/g, '&#A;&#D;');
3880
- ndata = ndata.replace(/\n/g, '&#D;');
3881
- ndata = ndata.replace(/\t/g, '&#9;');
3882
- var testlink = utils.global.open('about:blank', '_blank');
3883
- testlink.document.write(ndata); //fileData has contents for the file
3884
- testlink.document.close();
3885
- testlink.document.execCommand('SaveAs', false, path);
3886
- testlink.close();
3887
- } else {
3888
- var opt = {
3889
- disableAutoBom: false,
3890
- };
3891
- alasql.utils.extend(opt, opts);
3892
- var blob = new Blob([data], {type: 'text/plain;charset=utf-8'});
3893
- saveAs(blob, path, opt.disableAutoBom);
3894
- if (cb) {
3895
- res = cb(res);
3896
- }
3862
+ var opt = {
3863
+ disableAutoBom: false,
3864
+ };
3865
+ alasql.utils.extend(opt, opts);
3866
+ var blob = new Blob([data], {type: 'text/plain;charset=utf-8'});
3867
+ saveAs(blob, path, opt.disableAutoBom);
3868
+ if (cb) {
3869
+ res = cb(res);
3897
3870
  }
3898
3871
  }
3899
3872
  }
@@ -3901,17 +3874,6 @@ var saveFile = (utils.saveFile = function (path, data, cb, opts) {
3901
3874
  return res;
3902
3875
  });
3903
3876
 
3904
- /**
3905
- @function Is this IE9
3906
- @return {boolean} True for IE9 and false for other browsers
3907
-
3908
- For IE9 compatibility issues
3909
- */
3910
- function isIE() {
3911
- var myNav = navigator.userAgent.toLowerCase();
3912
- return myNav.indexOf('msie') !== -1 ? parseInt(myNav.split('msie')[1]) : false;
3913
- }
3914
-
3915
3877
  /**
3916
3878
  @function Hash a string to signed integer
3917
3879
  @param {string} source string
@@ -11389,9 +11351,9 @@ yy.FuncValue = function (params) {
11389
11351
  return Object.assign(this, params);
11390
11352
  };
11391
11353
 
11392
- var re_invalidFnNameChars = /[^0-9A-Z_$]+/i;
11354
+ let re_invalidFnNameChars = /[^0-9A-Z_$]+/i;
11393
11355
  yy.FuncValue.prototype.toString = function () {
11394
- var s = '';
11356
+ let s = '';
11395
11357
 
11396
11358
  if (alasql.fn[this.funcid]) s += this.funcid;
11397
11359
  else if (alasql.aggr[this.funcid]) s += this.funcid;
@@ -11413,10 +11375,10 @@ yy.FuncValue.prototype.toString = function () {
11413
11375
  };
11414
11376
 
11415
11377
  yy.FuncValue.prototype.execute = function (databaseid, params, cb) {
11416
- var res = 1;
11378
+ let res = 1;
11417
11379
  alasql.precompile(this, databaseid, params); // Precompile queries
11418
11380
 
11419
- var expr = new Function('params,alasql', 'var y;return ' + this.toJS('', '', null));
11381
+ let expr = new Function('params,alasql', 'var y;return ' + this.toJS('', '', null));
11420
11382
  expr(params, alasql);
11421
11383
  if (cb) res = cb(res);
11422
11384
  return res;
@@ -11495,7 +11457,7 @@ stdlib.EXP = function (a) {
11495
11457
  };
11496
11458
 
11497
11459
  stdlib.IIF = function (a, b, c) {
11498
- if (arguments.length == 3) {
11460
+ if (arguments.length === 3) {
11499
11461
  return '((' + a + ')?(' + b + '):(' + c + '))';
11500
11462
  } else {
11501
11463
  throw new Error('Number of arguments of IFF is not equals to 3');
@@ -16994,16 +16956,7 @@ alasql.into.XLSX = function (filename, opts, data, columns, cb) {
16994
16956
  // saveAs(new Blob([s2ab(wbout)],{type:"application/octet-stream"}), '"'+filename+'"')
16995
16957
  // saveAs(new Blob([s2ab(wbout)],{type:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}), filename)
16996
16958
  // saveAs(new Blob([s2ab(wbout)],{type:"application/vnd.ms-excel"}), '"'+filename+'"');
16997
- if (isIE() == 9) {
16998
- throw new Error('Cannot save XLSX files in IE9. Please use XLS() export function');
16999
- // var URI = 'data:text/plain;charset=utf-8,';
17000
-
17001
- /** @todo Check if this code is required */
17002
-
17003
- // alert('ie9');
17004
- } else {
17005
- saveAs(new Blob([s2ab(wbout)], {type: 'application/octet-stream'}), filename);
17006
- }
16959
+ saveAs(new Blob([s2ab(wbout)], {type: 'application/octet-stream'}), filename);
17007
16960
  }
17008
16961
  }
17009
16962