diff --git a/docz/docs/03-demos/01-frontend/03-angular.md b/docz/docs/03-demos/01-frontend/03-angular.md
index da55c7d..ddf5d98 100644
--- a/docz/docs/03-demos/01-frontend/03-angular.md
+++ b/docz/docs/03-demos/01-frontend/03-angular.md
@@ -1,5 +1,7 @@
---
-title: Angular
+title: Sheets in Angular Sites
+sidebar_label: Angular
+description: Build interactive websites with Angular. Seamlessly integrate spreadsheets into your app using SheetJS. Bring Excel-powered workflows and data to the modern web.
pagination_prev: demos/index
pagination_next: demos/grid/index
sidebar_position: 3
@@ -10,18 +12,24 @@ import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import CodeBlock from '@theme/CodeBlock';
-Angular is a JS library for building user interfaces.
+Angular is a JS library for building user interfaces.[^1]
-This demo tries to cover common Angular data flow ideas and strategies. Angular
-and TypeScript familiarity is assumed.
+[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
+data from spreadsheets.
-**SheetJS plays nice with each version of Angular**.
+This demo uses Angular and SheetJS to process and generate spreadsheets. We'll
+explore how to load SheetJS in Angular projects and compare common state models
+and data flow strategies.
-Other demos cover general Angular deployments, including:
+:::note pass
+
+This demo focuses on Angular concepts. Other demos cover general deployments:
- [iOS and Android applications powered by NativeScript](/docs/demos/mobile/nativescript)
- [iOS and Android applications powered by Ionic](/docs/demos/mobile/ionic)
+:::
+
:::caution pass
Angular tooling uses native NodeJS modules. There are a number of issues when
@@ -61,31 +69,33 @@ import { read, utils, writeFile } from 'xlsx';
The various SheetJS APIs work with various data shapes. The preferred state
depends on the application.
+:::warning pass
+
+Angular 17 broke backwards compatibility with projects using Angular 2 - 16.
+
+**Despite the Angular turmoil, SheetJS plays nice with each version of Angular**.
+
+When relevant, code snippets for Angular 17 and Angular 2 - 16 are included. The
+"Angular 2-16" and "Angular 17+" tabs change the displayed code blocks
+
+:::
+
### Array of Objects
Typically, some users will create a spreadsheet with source data that should be
-loaded into the site. This sheet will have known columns. For example, our
-[presidents sheet](https://sheetjs.com/pres.xlsx) has "Name" / "Index" columns:
+loaded into the site. This sheet will have known columns.
+
+#### State
+
+The example [presidents sheet](https://sheetjs.com/pres.xlsx) has one header row
+with "Name" and "Index" columns. The natural JS representation is an object for
+each row, using the values in the first rows as keys:
+
+
Spreadsheet
State
![`pres.xlsx` data](pathname:///pres.png)
-This naturally maps to an array of typed objects, as in the TS example below:
-
-```ts
-import { read, utils } from 'xlsx';
-
-interface President {
- Name: string;
- Index: number;
-}
-
-const f = await (await fetch("https://sheetjs.com/pres.xlsx")).arrayBuffer();
-const wb = read(f);
-const data = utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);
-console.log(data);
-```
-
-`data` will be an array of objects:
+
```js
[
@@ -97,8 +107,199 @@ console.log(data);
]
```
-A component will typically loop over the data using `*ngFor`. The following
-example generates a TABLE with a row for each President:
+
+
+This data is typically stored as an array of objects in the component class:
+
+```ts
+import { Component } from '@angular/core';
+
+@Component({ /* ... component configuration options ... */ })
+export class AppComponent {
+ /* the component state is an array of objects */
+ // highlight-next-line
+ rows: any[] = [ { Name: "SheetJS", Index: 0 }];
+}
+```
+
+When the spreadsheet header row is known ahead of time, row typing is possible:
+
+```ts
+import { Component } from '@angular/core';
+
+interface President {
+ Name: string;
+ Index: number;
+}
+
+@Component({ /* ... component configuration options ... */ })
+export class AppComponent {
+ /* the component state is an array of presidents */
+ // highlight-next-line
+ rows: President[] = [ { Name: "SheetJS", Index: 0 }];
+}
+```
+
+:::caution pass
+
+The types are informative. They do not enforce that worksheets include the named
+columns. A runtime data validation library should be used to verify the dataset.
+
+When the file header is not known in advance, `any` should be used.
+
+:::
+
+#### Updating State
+
+The SheetJS [`read`](/docs/api/parse-options) and [`sheet_to_json`](/docs/api/utilities/array#array-output)
+functions simplify state updates. They are best used in the function bodies of
+`ngOnInit`[^2] and event handlers.
+
+A `ngOnInit` method can download and update state when a person loads the site:
+
+```mermaid
+flowchart LR
+ url[(Remote\nFile)]
+ ab[(Data\nArrayBuffer)]
+ wb(SheetJS\nWorkbook)
+ ws(SheetJS\nWorksheet)
+ aoo(array of\nobjects)
+ state((component\nstate))
+ url --> |fetch\n\n| ab
+ ab --> |read\n\n| wb
+ wb --> |wb.Sheets\nselect sheet| ws
+ ws --> |sheet_to_json\n\n| aoo
+ aoo --> |setPres\nfrom `setState`| state
+```
+
+```ts
+import { Component } from '@angular/core';
+import { read, utils } from 'xlsx';
+
+interface President { Name: string; Index: number };
+
+@Component({ /* ... component configuration options ... */ })
+export class AppComponent {
+ rows: President[] = [ { Name: "SheetJS", Index: 0 }];
+ ngOnInit(): void { (async() => {
+ /* Download from https://sheetjs.com/pres.numbers */
+ const f = await fetch("https://sheetjs.com/pres.numbers");
+ const ab = await f.arrayBuffer();
+
+ // highlight-start
+ /* parse workbook */
+ const wb = read(ab);
+
+ /* generate array of objects from first worksheet */
+ const ws = wb.Sheets[wb.SheetNames[0]]; // get the first worksheet
+ const data = utils.sheet_to_json(ws); // generate objects
+
+ /* update data */
+ this.rows = data;
+ // highlight-end
+ })(); }
+}
+```
+
+#### Rendering Data
+
+Components typically render HTML tables from arrays of objects. The `
` table
+row elements are typically generated by mapping over the state array, as shown
+in the example template.
+
+:::caution pass
+
+Angular 2 - 16 recommended using `ngFor`[^3]. Angular 17 no longer supports the
+storied syntax, instead opting for a `@for` block reminiscent of JavaScript[^4].
+
+:::
+
+
+
+
+```html title="Example Template for displaying arrays of objects (Angular 2-16)"
+
+
Name
Index
+
+// highlight-start
+
+
{{row.Name}}
+
{{row.Index}}
+
+// highlight-end
+
+
+```
+
+
+
+
+```html title="Example Template for displaying arrays of objects (Angular 17+)"
+
+
Name
Index
+
+// highlight-start
+ @for(row of rows; track $index) {
+
{{row.Name}}
+
{{row.Index}}
+
}
+// highlight-end
+
+
+```
+
+
+
+
+#### Exporting Data
+
+The [`writeFile`](/docs/api/write-options) and [`json_to_sheet`](/docs/api/utilities/array#array-of-objects-input)
+functions simplify exporting data. They are best used in the function bodies of
+event handlers attached to button or other elements.
+
+A callback can generate a local file when a user clicks a button:
+
+```mermaid
+flowchart LR
+ state((component\nstate))
+ ws(SheetJS\nWorksheet)
+ wb(SheetJS\nWorkbook)
+ file[(XLSX\nexport)]
+ state --> |json_to_sheet\n\n| ws
+ ws --> |book_new\nbook_append_sheet| wb
+ wb --> |writeFile\n\n| file
+```
+
+```ts title="src/app/app.component.ts"
+import { Component } from '@angular/core';
+import { utils, writeFileXLSX } from 'xlsx';
+
+interface President { Name: string; Index: number };
+
+@Component({ /* ... component configuration options ... */ })
+export class AppComponent {
+ rows: President[] = [ { Name: "SheetJS", Index: 0 }];
+ /* get state data and export to XLSX */
+ onSave(): void {
+ /* generate worksheet from state */
+ // highlight-next-line
+ const ws = utils.json_to_sheet(this.rows);
+ /* create workbook and append worksheet */
+ const wb = utils.book_new();
+ utils.book_append_sheet(wb, ws, "Data");
+ /* export to XLSX */
+ writeFileXLSX(wb, "SheetJSAngularAoO.xlsx");
+ }
+}
+```
+
+#### Complete Component
+
+This complete component example fetches a test file and displays the contents in
+a HTML table. When the export button is clicked, a callback will export a file:
+
+
+
```ts title="src/app/app.component.ts"
import { Component } from '@angular/core';
@@ -152,11 +353,72 @@ export class AppComponent {
}
```
+
+
+
+```ts title="src/app/app.component.ts"
+import { Component } from '@angular/core';
+import { read, utils, writeFileXLSX } from 'xlsx';
+
+interface President { Name: string; Index: number };
+
+@Component({
+ selector: 'app-root',
+ standalone: true,
+ template: `
+
+`
+})
+export class AppComponent {
+ // highlight-next-line
+ rows: President[] = [ { Name: "SheetJS", Index: 0 }];
+ ngOnInit(): void { (async() => {
+ /* Download from https://sheetjs.com/pres.numbers */
+ const f = await fetch("https://sheetjs.com/pres.numbers");
+ const ab = await f.arrayBuffer();
+
+ /* parse workbook */
+ // highlight-next-line
+ const wb = read(ab);
+
+ /* update data */
+ // highlight-next-line
+ this.rows = utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);
+
+ })(); }
+ /* get state data and export to XLSX */
+ onSave(): void {
+ // highlight-next-line
+ const ws = utils.json_to_sheet(this.rows);
+ const wb = utils.book_new();
+ utils.book_append_sheet(wb, ws, "Data");
+ writeFileXLSX(wb, "SheetJSAngularAoO.xlsx");
+ }
+}
+```
+
+
+
+
How to run the example (click to show)
-:::note
+:::note Tested Deployments
-This demo was last run on 2023-10-22 using Angular CLI `16.2.7`
+This demo was last run on 2023-11-18 using Angular 17.0.3 and CLI `17.0.1`
:::
@@ -169,7 +431,7 @@ npx @angular/cli analytics disable -g
1) Create a new project:
```bash
-npx @angular/cli@16.2.7 new --minimal --defaults --no-interactive sheetjs-angular
+npx @angular/cli@17.0.1 new --minimal --defaults --no-interactive sheetjs-angular
```
2) Install the SheetJS dependency and start the dev server:
@@ -184,7 +446,9 @@ npm start`}
3) Open a web browser and access the displayed URL (`http://localhost:4200`)
-4) Replace `src/app/app.component.ts` with the previous code snippet.
+4) In the previous `src/app/app.component.ts` code snippet, select the tab for
+the appropriate version of Angular ("Angular 2-16" or "Angular 17+"), copy the
+code contents and replace `src/app/app.component.ts` in the project.
The page will refresh and show a table with an Export button. Click the button
and the page will attempt to download `SheetJSAngularAoO.xlsx`. Open the file
@@ -198,10 +462,23 @@ npm run build
To test the generated site, start a web server:
+
+
+
```bash
npx -y http-server dist/sheetjs-angular/
```
+
+
+
+```bash
+npx -y http-server dist/sheetjs-angular/browser/
+```
+
+
+
+
Access `http://localhost:8080` with a web browser to test the bundled site.
@@ -215,7 +492,10 @@ However, this does not handle merge cells well!
The `sheet_to_html` function generates HTML that is aware of merges and other
worksheet features. The generated HTML does not contain any `
```
-The HTML table can be directly exported with `XLSX.utils.table_to_book`:
+The HTML table can be directly exported with [`table_to_book`](/docs/api/utilities/html#html-table-input):
```js
$scope.exportSheetJS = function() {
@@ -291,11 +362,10 @@ app.controller('sheetjs', function($scope, $http) {
XLSX.writeFile(wb, "SheetJSAngularJSHTML.xlsx");
};
$http({
- method:'GET',
url:'https://sheetjs.com/pres.xlsx',
- responseType:'arraybuffer'
+ method:'GET', responseType:'arraybuffer'
}).then(function(data) {
- var wb = XLSX.read(data.data, {type:"array"});
+ var wb = XLSX.read(data.data);
$scope.data = XLSX.utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]);
}, function(err) { console.log(err); });
});
@@ -308,3 +378,7 @@ app.controller('sheetjs', function($scope, $http) {
URL with a web browser (typically `http://localhost:8080`)
+
+[^1]: See [`$http`](https://docs.angularjs.org/api/ng/service/$http) in the AngularJS documentation.
+[^2]: See ["Workbook Object"](/docs/csf/book)
+[^3]: See ["Creating Directives"](https://docs.angularjs.org/guide/directive#creating-a-directive-that-manipulates-the-dom) in the AngularJS documentation.
\ No newline at end of file
diff --git a/docz/docs/03-demos/06-desktop/04-tauri.md b/docz/docs/03-demos/06-desktop/04-tauri.md
index b1620ad..b5969c9 100644
--- a/docz/docs/03-demos/06-desktop/04-tauri.md
+++ b/docz/docs/03-demos/06-desktop/04-tauri.md
@@ -257,7 +257,7 @@ This demo was tested in the following environments:
| OS and Version | Arch | Tauri | Date |
|:---------------|:-----|:---------|:-----------|
-| macOS 13.5.1 | x64 | `v1.5.0` | 2023-09-30 |
+| macOS 14.1.1 | x64 | `v1.5.6` | 2023-11-17 |
| macOS 14.0 | ARM | `v1.5.2` | 2023-10-18 |
| Windows 10 | x64 | `v1.5.0` | 2023-10-01 |
| Windows 11 | ARM | `v1.4.1` | 2023-09-26 |
@@ -287,14 +287,15 @@ If required dependencies are installed, the output will show a checkmark next to
```
[✔] Environment
- - OS: Mac OS 13.5.1 X64
+ - OS: Mac OS 14.1.1 X64
✔ Xcode Command Line Tools: installed
- ✔ rustc: 1.72.1 (d5c2e9c34 2023-09-13)
- ✔ Cargo: 1.72.1 (103a7ff2e 2023-08-15)
- ✔ rustup: 1.26.0+1046 (d4c684485 2023-08-30)
+ ✔ rustc: 1.74.0 (79e9716c9 2023-11-13)
+ ✔ cargo: 1.74.0 (ecb9851af 2023-10-18)
+ ✔ rustup: 1.26.0+198 (393e187b7 2023-11-16)
✔ Rust toolchain: stable-x86_64-apple-darwin (default)
- - node: 16.20.2
- - npm: 8.19.4
+ - node: 20.9.0
+ - npm: 10.1.0
+ - bun: 1.0.2
```
:::caution pass
@@ -309,17 +310,9 @@ build step will correctly detect the platform architecture.
1) Create a new Tauri app:
```bash
-npm create tauri-app
+npm create tauri-app@latest -- -m npm -t vue-ts SheetJSTauri -y
```
-When prompted:
-
-- Project Name: `SheetJSTauri`
-- Choose which language to use for your frontend: `TypeScript / JavaScript`
-- Choose your package manager: `npm`
-- Choose your UI template: `Vue`
-- Choose your UI flavor: `TypeScript`
-
2) Enter the directory and install dependencies:
{`\
@@ -378,17 +371,7 @@ At the end, it will print the path to the generated installer.
:::info pass
-During the last Linux test, the build had failed with an error:
-
-```
-'openssl/opensslv.h' file not found
-```
-
-This error was resolved installing OpenSSL. On Arch Linux and HoloOS:
-
-```bash
-sudo pacman -S openssl
-```
+If the build fails, see ["Troubleshooting"](#troubleshooting) for more details.
:::
@@ -428,6 +411,51 @@ The following features should be manually verified:
- Edit the file in a spreadsheet editor, then click "Load Data" and select the
edited file. The table will refresh with new contents.
+#### Troubleshooting
+
+:::note pass
+
+During the last Linux test, the build failed with the following error message:
+
+```
+'openssl/opensslv.h' file not found
+```
+
+This error was resolved installing OpenSSL. On Arch Linux and HoloOS:
+
+```bash
+sudo pacman -S openssl
+```
+
+:::
+
+:::note pass
+
+During the last macOS test, the build failed with the following error message:
+
+```
+ Error failed to bundle project: error running bundle_dmg.sh
+```
+
+The root cause of the error can be discovered by running
+
+```bash
+npm run tauri build -- --verbose
+```
+
+The most recent test failed with a message:
+
+```
+execution error: Not authorized to send Apple events to Finder
+```
+
+This error was resolved by allowing Terminal to control Finder.
+
+In the "System Settings" app, select "Privacy & Security" in the left column and
+select "Automation" in the body. Look for "Terminal", expand the section, and enable "Finder".
+
+:::
+
[^1]: See ["Security"](https://tauri.app/v1/references/architecture/security#allowing-api) in the Tauri documentation
[^2]: See [`FsAllowlistConfig`](https://tauri.app/v1/api/config/#fsallowlistconfig) in the Tauri documentation
[^3]: See [`DialogAllowlistConfig`](https://tauri.app/v1/api/config/#dialogallowlistconfig) in the Tauri documentation
diff --git a/docz/docs/03-demos/07-data/26-redis.md b/docz/docs/03-demos/07-data/26-redis.md
index bae4bef..ead32df 100644
--- a/docz/docs/03-demos/07-data/26-redis.md
+++ b/docz/docs/03-demos/07-data/26-redis.md
@@ -208,10 +208,10 @@ const aoa = [ ["Hash"], [key] ].concat(Object.entries(values));
## Complete Example
-:::note
+:::note Tested Deployments
-This demo was last tested on 2023 August 22 with Redis 7.2.0, Redis connector
-module 4.6.7 and NodeJS 20.5.1.
+This demo was last tested on 2023 November 18 with Redis 7.2.3, Redis connector
+module 4.6.10 and NodeJS 20.9.0.
:::
@@ -225,7 +225,7 @@ this demo also requires NodeJS version 18 or later.
0) Set up and start a local Redis server.
-:::note
+:::note pass
This demo was last tested on macOS. Redis was installed with:
@@ -254,7 +254,7 @@ curl -LO https://docs.sheetjs.com/nosql/SheetJSRedisTest.mjs
2) Install dependencies:
{`\
-npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz redis@4.6.7`}
+npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz redis@4.6.10`}
3) Run the test script:
diff --git a/docz/docs/03-demos/09-cloud/02-netsuite.md b/docz/docs/03-demos/09-cloud/02-netsuite.md
index 0bc9f48..dd0d10c 100644
--- a/docz/docs/03-demos/09-cloud/02-netsuite.md
+++ b/docz/docs/03-demos/09-cloud/02-netsuite.md
@@ -27,7 +27,7 @@ This demo was verified by NetSuite consultants in the following deployments:
| ScheduledScript | 2.1 | 2023-08-18 |
| Restlet | 2.1 | 2023-10-05 |
| Suitelet | 2.1 | 2023-10-27 |
-| MapReduceScript | 2.1 | 2023-07-31 |
+| MapReduceScript | 2.1 | 2023-11-16 |
:::
diff --git a/docz/docs/03-demos/index.md b/docz/docs/03-demos/index.md
index 11a0b76..ea89fb9 100644
--- a/docz/docs/03-demos/index.md
+++ b/docz/docs/03-demos/index.md
@@ -33,7 +33,7 @@ in the [issue tracker](https://git.sheetjs.com/sheetjs/docs.sheetjs.com/issues)
- [`React`](/docs/demos/frontend/react)
- [`Svelte`](/docs/demos/frontend/svelte)
- [`VueJS`](/docs/demos/frontend/vue)
-- [`Angular.JS`](/docs/demos/frontend/angularjs)
+- [`AngularJS`](/docs/demos/frontend/angularjs)
- [`Dojo`](/docs/demos/frontend/legacy#dojo-toolkit)
- [`Knockout`](/docs/demos/frontend/legacy#knockoutjs)
diff --git a/docz/static/dta/dta.min.js b/docz/static/dta/dta.min.js
index 6d47997..e7ffc1c 100644
--- a/docz/static/dta/dta.min.js
+++ b/docz/static/dta/dta.min.js
@@ -1,2 +1,2 @@
-var DTA=(()=>{var O=Object.defineProperty;var I=Object.getOwnPropertyDescriptor;var K=Object.getOwnPropertyNames;var J=Object.prototype.hasOwnProperty;var j=r=>O(r,"__esModule",{value:!0});var q=(r,t)=>{for(var s in t)O(r,s,{get:t[s],enumerable:!0})},z=(r,t,s,e)=>{if(t&&typeof t=="object"||typeof t=="function")for(let c of K(t))!J.call(r,c)&&(s||c!=="default")&&O(r,c,{get:()=>t[c],enumerable:!(e=I(t,c))||e.enumerable});return r};var H=(r=>(t,s)=>r&&r.get(t)||(s=z(j({}),t,1),r&&r.set(t,s),s))(typeof WeakMap!="undefined"?new WeakMap:0);var re={};q(re,{parse:()=>te,set_utils:()=>Q});var k;function Q(r){k=r}function W(r){return new DataView(r.buffer,r.byteOffset,r.byteLength)}function i(r,t){return r.str.slice(r.ptr,r.ptr+t.length)!=t?!1:(r.ptr+=t.length,!0)}function X(r,t){let s=r.str.indexOf(t,r.ptr);if(s==-1)throw new Error(`Expected ${t} after offset ${r.ptr}`);r.ptr=s+t.length}function p(r,t){let s=r.str.indexOf(t,r.ptr);if(s==-1)throw new Error(`Expected ${t} after offset ${r.ptr}`);let e=r.raw.slice(r.ptr,s),c={ptr:0,raw:e,str:r.str.slice(r.ptr,s),dv:W(e)};return r.ptr=s+t.length,c}function F(r,t){r.ptr+=8;let s=r.dv.getFloat64(r.ptr-8,t);return s>8988e304?null:s}function R(r,t){r.ptr+=4;let s=r.dv.getFloat32(r.ptr-4,t);return s>1701e35?null:s}function g(r,t){return r.ptr+=4,r.dv.getUint32(r.ptr-4,t)}function V(r,t){r.ptr+=4;let s=r.dv.getInt32(r.ptr-4,t);return s>2147483620?null:s}function P(r,t){return r.ptr+=2,r.dv.getUint16(r.ptr-2,t)}function C(r,t){r.ptr+=2;let s=r.dv.getInt16(r.ptr-2,t);return s>32740?null:s}function x(r){return r.raw[r.ptr++]}function G(r){let t=r.raw[r.ptr++];return t=t<128?t:t-256,t>100?null:t}var Y=["117","118"];function Z(r){let t="Not a DTA file",s=new TextDecoder("latin1").decode(r),e={ptr:0,raw:r,str:s,dv:W(r)},c=118,n=!0,b=0,S=0,$=0,D=0,M="",A="",T=[],d=[],h=[];if(!i(e,""))throw t;{if(!i(e,""))throw t;{if(!i(e,""))throw t;let o=p(e,"");if(Y.indexOf(o.str)==-1)throw`Unsupported DTA ${o.str} file`;c=+o.str}{if(!i(e,""))throw t;let o=p(e,"");switch(o.str){case"MSF":n=!1;break;case"LSF":n=!0;break;default:throw`Unsupported byteorder ${o.str}`}}{if(!i(e,""))throw t;let o=p(e,"");b=P(o,n)}{if(!i(e,""))throw t;let o=p(e,"");if(c==117)S=$=g(o,n);else{let a=g(o,n),l=g(o,n);S=n?($=a)+(D=l)*Math.pow(2,32):($=l)+(D=a)*Math.pow(2,32)}S>1e6&&console.error("More than 1 million observations -- extra rows will be dropped")}{if(!i(e,""),a=c>=118?2:1,l=a==1?x(o):P(o,n);if(l+a!=o.str.length)throw`Expected string length ${l} but actual length was ${o.str.length-a}`;l>0&&(M=new TextDecoder().decode(o.raw.slice(a)))}{if(!i(e,""))throw t;let o=p(e,""),a=x(o);if(a+1!=o.str.length)throw`Expected string length ${a} but actual length was ${o.str.length-1}`;a>0&&(A=o.str.slice(1))}if(!i(e,""))throw t}{if(!i(e,"")}let f=0;{if(!i(e,""))throw t;let o=p(e,"");if(o.raw.length!=2*b)throw`Expected variable_types length ${b*2}, found ${o.raw.length}`;for(;o.ptr=1&&a<=2045)f+=a;else switch(a){case 32768:f+=8;break;case 65526:f+=8;break;case 65527:f+=4;break;case 65528:f+=4;break;case 65529:f+=2;break;case 65530:f+=1;break;default:throw`Unsupported field type ${a}`}}}{if(!i(e,""))throw t;let o=p(e,""),a=c>=118?129:33;if(o.raw.length!=a*b)throw`Expected variable_types length ${b*a}, found ${o.raw.length}`;for(;o.ptr"))throw t;let o=p(e,"");if(o.raw.length!=2*b+2)throw`Expected sortlist length ${b*2+2}, found ${o.raw.length}`}{if(!i(e,""))throw t;let o=p(e,""),a=c>=118?57:49;if(o.raw.length!=a*b)throw`Expected formats length ${b*a}, found ${o.raw.length}`;for(;o.ptr"))throw t;let o=c>=118?129:33,a=p(e,"")}{if(!i(e,""))throw t;let o=c>=118?321:81,a=p(e,"")}{if(!i(e,""))throw t;for(;e.str.slice(e.ptr,e.ptr+4)=="";){e.ptr+=4;let o=g(e,n);if(e.ptr+=o,!i(e,""))throw t}if(!i(e,""))throw t}let _=k.aoa_to_sheet([d],{dense:!0});var U=[];{if(!i(e,""))throw t;for(let o=0;o=1&&u<=2045){let w=new TextDecoder().decode(e.raw.slice(e.ptr,e.ptr+u));w=w.replace(/\x00[\s\S]*/,""),a[l]=w,e.ptr+=u}else switch(u){case 65526:a[l]=F(e,n);break;case 65527:a[l]=R(e,n);break;case 65528:a[l]=V(e,n);break;case 65529:a[l]=C(e,n);break;case 65530:a[l]=G(e);break;case 32768:a[l]="##SheetJStrL##",U.push([o+1,l,e.raw.slice(e.ptr,e.ptr+8)]),e.ptr+=8;break;default:throw`Unsupported field type ${u} for ${d[l]}`}}k.sheet_add_aoa(_,[a],{origin:-1,sheetStubs:!0})}if(!i(e,""))throw t}{if(!i(e,""))throw t;let o=[];for(;e.raw[e.ptr]==71;){if(!i(e,"GSO"))throw t;let a=g(e,n),l=0;if(c==117)l=g(e,n);else{let v=g(e,n),m=g(e,n);l=n?v+m*Math.pow(2,32):m+v*Math.pow(2,32),l>1e6&&console.error("More than 1 million observations -- data will be dropped")}let u=x(e),w=g(e,n);o[l]||(o[l]=[]);let y="";u==129?(y=new TextDecoder("latin1").decode(e.raw.slice(e.ptr,e.ptr+w)),e.ptr+=w):(y=new TextDecoder("latin1").decode(e.raw.slice(e.ptr,e.ptr+w)).replace(/\x00$/,""),e.ptr+=w),o[l][a]=y}if(!i(e,""))throw t;U.forEach(([a,l,u])=>{let w=W(u),y=0,v=0;switch(c){case 117:y=w.getUint32(0,n),v=w.getUint32(4,n);break;case 118:case 120:{y=w.getUint16(0,n);let m=w.getUint16(2,n),E=w.getUint32(4,n);v=n?m+E*65536:E+m*2**32}break;case 119:case 121:{let m=w.getUint16(0,n),E=u[2];y=n?m+(E<<16):E+(m<<8);let B=u[3],L=w.getUint32(4,n);v=n?B+L*256:L+B*2**32}}_["!data"][a][l].v=o[v][y]})}{if(!i(e,""))throw t;let o=p(e,"")}if(!i(e,""))throw t;let N=k.book_new();return k.book_append_sheet(N,_,"Sheet1"),N}function ee(r){let t=r[0];switch(t){case 102:case 112:throw`Unsupported DTA ${t} file`;case 103:case 104:case 105:case 108:case 110:case 111:case 113:case 114:case 115:break;default:throw new Error("Not a DTA file")}let s={ptr:1,raw:r,str:"",dv:W(r)},e=!0,c=0,n=0,b="",S="",$=[],D=[],M=[];{let d=x(s);switch(d){case 1:e=!1;break;case 2:e=!0;break;default:throw`DTA ${t} Unexpected byteorder ${d}`}let h=x(s);if(h!=1)throw`DTA ${t} Unexpected filetype ${h}`;s.ptr++,c=P(s,e),n=g(s,e),s.ptr+=t>=108?81:32,t>=105&&(s.ptr+=18)}{let d=0;for(d=0;d=110?33:9;for(d=0;d=114?49:t>=105?12:7;for(d=0;d=110?33:9)*c}if(s.ptr+=(t>=106?81:32)*c,t>=105)for(;s.ptr=111?g:P)(s,e);if(d==0&&h==0)break;s.ptr+=h}let A=k.aoa_to_sheet([D],{dense:!0});for(let d=0;d=111&&_>=1&&_<=244){let U=new TextDecoder().decode(s.raw.slice(s.ptr,s.ptr+_));U=U.replace(/\x00[\s\S]*/,""),h[f]=U,s.ptr+=_}else switch(_){case 251:case 98:h[f]=G(s);break;case 252:case 105:h[f]=C(s,e);break;case 253:case 108:h[f]=V(s,e);break;case 254:case 102:h[f]=R(s,e);break;case 255:case 100:h[f]=F(s,e);break;default:throw`Unsupported field type ${_} for ${D[f]}`}}k.sheet_add_aoa(A,[h],{origin:-1,sheetStubs:!0})}let T=k.book_new();return k.book_append_sheet(T,A,"Sheet1"),T}function te(r){if(r[0]>=102&&r[0]<=115)return ee(r);if(r[0]===60)return Z(r);throw new Error("Not a DTA file")}return H(re);})();
+var DTA=(()=>{var O=Object.defineProperty;var I=Object.getOwnPropertyDescriptor;var K=Object.getOwnPropertyNames;var J=Object.prototype.hasOwnProperty;var j=r=>O(r,"__esModule",{value:!0});var q=(r,t)=>{for(var s in t)O(r,s,{get:t[s],enumerable:!0})},z=(r,t,s,e)=>{if(t&&typeof t=="object"||typeof t=="function")for(let c of K(t))!J.call(r,c)&&(s||c!=="default")&&O(r,c,{get:()=>t[c],enumerable:!(e=I(t,c))||e.enumerable});return r};var H=(r=>(t,s)=>r&&r.get(t)||(s=z(j({}),t,1),r&&r.set(t,s),s))(typeof WeakMap!="undefined"?new WeakMap:0);var re={};q(re,{parse:()=>te,set_utils:()=>Q});var x;function Q(r){x=r}function W(r){return new DataView(r.buffer,r.byteOffset,r.byteLength)}function i(r,t){return r.str.slice(r.ptr,r.ptr+t.length)!=t?!1:(r.ptr+=t.length,!0)}function X(r,t){let s=r.str.indexOf(t,r.ptr);if(s==-1)throw new Error(`Expected ${t} after offset ${r.ptr}`);r.ptr=s+t.length}function u(r,t){let s=r.str.indexOf(t,r.ptr);if(s==-1)throw new Error(`Expected ${t} after offset ${r.ptr}`);let e=r.raw.slice(r.ptr,s),c={ptr:0,raw:e,str:r.str.slice(r.ptr,s),dv:W(e)};return r.ptr=s+t.length,c}function L(r,t){r.ptr+=8;let s=r.dv.getFloat64(r.ptr-8,t);return s>8988e304?null:s}function R(r,t){r.ptr+=4;let s=r.dv.getFloat32(r.ptr-4,t);return s>1701e35?null:s}function _(r,t){return r.ptr+=4,r.dv.getUint32(r.ptr-4,t)}function V(r,t){r.ptr+=4;let s=r.dv.getInt32(r.ptr-4,t);return s>2147483620?null:s}function P(r,t){return r.ptr+=2,r.dv.getUint16(r.ptr-2,t)}function C(r,t){r.ptr+=2;let s=r.dv.getInt16(r.ptr-2,t);return s>32740?null:s}function $(r){return r.raw[r.ptr++]}function G(r){let t=r.raw[r.ptr++];return t=t<128?t:t-256,t>100?null:t}var Y=["117","118","119","120","121"];function Z(r){let t="Not a DTA file",s=new TextDecoder("latin1").decode(r),e={ptr:0,raw:r,str:s,dv:W(r)},c=118,n=!0,g=0,U=0,D=0,S=0,M="",A="",T=[],f=[],w=[];if(!i(e,""))throw t;{if(!i(e,""))throw t;{if(!i(e,""))throw t;let o=u(e,"");if(Y.indexOf(o.str)==-1)throw`Unsupported DTA ${o.str} file`;c=+o.str}{if(!i(e,""))throw t;let o=u(e,"");switch(o.str){case"MSF":n=!1;break;case"LSF":n=!0;break;default:throw`Unsupported byteorder ${o.str}`}}{if(!i(e,""))throw t;let o=u(e,"");g=P(o,n)}{if(!i(e,""))throw t;let o=u(e,"");if(c==117)U=D=_(o,n);else{let a=_(o,n),l=_(o,n);U=n?(D=a)+(S=l)*Math.pow(2,32):(D=l)+(S=a)*Math.pow(2,32)}U>1e6&&console.error("More than 1 million observations -- extra rows will be dropped")}{if(!i(e,""),a=c>=118?2:1,l=a==1?$(o):P(o,n);if(l+a!=o.str.length)throw`Expected string length ${l} but actual length was ${o.str.length-a}`;l>0&&(M=new TextDecoder().decode(o.raw.slice(a)))}{if(!i(e,""))throw t;let o=u(e,""),a=$(o);if(a+1!=o.str.length)throw`Expected string length ${a} but actual length was ${o.str.length-1}`;a>0&&(A=o.str.slice(1))}if(!i(e,""))throw t}{if(!i(e,"")}let d=0;{if(!i(e,""))throw t;let o=u(e,"");if(o.raw.length!=2*g)throw`Expected variable_types length ${g*2}, found ${o.raw.length}`;for(;o.ptr=1&&a<=2045)d+=a;else switch(a){case 32768:d+=8;break;case 65525:d+=0;break;case 65526:d+=8;break;case 65527:d+=4;break;case 65528:d+=4;break;case 65529:d+=2;break;case 65530:d+=1;break;default:throw`Unsupported field type ${a}`}}}{if(!i(e,""))throw t;let o=u(e,""),a=c>=118?129:33;if(o.raw.length!=a*g)throw`Expected variable_types length ${g*a}, found ${o.raw.length}`;for(;o.ptr"))throw t;let o=u(e,"");if(o.raw.length!=(2*g+2)*(c==119||c==121?2:1))throw`Expected sortlist length ${g*2+2}, found ${o.raw.length}`}{if(!i(e,""))throw t;let o=u(e,""),a=c>=118?57:49;if(o.raw.length!=a*g)throw`Expected formats length ${g*a}, found ${o.raw.length}`;for(;o.ptr"))throw t;let o=c>=118?129:33,a=u(e,"")}{if(!i(e,""))throw t;let o=c>=118?321:81,a=u(e,"")}{if(!i(e,""))throw t;for(;e.str.slice(e.ptr,e.ptr+4)=="";){e.ptr+=4;let o=_(e,n);if(e.ptr+=o,!i(e,""))throw t}if(!i(e,""))throw t}let p=x.aoa_to_sheet([f],{dense:!0});var k=[];{if(!i(e,""))throw t;for(let o=0;o=1&&b<=2045){let h=new TextDecoder().decode(e.raw.slice(e.ptr,e.ptr+b));h=h.replace(/\x00[\s\S]*/,""),a[l]=h,e.ptr+=b}else switch(b){case 65525:e.ptr+=0;break;case 65526:a[l]=L(e,n);break;case 65527:a[l]=R(e,n);break;case 65528:a[l]=V(e,n);break;case 65529:a[l]=C(e,n);break;case 65530:a[l]=G(e);break;case 32768:a[l]="##SheetJStrL##",k.push([o+1,l,e.raw.slice(e.ptr,e.ptr+8)]),e.ptr+=8;break;default:throw`Unsupported field type ${b} for ${f[l]}`}}x.sheet_add_aoa(p,[a],{origin:-1,sheetStubs:!0})}if(!i(e,""))throw t}{if(!i(e,""))throw t;let o=[];for(;e.raw[e.ptr]==71;){if(!i(e,"GSO"))throw t;let a=_(e,n),l=0;if(c==117)l=_(e,n);else{let v=_(e,n),m=_(e,n);l=n?v+m*Math.pow(2,32):m+v*Math.pow(2,32),l>1e6&&console.error("More than 1 million observations -- data will be dropped")}let b=$(e),h=_(e,n);o[l]||(o[l]=[]);let y="";b==129?(y=new TextDecoder("latin1").decode(e.raw.slice(e.ptr,e.ptr+h)),e.ptr+=h):(y=new TextDecoder("latin1").decode(e.raw.slice(e.ptr,e.ptr+h)).replace(/\x00$/,""),e.ptr+=h),o[l][a]=y}if(!i(e,""))throw t;k.forEach(([a,l,b])=>{let h=W(b),y=0,v=0;switch(c){case 117:y=h.getUint32(0,n),v=h.getUint32(4,n);break;case 118:case 120:{y=h.getUint16(0,n);let m=h.getUint16(2,n),E=h.getUint32(4,n);v=n?m+E*65536:E+m*2**32}break;case 119:case 121:{let m=h.getUint16(0,n),E=b[2];y=n?m+(E<<16):E+(m<<8);let N=b[3],B=h.getUint32(4,n);v=n?N+B*256:B+N*2**32}}p["!data"][a][l].v=o[v][y]})}{if(!i(e,""))throw t;let o=u(e,"")}if(!i(e,""))throw t;let F=x.book_new();return x.book_append_sheet(F,p,"Sheet1"),F}function ee(r){let t=r[0];switch(t){case 102:case 103:case 104:case 105:case 108:case 110:case 111:case 112:case 113:case 114:case 115:break;default:throw new Error("Not a DTA file")}let s={ptr:1,raw:r,str:"",dv:W(r)},e=!0,c=0,n=0,g="",U="",D=[],S=[],M=[];{let f=$(s);switch(f){case 1:e=!1;break;case 2:e=!0;break;default:throw`DTA ${t} Unexpected byteorder ${f}`}let w=$(s);if(w!=1)throw`DTA ${t} Unexpected filetype ${w}`;s.ptr++,c=P(s,e),n=_(s,e),s.ptr+=t>=108?81:t>=103?32:30,t>=105&&(s.ptr+=18)}{let f=0;for(f=0;f=110?33:9;for(f=0;f=114?49:t>=105?12:7;for(f=0;f=110?33:9)*c}if(s.ptr+=(t>=106?81:32)*c,t>=105)for(;s.ptr=111?_:P)(s,e);if(f==0&&w==0)break;s.ptr+=w}let A=x.aoa_to_sheet([S],{dense:!0});for(let f=0;f=111&&p>=1&&p<=244){let k=new TextDecoder().decode(s.raw.slice(s.ptr,s.ptr+p));k=k.replace(/\x00[\s\S]*/,""),w[d]=k,s.ptr+=p}else if(t<=110&&p>=128){let k=new TextDecoder().decode(s.raw.slice(s.ptr,s.ptr+p-127));k=k.replace(/\x00[\s\S]*/,""),w[d]=k,s.ptr+=p-127}else switch(p){case 251:case 98:w[d]=G(s);break;case 252:case 105:w[d]=C(s,e);break;case 253:case 108:w[d]=V(s,e);break;case 254:case 102:w[d]=R(s,e);break;case 255:case 100:w[d]=L(s,e);break;default:throw`Unsupported field type ${p} for ${S[d]}`}}x.sheet_add_aoa(A,[w],{origin:-1,sheetStubs:!0})}let T=x.book_new();return x.book_append_sheet(T,A,"Sheet1"),T}function te(r){if(r[0]>=102&&r[0]<=115)return ee(r);if(r[0]===60)return Z(r);throw new Error("Not a DTA file")}return H(re);})();
//# sourceMappingURL=dta.min.js.map