From c03bc1880376fa6135dfa1eb4097dce7cd8e0fcc Mon Sep 17 00:00:00 2001
From: SheetJS <dev@sheetjs.com>
Date: Fri, 22 Jul 2022 05:01:56 -0400
Subject: [PATCH] package.json exports

---
 bits/90_utils.js                 |  18 +++-
 demos/README.md                  |   6 +-
 demos/browserify/Makefile        |  17 ----
 demos/browserify/README.md       |  29 +-----
 demos/browserify/app.js          | 149 -------------------------------
 demos/browserify/browserify.html |  62 -------------
 demos/browserify/xlsxworker.js   |  12 ---
 demos/parcel/Makefile            |  12 ---
 demos/parcel/README.md           |  12 +--
 demos/parcel/index.html          |  48 ----------
 demos/parcel/index.js            | 130 ---------------------------
 demos/parcel/package.json        |  10 ---
 package.json                     |  15 ++++
 13 files changed, 38 insertions(+), 482 deletions(-)
 delete mode 100644 demos/browserify/Makefile
 delete mode 100644 demos/browserify/app.js
 delete mode 100644 demos/browserify/browserify.html
 delete mode 100644 demos/browserify/xlsxworker.js
 delete mode 100644 demos/parcel/Makefile
 delete mode 100644 demos/parcel/index.html
 delete mode 100644 demos/parcel/index.js
 delete mode 100644 demos/parcel/package.json

diff --git a/bits/90_utils.js b/bits/90_utils.js
index d43c141..b663c6d 100644
--- a/bits/90_utils.js
+++ b/bits/90_utils.js
@@ -191,8 +191,10 @@ function sheet_to_formulae(sheet/*:Worksheet*/)/*:Array<string>*/ {
 
 function sheet_add_json(_ws/*:?Worksheet*/, js/*:Array<any>*/, opts)/*:Worksheet*/ {
 	var o = opts || {};
+	var dense = _ws ? Array.isArray(_ws) : o.dense;
+	if(DENSE != null && dense == null) dense = DENSE;
 	var offset = +!o.skipHeader;
-	var ws/*:Worksheet*/ = _ws || ({}/*:any*/);
+	var ws/*:Worksheet*/ = _ws || (dense ? ([]/*:any*/) : ({}/*:any*/));
 	var _R = 0, _C = 0;
 	if(ws && o.origin != null) {
 		if(typeof o.origin == 'number') _R = o.origin;
@@ -233,7 +235,13 @@ function sheet_add_json(_ws/*:?Worksheet*/, js/*:Array<any>*/, opts)/*:Worksheet
 					z = (cell.z && fmt_is_date(cell.z)) ? cell.z : (o.dateNF || table_fmt[14]);
 				}
 				else if(v === null && o.nullError) { t = 'e'; v = 0; }
-				if(!cell) ws[ref] = cell = ({t:t, v:v}/*:any*/);
+				if(!cell) {
+					if(!dense) ws[ref] = cell = ({t:t, v:v}/*:any*/);
+					else {
+						if(!ws[_R + R + offset]) ws[_R + R + offset] = [];
+						ws[_R + R + offset][_C + C] = cell = ({t:t, v:v}/*:any*/);
+					}
+				}
 				else {
 					cell.t = t; cell.v = v;
 					delete cell.w; delete cell.R;
@@ -245,7 +253,11 @@ function sheet_add_json(_ws/*:?Worksheet*/, js/*:Array<any>*/, opts)/*:Worksheet
 	});
 	range.e.c = Math.max(range.e.c, _C + hdr.length - 1);
 	var __R = encode_row(_R);
-	if(offset) for(C = 0; C < hdr.length; ++C) ws[encode_col(C + _C) + __R] = {t:'s', v:hdr[C]};
+	if(dense && !ws[_R]) ws[_R] = [];
+	if(offset) for(C = 0; C < hdr.length; ++C) {
+		if(dense) ws[_R][C + _C] = {t:'s', v:hdr[C]};
+		else ws[encode_col(C + _C) + __R] = {t:'s', v:hdr[C]};
+	}
 	ws['!ref'] = encode_range(range);
 	return ws;
 }
diff --git a/demos/README.md b/demos/README.md
index 20d6926..b4e9fa9 100644
--- a/demos/README.md
+++ b/demos/README.md
@@ -54,8 +54,10 @@ can be installed with Bash on Windows or with `cygwin`.
 - [`internet explorer`](oldie/)
 
 **Bundlers and Tooling**
-- [`browserify`](browserify/)
-- [`parcel`](parcel/)
+- [`browserify`](https://docs.sheetjs.com/docs/getting-started/demos/bundler#browserify)
+- [`bun`](https://docs.sheetjs.com/docs/getting-started/demos/bundler#bun)
+- [`esbuild`](https://docs.sheetjs.com/docs/getting-started/demos/bundler#esbuild)
+- [`parcel`](https://docs.sheetjs.com/docs/getting-started/demos/bundler#parcel)
 - [`requirejs`](requirejs/)
 - [`rollup`](rollup/)
 - [`systemjs`](systemjs/)
diff --git a/demos/browserify/Makefile b/demos/browserify/Makefile
deleted file mode 100644
index ada562e..0000000
--- a/demos/browserify/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-TOOL=browserify
-.PHONY: all
-all: $(TOOL).min.js worker.min.js
-
-$(TOOL).min.js: $(TOOL).js
-	uglifyjs $< > $@
-
-.PHONY: $(TOOL).js
-$(TOOL).js: app.js
-	browserify $< > $@
-
-worker.min.js: worker.js
-	uglifyjs $< > $@
-
-.PHONY: worker.js
-worker.js: xlsxworker.js
-	browserify $< > $@
diff --git a/demos/browserify/README.md b/demos/browserify/README.md
index 1d646f7..c27653b 100644
--- a/demos/browserify/README.md
+++ b/demos/browserify/README.md
@@ -1,31 +1,6 @@
 # Browserify
 
-The library is compatible with Browserify and should just work out of the box.
-
-This demo uses the `require` form to expose the whole library, enabling client
-code to access the library with `var XLSX = require('xlsx')`.  The JS code from
-the root demo was moved to a separate `app.js` script.  That script is bundled:
-
-```bash
-browserify app.js > browserify.js
-uglifyjs browserify.js > browserify.min.js
-```
-
-### Worker Scripts
-
-Browserify can also bundle worker scripts!  Instead of using `importScripts`,
-the worker script should require the module:
-
-```diff
--importScripts('dist/xlsx.full.min.js');
-+var XLSX = require('xlsx');
-```
-
-The same process generates the worker script:
-
-```bash
-browserify xlsxworker.js > worker.js
-uglifyjs worker.js > worker.min.js
-```
+[The new demo](https://docs.sheetjs.com/docs/getting-started/demos/bundler#browserify)
+includes a more concise example.
 
 [![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
diff --git a/demos/browserify/app.js b/demos/browserify/app.js
deleted file mode 100644
index 1bc148e..0000000
--- a/demos/browserify/app.js
+++ /dev/null
@@ -1,149 +0,0 @@
-/* xlsx.js (C) 2013-present  SheetJS -- http://sheetjs.com */
-var XLSX = require('../../'); // test against development version
-//var XLSX = require('xlsx'); // use in production
-/*jshint browser:true */
-/*global require */
-
-var global_wb;
-
-var process_wb = (function() {
-	var OUT = document.getElementById('out');
-	var HTMLOUT = document.getElementById('htmlout');
-
-	var get_format = (function() {
-		var radios = document.getElementsByName( "format" );
-		return function() {
-			for(var i = 0; i < radios.length; ++i) if(radios[i].checked || radios.length === 1) return radios[i].value;
-		};
-	})();
-
-	var to_json = function to_json(workbook) {
-		var result = {};
-		workbook.SheetNames.forEach(function(sheetName) {
-			var roa = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName]);
-			if(roa.length) result[sheetName] = roa;
-		});
-		return JSON.stringify(result, 2, 2);
-	};
-
-	var to_csv = function to_csv(workbook) {
-		var result = [];
-		workbook.SheetNames.forEach(function(sheetName) {
-			var csv = XLSX.utils.sheet_to_csv(workbook.Sheets[sheetName]);
-			if(csv.length){
-				result.push("SHEET: " + sheetName);
-				result.push("");
-				result.push(csv);
-			}
-		});
-		return result.join("\n");
-	};
-
-	var to_fmla = function to_fmla(workbook) {
-		var result = [];
-		workbook.SheetNames.forEach(function(sheetName) {
-			var formulae = XLSX.utils.get_formulae(workbook.Sheets[sheetName]);
-			if(formulae.length){
-				result.push("SHEET: " + sheetName);
-				result.push("");
-				result.push(formulae.join("\n"));
-			}
-		});
-		return result.join("\n");
-	};
-
-	var to_html = function to_html(workbook) {
-		HTMLOUT.innerHTML = "";
-		workbook.SheetNames.forEach(function(sheetName) {
-			var htmlstr = XLSX.write(workbook, {sheet:sheetName, type:'string', bookType:'html'});
-			HTMLOUT.innerHTML += htmlstr;
-		});
-		return "";
-	};
-
-	return function process_wb(wb) {
-		global_wb = wb;
-		var output = "";
-		switch(get_format()) {
-			case "form": output = to_fmla(wb); break;
-			case "html": output = to_html(wb); break;
-			case "json": output = to_json(wb); break;
-			default: output = to_csv(wb);
-		}
-		if(OUT.innerText === undefined) OUT.textContent = output;
-		else OUT.innerText = output;
-		if(typeof console !== 'undefined') console.log("output", new Date());
-	};
-})();
-
-var setfmt = window.setfmt = function setfmt() { if(global_wb) process_wb(global_wb); };
-
-var b64it = window.b64it = (function() {
-	var tarea = document.getElementById('b64data');
-	return function b64it() {
-		if(typeof console !== 'undefined') console.log("onload", new Date());
-		var wb = XLSX.read(tarea.value, {type:'base64', WTF:false});
-		process_wb(wb);
-	};
-})();
-
-var do_file = (function() {
-	var use_worker = typeof Worker !== 'undefined';
-	var domwork = document.getElementsByName("useworker")[0];
-	if(!use_worker) domwork.disabled = !(domwork.checked = false);
-
-	var xw = function xw(data, cb) {
-		var worker = new Worker('./worker.min.js');
-		worker.onmessage = function(e) {
-			switch(e.data.t) {
-				case 'ready': break;
-				case 'e': console.error(e.data.d); break;
-				case 'xlsx': cb(JSON.parse(e.data.d)); break;
-			}
-		};
-		worker.postMessage({d:data,b:'array'});
-	};
-
-	return function do_file(files) {
-		use_worker = domwork.checked;
-		var f = files[0];
-		var reader = new FileReader();
-		reader.onload = function(e) {
-			if(typeof console !== 'undefined') console.log("onload", new Date(), use_worker);
-			var data = e.target.result;
-			data = new Uint8Array(data);
-			if(use_worker) xw(data, process_wb);
-			else process_wb(XLSX.read(data, {type: 'array'}));
-		};
-		reader.readAsArrayBuffer(f);
-	};
-})();
-
-(function() {
-	var drop = document.getElementById('drop');
-	if(!drop.addEventListener) return;
-
-	function handleDrop(e) {
-		e.stopPropagation();
-		e.preventDefault();
-		do_file(e.dataTransfer.files);
-	}
-
-	function handleDragover(e) {
-		e.stopPropagation();
-		e.preventDefault();
-		e.dataTransfer.dropEffect = 'copy';
-	}
-
-	drop.addEventListener('dragenter', handleDragover, false);
-	drop.addEventListener('dragover', handleDragover, false);
-	drop.addEventListener('drop', handleDrop, false);
-})();
-
-(function() {
-	var xlf = document.getElementById('xlf');
-	if(!xlf.addEventListener) return;
-	function handleFile(e) { do_file(e.target.files); }
-	xlf.addEventListener('change', handleFile, false);
-})();
-
diff --git a/demos/browserify/browserify.html b/demos/browserify/browserify.html
deleted file mode 100644
index 49d1803..0000000
--- a/demos/browserify/browserify.html
+++ /dev/null
@@ -1,62 +0,0 @@
-<!DOCTYPE html>
-<!-- xlsx.js (C) 2013-present  SheetJS http://sheetjs.com -->
-<!-- vim: set ts=2: -->
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<title>SheetJS Live Demo</title>
-<style>
-#drop{
-	border:2px dashed #bbb;
-	-moz-border-radius:5px;
-	-webkit-border-radius:5px;
-	border-radius:5px;
-	padding:25px;
-	text-align:center;
-	font:20pt bold,"Vollkorn";color:#bbb
-}
-#b64data{
-	width:100%;
-}
-a { text-decoration: none }
-</style>
-</head>
-<body>
-<pre>
-<b><a href="http://sheetjs.com">SheetJS Data Preview Live Demo</a></b>
-(Base64 text works back to IE6; drag and drop works back to IE10)
-
-<a href="https://github.com/SheetJS/js-xlsx">Source Code Repo</a>
-<a href="https://github.com/SheetJS/js-xlsx/issues">Issues?  Something look weird?  Click here and report an issue</a>
-Output Format: <select name="format" onchange="setfmt()">
-<option value="csv" selected> CSV</option>
-<option value="json"> JSON</option>
-<option value="form"> FORMULAE</option>
-<option value="html"> HTML</option>
-</select><br />
-<div id="drop">Drop a spreadsheet file here to see sheet data</div>
-<input type="file" name="xlfile" id="xlf" /> ... or click here to select a file
-
-<textarea id="b64data">... or paste a base64-encoding here</textarea>
-<input type="button" id="dotext" value="Click here to process the base64 text" onclick="b64it();"/><br />
-<b>Advanced Demo Options:</b>
-Use Web Workers: (when available) <input type="checkbox" name="useworker" checked>
-</pre>
-<pre id="out"></pre>
-<div id="htmlout"></div>
-<br />
-<script src="browserify.min.js"></script>
-<script type="text/javascript">
-/* eslint no-use-before-define:0 */
-	var _gaq = _gaq || [];
-	_gaq.push(['_setAccount', 'UA-36810333-1']);
-	_gaq.push(['_trackPageview']);
-
-	(function() {
-		var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
-		ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
-		var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
-	})();
-</script>
-</body>
-</html>
diff --git a/demos/browserify/xlsxworker.js b/demos/browserify/xlsxworker.js
deleted file mode 100644
index c76ee95..0000000
--- a/demos/browserify/xlsxworker.js
+++ /dev/null
@@ -1,12 +0,0 @@
-/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
-var XLSX = require('../../'); // test against development version
-//var XLSX = require('xlsx'); // use in production
-postMessage({t:"ready"});
-
-onmessage = function (evt) {
-  var v;
-  try {
-    v = XLSX.read(evt.data.d, {type: evt.data.b});
-postMessage({t:"xlsx", d:JSON.stringify(v)});
-  } catch(e) { postMessage({t:"e",d:e.stack||e}); }
-};
diff --git a/demos/parcel/Makefile b/demos/parcel/Makefile
deleted file mode 100644
index 81250eb..0000000
--- a/demos/parcel/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-.PHONY: app
-app: init
-	npx parcel build index.html
-
-.PHONY: init
-init:
-	mkdir -p node_modules
-	npm i
-
-.PHONY: ctest 
-ctest: init
-	npx parcel index.html
diff --git a/demos/parcel/README.md b/demos/parcel/README.md
index 12cd331..6bcfc87 100644
--- a/demos/parcel/README.md
+++ b/demos/parcel/README.md
@@ -1,14 +1,6 @@
 # Parcel
 
-Parcel Bundler starting from version 1.5.0 should play nice with this library
-out of the box:
-
-```js
-import { read, write, utils } from 'xlsx'
-```
-
-Errors of the form `Could not statically evaluate fs call` stem from a parcel
-[bug](https://github.com/parcel-bundler/parcel/pull/523#issuecomment-357486164).
-Upgrade to version 1.5.0 or later.
+[The new demo](https://docs.sheetjs.com/docs/getting-started/demos/bundler#parcel)
+includes a more concise example.
 
 [![Analytics](https://ga-beacon.appspot.com/UA-36810333-1/SheetJS/js-xlsx?pixel)](https://github.com/SheetJS/js-xlsx)
diff --git a/demos/parcel/index.html b/demos/parcel/index.html
deleted file mode 100644
index 896a181..0000000
--- a/demos/parcel/index.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<!DOCTYPE html>
-<!-- xlsx.js (C) 2013-present  SheetJS http://sheetjs.com -->
-<!-- vim: set ts=2: -->
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<title>SheetJS Live Demo</title>
-<style>
-#drop{
-	border:2px dashed #bbb;
-	-moz-border-radius:5px;
-	-webkit-border-radius:5px;
-	border-radius:5px;
-	padding:25px;
-	text-align:center;
-	font:20pt bold,"Vollkorn";color:#bbb
-}
-#b64data{
-	width:100%;
-}
-a { text-decoration: none }
-</style>
-</head>
-<body>
-<pre>
-<b><a href="http://sheetjs.com">SheetJS Data Preview Live Demo</a></b>
-(Base64 text works back to IE6; drag and drop works back to IE10)
-
-<a href="https://github.com/SheetJS/js-xlsx">Source Code Repo</a>
-<a href="https://github.com/SheetJS/js-xlsx/issues">Issues?  Something look weird?  Click here and report an issue</a>
-Output Format: <select name="format" onchange="setfmt()">
-<option value="csv" selected> CSV</option>
-<option value="json"> JSON</option>
-<option value="form"> FORMULAE</option>
-<option value="html"> HTML</option>
-</select><br />
-<div id="drop">Drop a spreadsheet file here to see sheet data</div>
-<input type="file" name="xlfile" id="xlf" /> ... or click here to select a file
-
-<textarea id="b64data">... or paste a base64-encoding here</textarea>
-<input type="button" id="dotext" value="Click here to process the base64 text" onclick="b64it();"/><br />
-</pre>
-<pre id="out"></pre>
-<div id="htmlout"></div>
-<br />
-<script src="./index.js" type="module"></script>
-</body>
-</html>
diff --git a/demos/parcel/index.js b/demos/parcel/index.js
deleted file mode 100644
index 341dbae..0000000
--- a/demos/parcel/index.js
+++ /dev/null
@@ -1,130 +0,0 @@
-/* xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
-/*jshint browser:true */
-import * as X from '../../';
-
-console.log(X.version);
-
-var global_wb;
-
-var process_wb = (function() {
-	var OUT = document.getElementById('out');
-	var HTMLOUT = document.getElementById('htmlout');
-
-	var get_format = (function() {
-		var radios = document.getElementsByName( "format" );
-		return function() {
-			for(var i = 0; i < radios.length; ++i) if(radios[i].checked || radios.length === 1) return radios[i].value;
-		};
-	})();
-
-	var to_json = function to_json(workbook) {
-		var result = {};
-		workbook.SheetNames.forEach(function(sheetName) {
-			var roa = X.utils.sheet_to_json(workbook.Sheets[sheetName]);
-			if(roa.length) result[sheetName] = roa;
-		});
-		return JSON.stringify(result, 2, 2);
-	};
-
-	var to_csv = function to_csv(workbook) {
-		var result = [];
-		workbook.SheetNames.forEach(function(sheetName) {
-			var csv = X.utils.sheet_to_csv(workbook.Sheets[sheetName]);
-			if(csv.length){
-				result.push("SHEET: " + sheetName);
-				result.push("");
-				result.push(csv);
-			}
-		});
-		return result.join("\n");
-	};
-
-	var to_fmla = function to_fmla(workbook) {
-		var result = [];
-		workbook.SheetNames.forEach(function(sheetName) {
-			var formulae = X.utils.get_formulae(workbook.Sheets[sheetName]);
-			if(formulae.length){
-				result.push("SHEET: " + sheetName);
-				result.push("");
-				result.push(formulae.join("\n"));
-			}
-		});
-		return result.join("\n");
-	};
-
-	var to_html = function to_html(workbook) {
-		HTMLOUT.innerHTML = "";
-		workbook.SheetNames.forEach(function(sheetName) {
-			var htmlstr = X.write(workbook, {sheet:sheetName, type:'string', bookType:'html'});
-			HTMLOUT.innerHTML += htmlstr;
-		});
-		return "";
-	};
-
-	return function process_wb(wb) {
-		global_wb = wb;
-		var output = "";
-		switch(get_format()) {
-			case "form": output = to_fmla(wb); break;
-			case "html": output = to_html(wb); break;
-			case "json": output = to_json(wb); break;
-			default: output = to_csv(wb);
-		}
-		if(OUT.innerText === undefined) OUT.textContent = output;
-		else OUT.innerText = output;
-		if(typeof console !== 'undefined') console.log("output", new Date());
-	};
-})();
-
-var setfmt = window.setfmt = function setfmt() { if(global_wb) process_wb(global_wb); };
-
-var b64it = window.b64it = (function() {
-	var tarea = document.getElementById('b64data');
-	return function b64it() {
-		if(typeof console !== 'undefined') console.log("onload", new Date());
-		var wb = X.read(tarea.value, {type:'base64', WTF:false});
-		process_wb(wb);
-	};
-})();
-
-var do_file = (function() {
-	return function do_file(files) {
-		var f = files[0];
-		var reader = new FileReader();
-		reader.onload = function(e) {
-			if(typeof console !== 'undefined') console.log("onload", new Date());
-			var data = e.target.result;
-			data = new Uint8Array(data);
-			process_wb(X.read(data, {type: 'array'}));
-		};
-		reader.readAsArrayBuffer(f);
-	};
-})();
-
-(function() {
-	var drop = document.getElementById('drop');
-	if(!drop.addEventListener) return;
-
-	function handleDrop(e) {
-		e.stopPropagation();
-		e.preventDefault();
-		do_file(e.dataTransfer.files);
-	}
-
-	function handleDragover(e) {
-		e.stopPropagation();
-		e.preventDefault();
-		e.dataTransfer.dropEffect = 'copy';
-	}
-
-	drop.addEventListener('dragenter', handleDragover, false);
-	drop.addEventListener('dragover', handleDragover, false);
-	drop.addEventListener('drop', handleDrop, false);
-})();
-
-(function() {
-	var xlf = document.getElementById('xlf');
-	if(!xlf.addEventListener) return;
-	function handleFile(e) { do_file(e.target.files); }
-	xlf.addEventListener('change', handleFile, false);
-})();
diff --git a/demos/parcel/package.json b/demos/parcel/package.json
deleted file mode 100644
index da9860f..0000000
--- a/demos/parcel/package.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-	"source":"index.html",
-	"scripts": {
-		"build":"parcel build"
-	},
-	"dependencies": {
-		"parcel": "^2.5.0",
-		"xlsx":"https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz"
-	}
-}
diff --git a/package.json b/package.json
index 12d72ea..83b9e44 100644
--- a/package.json
+++ b/package.json
@@ -29,6 +29,21 @@
 		".": {
 			"import": "./xlsx.mjs",
 			"require": "./xlsx.js"
+		},
+		"./xlsx.mjs": {
+			"import": "./xlsx.mjs"
+		},
+		"./dist/xlsx.zahl": {
+			"import": "./dist/xlsx.zahl.mjs",
+			"require": "./dist/xlsx.zahl.js"
+		},
+		"./dist/cpexcel": {
+			"import": "./dist/cpexcel.full.mjs",
+			"require": "./dist/cpexcel.js"
+		},
+		"./dist/cpexcel.full": {
+			"import": "./dist/cpexcel.full.mjs",
+			"require": "./dist/cpexcel.js"
 		}
 	},
 	"browser": {