Compare commits

..

1 Commits

Author SHA1 Message Date
Nicolás Hatcher
dcfee794b9 UPDATE[docs]: Compatibility and other engines 2025-01-04 09:46:26 +01:00
206 changed files with 2878 additions and 18585 deletions

View File

@@ -1,449 +0,0 @@
name: nodejs
env:
DEBUG: napi:*
APP_NAME: nodejs
MACOSX_DEPLOYMENT_TARGET: '10.13'
permissions:
contents: write
id-token: write
'on':
workflow_dispatch:
inputs:
publish:
description: "Publish to npm"
required: true
type: choice
options:
- yes
- no
default: "no"
defaults:
run:
working-directory: ./bindings/nodejs
jobs:
build:
strategy:
fail-fast: false
matrix:
settings:
- host: macos-latest
target: x86_64-apple-darwin
build: yarn build --target x86_64-apple-darwin
- host: windows-latest
build: yarn build --target x86_64-pc-windows-msvc
target: x86_64-pc-windows-msvc
- host: ubuntu-latest
target: x86_64-unknown-linux-gnu
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian
build: yarn build --target x86_64-unknown-linux-gnu
- host: ubuntu-latest
target: x86_64-unknown-linux-musl
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine
build: yarn build --target x86_64-unknown-linux-musl
- host: macos-latest
target: aarch64-apple-darwin
build: yarn build --target aarch64-apple-darwin
- host: ubuntu-latest
target: aarch64-unknown-linux-gnu
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian-aarch64
build: yarn build --target aarch64-unknown-linux-gnu
- host: ubuntu-latest
target: armv7-unknown-linux-gnueabihf
setup: |
sudo apt-get update
sudo apt-get install gcc-arm-linux-gnueabihf -y
build: yarn build --target armv7-unknown-linux-gnueabihf
- host: ubuntu-latest
target: armv7-unknown-linux-musleabihf
build: yarn build --target armv7-unknown-linux-musleabihf
- host: ubuntu-latest
target: aarch64-linux-android
build: yarn build --target aarch64-linux-android
- host: ubuntu-latest
target: armv7-linux-androideabi
build: yarn build --target armv7-linux-androideabi
- host: ubuntu-latest
target: aarch64-unknown-linux-musl
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine
build: |-
set -e &&
rustup target add aarch64-unknown-linux-musl &&
yarn build --target aarch64-unknown-linux-musl
- host: windows-latest
target: aarch64-pc-windows-msvc
build: yarn build --target aarch64-pc-windows-msvc
- host: ubuntu-latest
target: riscv64gc-unknown-linux-gnu
setup: |
sudo apt-get update
sudo apt-get install gcc-riscv64-linux-gnu -y
build: yarn build --target riscv64gc-unknown-linux-gnu
name: stable - ${{ matrix.settings.target }} - node@20
runs-on: ${{ matrix.settings.host }}
defaults:
run:
working-directory: ./bindings/nodejs
steps:
- uses: actions/checkout@v4
- name: Setup node
uses: actions/setup-node@v4
if: ${{ !matrix.settings.docker }}
with:
node-version: 20
cache: yarn
cache-dependency-path: "bindings/nodejs"
- name: Install
uses: dtolnay/rust-toolchain@stable
if: ${{ !matrix.settings.docker }}
with:
toolchain: stable
targets: ${{ matrix.settings.target }}
- name: Cache cargo
uses: actions/cache@v4
with:
path: |
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
.cargo-cache
target/
key: ${{ matrix.settings.target }}-cargo-${{ matrix.settings.host }}
- uses: goto-bus-stop/setup-zig@v2
if: ${{ matrix.settings.target == 'armv7-unknown-linux-gnueabihf' || matrix.settings.target == 'armv7-unknown-linux-musleabihf' }}
with:
version: 0.13.0
- name: Setup toolchain
run: ${{ matrix.settings.setup }}
if: ${{ matrix.settings.setup }}
shell: bash
- name: Install dependencies
run: yarn install
- name: Build in docker
uses: addnab/docker-run-action@v3
if: ${{ matrix.settings.docker }}
with:
image: ${{ matrix.settings.docker }}
options: '--user 0:0 -v ${{ github.workspace }}/.cargo-cache/git/db:/usr/local/cargo/git/db -v ${{ github.workspace }}/.cargo/registry/cache:/usr/local/cargo/registry/cache -v ${{ github.workspace }}/.cargo/registry/index:/usr/local/cargo/registry/index -v ${{ github.workspace }}:/build -w /build/bindings/nodejs'
run: ${{ matrix.settings.build }}
- name: Build
run: ${{ matrix.settings.build }}
if: ${{ !matrix.settings.docker }}
shell: bash
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: bindings-${{ matrix.settings.target }}
path: bindings/nodejs/${{ env.APP_NAME }}.*.node
if-no-files-found: error
test-macOS-windows-binding:
name: Test bindings on ${{ matrix.settings.target }} - node@${{ matrix.node }}
needs:
- build
strategy:
fail-fast: false
matrix:
settings:
- host: macos-latest
target: x86_64-apple-darwin
- host: windows-latest
target: x86_64-pc-windows-msvc
node:
- '18'
- '20'
runs-on: ${{ matrix.settings.host }}
defaults:
run:
working-directory: ./bindings/nodejs
steps:
- uses: actions/checkout@v4
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: yarn
cache-dependency-path: "bindings/nodejs"
architecture: x64
- name: Install dependencies
run: yarn install
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: bindings-${{ matrix.settings.target }}
path: bindings/nodejs/
- name: List packages
run: ls -R .
shell: bash
- name: Test bindings
run: yarn test
test-linux-x64-gnu-binding:
name: Test bindings on Linux-x64-gnu - node@${{ matrix.node }}
needs:
- build
strategy:
fail-fast: false
matrix:
node:
- '18'
- '20'
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./bindings/nodejs
steps:
- uses: actions/checkout@v4
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: yarn
cache-dependency-path: "bindings/nodejs"
- name: Install dependencies
run: yarn install
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: bindings-x86_64-unknown-linux-gnu
path: bindings/nodejs/
- name: List packages
run: ls -R .
shell: bash
- name: Test bindings
run: docker run --rm -v $(pwd):/build -w /build/bindings/nodejs node:${{ matrix.node }}-slim yarn test
test-linux-x64-musl-binding:
name: Test bindings on x86_64-unknown-linux-musl - node@${{ matrix.node }}
needs:
- build
strategy:
fail-fast: false
matrix:
node:
- '18'
- '20'
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./bindings/nodejs
steps:
- uses: actions/checkout@v4
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: yarn
cache-dependency-path: "bindings/nodejs"
- name: Install dependencies
run: |
yarn config set supportedArchitectures.libc "musl"
yarn install
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: bindings-x86_64-unknown-linux-musl
path: bindings/nodejs/
- name: List packages
run: ls -R .
shell: bash
- name: Test bindings
run: docker run --rm -v $(pwd):/build -w /build/bindings/nodejs node:${{ matrix.node }}-alpine yarn test
test-linux-aarch64-gnu-binding:
name: Test bindings on aarch64-unknown-linux-gnu - node@${{ matrix.node }}
needs:
- build
strategy:
fail-fast: false
matrix:
node:
- '18'
- '20'
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./bindings/nodejs
steps:
- uses: actions/checkout@v4
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: bindings-aarch64-unknown-linux-gnu
path: bindings/nodejs/
- name: List packages
run: ls -R .
shell: bash
- name: Install dependencies
run: |
yarn config set supportedArchitectures.cpu "arm64"
yarn config set supportedArchitectures.libc "glibc"
yarn install
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: arm64
- run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
- name: Setup and run tests
uses: addnab/docker-run-action@v3
with:
image: node:${{ matrix.node }}-slim
options: '--platform linux/arm64 -v ${{ github.workspace }}:/build -w /build/bindings/nodejs'
run: |
set -e
yarn test
ls -la
test-linux-aarch64-musl-binding:
name: Test bindings on aarch64-unknown-linux-musl - node@${{ matrix.node }}
needs:
- build
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./bindings/nodejs
steps:
- uses: actions/checkout@v4
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: bindings-aarch64-unknown-linux-musl
path: bindings/nodejs/
- name: List packages
run: ls -R .
shell: bash
- name: Install dependencies
run: |
yarn config set supportedArchitectures.cpu "arm64"
yarn config set supportedArchitectures.libc "musl"
yarn install
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: arm64
- run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
- name: Setup and run tests
uses: addnab/docker-run-action@v3
with:
image: node:lts-alpine
options: '--platform linux/arm64 -v ${{ github.workspace }}:/build -w /build/bindings/nodejs'
run: |
set -e
yarn test
test-linux-arm-gnueabihf-binding:
name: Test bindings on armv7-unknown-linux-gnueabihf - node@${{ matrix.node }}
needs:
- build
strategy:
fail-fast: false
matrix:
node:
- '18'
- '20'
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./bindings/nodejs
steps:
- uses: actions/checkout@v4
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: bindings-armv7-unknown-linux-gnueabihf
path: bindings/nodejs/
- name: List packages
run: ls -R .
shell: bash
- name: Install dependencies
run: |
yarn config set supportedArchitectures.cpu "arm"
yarn install
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: arm
- run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
- name: Setup and run tests
uses: addnab/docker-run-action@v3
with:
image: node:${{ matrix.node }}-bullseye-slim
options: '--platform linux/arm/v7 -v ${{ github.workspace }}:/build -w /build/bindings/nodejs'
run: |
set -e
yarn test
ls -la
universal-macOS:
name: Build universal macOS binary
needs:
- build
runs-on: macos-latest
defaults:
run:
working-directory: ./bindings/nodejs
steps:
- uses: actions/checkout@v4
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 20
cache: yarn
cache-dependency-path: "bindings/nodejs"
- name: Install dependencies
run: yarn install
- name: Download macOS x64 artifact
uses: actions/download-artifact@v4
with:
name: bindings-x86_64-apple-darwin
path: bindings/nodejs/artifacts
- name: Download macOS arm64 artifact
uses: actions/download-artifact@v4
with:
name: bindings-aarch64-apple-darwin
path: bindings/nodejs/artifacts
- name: Combine binaries
run: yarn universal
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: bindings-universal-apple-darwin
path: bindings/nodejs/${{ env.APP_NAME }}.*.node
if-no-files-found: error
publish:
name: Publish
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./bindings/nodejs
needs:
- test-macOS-windows-binding
- test-linux-x64-gnu-binding
- test-linux-x64-musl-binding
- test-linux-aarch64-gnu-binding
- test-linux-aarch64-musl-binding
- test-linux-arm-gnueabihf-binding
- universal-macOS
steps:
- uses: actions/checkout@v4
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 20
cache: yarn
cache-dependency-path: "bindings/nodejs"
- name: Install dependencies
run: yarn install
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: bindings/nodejs/artifacts
- name: Move artifacts
run: yarn artifacts
- name: List packages
run: ls -R ./npm
shell: bash
- name: Publish
run: |
npm config set provenance true
if [ "${{ github.event.inputs.publish }}" = "yes" ]; then
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc
npm publish --access public
else
echo "Not a release, skipping publish"
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

1
.gitignore vendored
View File

@@ -1,3 +1,2 @@
target/*
**/node_modules/**
.DS_Store

145
Cargo.lock generated
View File

@@ -85,12 +85,6 @@ dependencies = [
"syn",
]
[[package]]
name = "bitflags"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
[[package]]
name = "block-buffer"
version = "0.10.4"
@@ -216,15 +210,6 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
[[package]]
name = "convert_case"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.6"
@@ -286,16 +271,6 @@ dependencies = [
"memchr",
]
[[package]]
name = "ctor"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "deranged"
version = "0.3.11"
@@ -414,7 +389,7 @@ dependencies = [
[[package]]
name = "ironcalc"
version = "0.3.0"
version = "0.2.0"
dependencies = [
"bitcode",
"chrono",
@@ -430,7 +405,7 @@ dependencies = [
[[package]]
name = "ironcalc_base"
version = "0.3.0"
version = "0.2.0"
dependencies = [
"bitcode",
"chrono",
@@ -446,17 +421,6 @@ dependencies = [
"serde_json",
]
[[package]]
name = "ironcalc_nodejs"
version = "0.3.0"
dependencies = [
"ironcalc",
"napi",
"napi-build",
"napi-derive",
"serde",
]
[[package]]
name = "itertools"
version = "0.12.1"
@@ -496,16 +460,6 @@ version = "0.2.153"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "libloading"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
dependencies = [
"cfg-if",
"windows-targets",
]
[[package]]
name = "log"
version = "0.4.21"
@@ -536,65 +490,6 @@ dependencies = [
"adler",
]
[[package]]
name = "napi"
version = "2.16.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "214f07a80874bb96a8433b3cdfc84980d56c7b02e1a0d7ba4ba0db5cef785e2b"
dependencies = [
"bitflags",
"ctor",
"napi-derive",
"napi-sys",
"once_cell",
"serde",
"serde_json",
]
[[package]]
name = "napi-build"
version = "2.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db836caddef23662b94e16bf1f26c40eceb09d6aee5d5b06a7ac199320b69b19"
[[package]]
name = "napi-derive"
version = "2.16.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cbe2585d8ac223f7d34f13701434b9d5f4eb9c332cccce8dee57ea18ab8ab0c"
dependencies = [
"cfg-if",
"convert_case",
"napi-derive-backend",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "napi-derive-backend"
version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1639aaa9eeb76e91c6ae66da8ce3e89e921cd3885e99ec85f4abacae72fc91bf"
dependencies = [
"convert_case",
"once_cell",
"proc-macro2",
"quote",
"regex",
"semver",
"syn",
]
[[package]]
name = "napi-sys"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "427802e8ec3a734331fec1035594a210ce1ff4dc5bc1950530920ab717964ea3"
dependencies = [
"libloading",
]
[[package]]
name = "num-conv"
version = "0.1.0"
@@ -721,9 +616,9 @@ dependencies = [
[[package]]
name = "pyo3"
version = "0.23.4"
version = "0.22.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57fe09249128b3173d092de9523eaa75136bf7ba85e0d69eca241c7939c933cc"
checksum = "15ee168e30649f7f234c3d49ef5a7a6cbf5134289bc46c29ff3155fa3221c225"
dependencies = [
"cfg-if",
"indoc",
@@ -739,9 +634,9 @@ dependencies = [
[[package]]
name = "pyo3-build-config"
version = "0.23.4"
version = "0.22.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cd3927b5a78757a0d71aa9dff669f903b1eb64b54142a9bd9f757f8fde65fd7"
checksum = "e61cef80755fe9e46bb8a0b8f20752ca7676dcc07a5277d8b7768c6172e529b3"
dependencies = [
"once_cell",
"target-lexicon",
@@ -749,9 +644,9 @@ dependencies = [
[[package]]
name = "pyo3-ffi"
version = "0.23.4"
version = "0.22.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dab6bb2102bd8f991e7749f130a70d05dd557613e39ed2deeee8e9ca0c4d548d"
checksum = "67ce096073ec5405f5ee2b8b31f03a68e02aa10d5d4f565eca04acc41931fa1c"
dependencies = [
"libc",
"pyo3-build-config",
@@ -759,9 +654,9 @@ dependencies = [
[[package]]
name = "pyo3-macros"
version = "0.23.4"
version = "0.22.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91871864b353fd5ffcb3f91f2f703a22a9797c91b9ab497b1acac7b07ae509c7"
checksum = "2440c6d12bc8f3ae39f1e775266fa5122fd0c8891ce7520fa6048e683ad3de28"
dependencies = [
"proc-macro2",
"pyo3-macros-backend",
@@ -771,9 +666,9 @@ dependencies = [
[[package]]
name = "pyo3-macros-backend"
version = "0.23.4"
version = "0.22.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43abc3b80bc20f3facd86cd3c60beed58c3e2aa26213f3cda368de39c60a27e4"
checksum = "1be962f0e06da8f8465729ea2cb71a416d2257dff56cbe40a70d3e62a93ae5d1"
dependencies = [
"heck",
"proc-macro2",
@@ -784,7 +679,7 @@ dependencies = [
[[package]]
name = "pyroncalc"
version = "0.3.0"
version = "0.1.2"
dependencies = [
"ironcalc",
"pyo3",
@@ -884,12 +779,6 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
[[package]]
name = "semver"
version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03"
[[package]]
name = "serde"
version = "1.0.197"
@@ -1034,12 +923,6 @@ version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unicode-segmentation"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
[[package]]
name = "unindent"
version = "0.2.3"
@@ -1070,7 +953,7 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm"
version = "0.3.0"
version = "0.1.3"
dependencies = [
"ironcalc_base",
"serde",

View File

@@ -6,12 +6,10 @@ members = [
"xlsx",
"bindings/wasm",
"bindings/python",
"bindings/nodejs",
]
exclude = [
"generate_locale",
"webapp/app.ironcalc.com/server",
]
[profile.release]

View File

@@ -2,8 +2,7 @@
lint:
cargo fmt -- --check
cargo clippy --all-targets --all-features -- -W clippy::unwrap_used -W clippy::expect_used -W clippy::panic -D warnings
cd webapp/IronCalc/ && npm install && npm run check
cd webapp/app.ironcalc.com/frontend/ && npm install && npm run check
cd webapp && npm install && npm run check
.PHONY: format
format:
@@ -16,7 +15,7 @@ tests: lint
# Regretabbly we need to build the wasm twice, once for the nodejs tests
# and a second one for the vitest.
cd bindings/wasm/ && wasm-pack build --target nodejs && node tests/test.mjs && make
cd webapp/IronCalc/ && npm run test
cd webapp && npm run test
cd bindings/python && ./run_tests.sh && ./run_examples.sh
.PHONY: remove-artifacts

View File

@@ -1,11 +1,11 @@
[package]
name = "ironcalc_base"
version = "0.3.0"
version = "0.2.0"
authors = ["Nicolás Hatcher <nicolas@theuniverse.today>"]
edition = "2021"
homepage = "https://www.ironcalc.com"
repository = "https://github.com/ironcalc/ironcalc/"
description = "Open source spreadsheet engine"
description = "The democratization of spreadsheets"
license = "MIT OR Apache-2.0"
readme = "README.md"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View File

@@ -188,7 +188,10 @@ impl Model {
node: &Node,
cell: CellReferenceIndex,
) -> Result<(f64, f64, Suffix), CalcResult> {
let value = self.get_string(node, cell)?;
let value = match self.get_string(node, cell) {
Ok(s) => s,
Err(s) => return Err(s),
};
if value.is_empty() {
return Ok((0.0, 0.0, Suffix::I));
}

View File

@@ -14,8 +14,14 @@ use super::financial_util::{compute_irr, compute_npv, compute_rate, compute_xirr
// https://github.com/apache/openoffice/blob/c014b5f2b55cff8d4b0c952d5c16d62ecde09ca1/main/scaddins/source/analysis/financial.cxx
fn is_less_than_one_year(start_date: i64, end_date: i64) -> Result<bool, String> {
let end = from_excel_date(end_date)?;
let start = from_excel_date(start_date)?;
let end = match from_excel_date(end_date) {
Ok(s) => s,
Err(s) => return Err(s),
};
let start = match from_excel_date(start_date) {
Ok(s) => s,
Err(s) => return Err(s),
};
if end_date - start_date < 365 {
return Ok(true);
}

View File

@@ -960,7 +960,10 @@ impl Model {
}
}
}
let sheet = self.get_sheet_index_by_name(&sheet_name)?;
let sheet = match self.get_sheet_index_by_name(&sheet_name) {
Some(s) => s,
None => return None,
};
let row = match row.parse::<i32>() {
Ok(r) => r,
Err(_) => return None,

View File

@@ -1,5 +0,0 @@
[target.aarch64-unknown-linux-musl]
linker = "aarch64-linux-musl-gcc"
rustflags = ["-C", "target-feature=-crt-static"]
[target.x86_64-pc-windows-msvc]
rustflags = ["-C", "target-feature=+crt-static"]

View File

@@ -1,197 +0,0 @@
# Created by https://www.toptal.com/developers/gitignore/api/node
# Edit at https://www.toptal.com/developers/gitignore?templates=node
### Node ###
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# Next.js build output
.next
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# End of https://www.toptal.com/developers/gitignore/api/node
# Created by https://www.toptal.com/developers/gitignore/api/macos
# Edit at https://www.toptal.com/developers/gitignore?templates=macos
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### macOS Patch ###
# iCloud generated files
*.icloud
# End of https://www.toptal.com/developers/gitignore/api/macos
# Created by https://www.toptal.com/developers/gitignore/api/windows
# Edit at https://www.toptal.com/developers/gitignore?templates=windows
### Windows ###
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# End of https://www.toptal.com/developers/gitignore/api/windows
#Added by cargo
/target
Cargo.lock
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
*.node

View File

@@ -1,13 +0,0 @@
target
Cargo.lock
.cargo
.github
npm
.eslintrc
.prettierignore
rustfmt.toml
yarn.lock
*.node
.yarn
__test__
renovate.json

View File

@@ -1 +0,0 @@
nodeLinker: node-modules

View File

@@ -1,18 +0,0 @@
[package]
edition = "2021"
name = "ironcalc_nodejs"
version = "0.3.0"
[lib]
crate-type = ["cdylib"]
[dependencies]
# Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix
napi = { version = "2.12.2", default-features = false, features = ["napi4", "serde-json"] }
napi-derive = "2.12.2"
ironcalc = { path = "../../xlsx", version = "0.3.0" }
serde = { version = "1.0", features = ["derive"] }
[build-dependencies]
napi-build = "2.0.1"

View File

@@ -1,18 +0,0 @@
# IronCalc nodejs bindingds
Example usage:
```javascript
import { Model } from '@ironcalc/wasm';
const model = new Model("Workbook1", "en", "UTC");
model.setUserInput(0, 1, 1, "=1+1");
const result1 = model.getFormattedCellValue(0, 1, 1);
console.log('Cell value', result1);
let result2 = model.getCellStyle(0, 1, 1);
console.log('Cell style', result2);
```

View File

@@ -1,11 +0,0 @@
import test from 'ava'
import { Model } from '../index.js';
test('sum from native', (t) => {
const model = new Model("Workbook1", "en", "UTC");
model.setUserInput(0, 1, 1, "=1+1");
t.is(model.getFormattedCellValue(0, 1, 1), '2');
});

View File

@@ -1,5 +0,0 @@
extern crate napi_build;
fn main() {
napi_build::setup();
}

View File

@@ -1,77 +0,0 @@
/* tslint:disable */
/* eslint-disable */
/* auto-generated by NAPI-RS */
export declare class Model {
constructor(name: string, locale: string, timezone: string)
static fromBytes(bytes: Uint8Array): Model
canUndo(): boolean
canRedo(): boolean
pauseEvaluation(): void
resumeEvaluation(): void
flushSendQueue(): Array<number>
applyExternalDiffs(diffs: Uint8Array): void
getCellContent(sheet: number, row: number, column: number): string
newSheet(): void
deleteSheet(sheet: number): void
hideSheet(sheet: number): void
unhideSheet(sheet: number): void
renameSheet(sheet: number, name: string): void
setSheetColor(sheet: number, color: string): void
rangeClearAll(sheet: number, startRow: number, startColumn: number, endRow: number, endColumn: number): void
rangeClearContents(sheet: number, startRow: number, startColumn: number, endRow: number, endColumn: number): void
insertRow(sheet: number, row: number): void
insertColumn(sheet: number, column: number): void
deleteRow(sheet: number, row: number): void
deleteColumn(sheet: number, column: number): void
setRowHeight(sheet: number, row: number, height: number): void
setColumnWidth(sheet: number, column: number, width: number): void
getRowHeight(sheet: number, row: number): number
getColumnWidth(sheet: number, column: number): number
setUserInput(sheet: number, row: number, column: number, input: string): void
getFormattedCellValue(sheet: number, row: number, column: number): string
getFrozenRowsCount(sheet: number): number
getFrozenColumnsCount(sheet: number): number
setFrozenRowsCount(sheet: number, count: number): void
setFrozenColumnsCount(sheet: number, count: number): void
updateRangeStyle(range: unknown, stylePath: string, value: string): void
getCellStyle(sheet: number, row: number, column: number): unknown
onPasteStyles(styles: unknown): void
getCellType(sheet: number, row: number, column: number): number
getWorksheetsProperties(): unknown
getSelectedSheet(): number
getSelectedCell(): Array<number>
getSelectedView(): unknown
setSelectedSheet(sheet: number): void
setSelectedCell(row: number, column: number): void
setSelectedRange(startRow: number, startColumn: number, endRow: number, endColumn: number): void
setTopLeftVisibleCell(topRow: number, topColumn: number): void
setShowGridLines(sheet: number, showGridLines: boolean): void
getShowGridLines(sheet: number): boolean
autoFillRows(sourceArea: unknown, toRow: number): void
autoFillColumns(sourceArea: unknown, toColumn: number): void
onArrowRight(): void
onArrowLeft(): void
onArrowUp(): void
onArrowDown(): void
onPageDown(): void
onPageUp(): void
setWindowWidth(windowWidth: number): void
setWindowHeight(windowHeight: number): void
getScrollX(): number
getScrollY(): number
onExpandSelectedRange(key: string): void
onAreaSelecting(targetRow: number, targetColumn: number): void
setAreaWithBorder(area: unknown, borderArea: unknown): void
toBytes(): Array<number>
getName(): string
setName(name: string): void
copyToClipboard(): unknown
pasteFromClipboard(sourceSheet: number, sourceRange: unknown, clipboard: unknown, isCut: boolean): void
pasteCsvText(area: unknown, csv: string): void
getDefinedNameList(): unknown
newDefinedName(name: string, scope: number | undefined | null, formula: string): void
updateDefinedName(name: string, scope: number | undefined | null, newName: string, newScope: number | undefined | null, newFormula: string): void
deleteDefinedName(name: string, scope?: number | undefined | null): void
}

View File

@@ -1,315 +0,0 @@
/* tslint:disable */
/* eslint-disable */
/* prettier-ignore */
/* auto-generated by NAPI-RS */
const { existsSync, readFileSync } = require('fs')
const { join } = require('path')
const { platform, arch } = process
let nativeBinding = null
let localFileExisted = false
let loadError = null
function isMusl() {
// For Node 10
if (!process.report || typeof process.report.getReport !== 'function') {
try {
const lddPath = require('child_process').execSync('which ldd').toString().trim()
return readFileSync(lddPath, 'utf8').includes('musl')
} catch (e) {
return true
}
} else {
const { glibcVersionRuntime } = process.report.getReport().header
return !glibcVersionRuntime
}
}
switch (platform) {
case 'android':
switch (arch) {
case 'arm64':
localFileExisted = existsSync(join(__dirname, 'nodejs.android-arm64.node'))
try {
if (localFileExisted) {
nativeBinding = require('./nodejs.android-arm64.node')
} else {
nativeBinding = require('@ironcalc/nodejs-android-arm64')
}
} catch (e) {
loadError = e
}
break
case 'arm':
localFileExisted = existsSync(join(__dirname, 'nodejs.android-arm-eabi.node'))
try {
if (localFileExisted) {
nativeBinding = require('./nodejs.android-arm-eabi.node')
} else {
nativeBinding = require('@ironcalc/nodejs-android-arm-eabi')
}
} catch (e) {
loadError = e
}
break
default:
throw new Error(`Unsupported architecture on Android ${arch}`)
}
break
case 'win32':
switch (arch) {
case 'x64':
localFileExisted = existsSync(
join(__dirname, 'nodejs.win32-x64-msvc.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./nodejs.win32-x64-msvc.node')
} else {
nativeBinding = require('@ironcalc/nodejs-win32-x64-msvc')
}
} catch (e) {
loadError = e
}
break
case 'ia32':
localFileExisted = existsSync(
join(__dirname, 'nodejs.win32-ia32-msvc.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./nodejs.win32-ia32-msvc.node')
} else {
nativeBinding = require('@ironcalc/nodejs-win32-ia32-msvc')
}
} catch (e) {
loadError = e
}
break
case 'arm64':
localFileExisted = existsSync(
join(__dirname, 'nodejs.win32-arm64-msvc.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./nodejs.win32-arm64-msvc.node')
} else {
nativeBinding = require('@ironcalc/nodejs-win32-arm64-msvc')
}
} catch (e) {
loadError = e
}
break
default:
throw new Error(`Unsupported architecture on Windows: ${arch}`)
}
break
case 'darwin':
localFileExisted = existsSync(join(__dirname, 'nodejs.darwin-universal.node'))
try {
if (localFileExisted) {
nativeBinding = require('./nodejs.darwin-universal.node')
} else {
nativeBinding = require('@ironcalc/nodejs-darwin-universal')
}
break
} catch {}
switch (arch) {
case 'x64':
localFileExisted = existsSync(join(__dirname, 'nodejs.darwin-x64.node'))
try {
if (localFileExisted) {
nativeBinding = require('./nodejs.darwin-x64.node')
} else {
nativeBinding = require('@ironcalc/nodejs-darwin-x64')
}
} catch (e) {
loadError = e
}
break
case 'arm64':
localFileExisted = existsSync(
join(__dirname, 'nodejs.darwin-arm64.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./nodejs.darwin-arm64.node')
} else {
nativeBinding = require('@ironcalc/nodejs-darwin-arm64')
}
} catch (e) {
loadError = e
}
break
default:
throw new Error(`Unsupported architecture on macOS: ${arch}`)
}
break
case 'freebsd':
if (arch !== 'x64') {
throw new Error(`Unsupported architecture on FreeBSD: ${arch}`)
}
localFileExisted = existsSync(join(__dirname, 'nodejs.freebsd-x64.node'))
try {
if (localFileExisted) {
nativeBinding = require('./nodejs.freebsd-x64.node')
} else {
nativeBinding = require('@ironcalc/nodejs-freebsd-x64')
}
} catch (e) {
loadError = e
}
break
case 'linux':
switch (arch) {
case 'x64':
if (isMusl()) {
localFileExisted = existsSync(
join(__dirname, 'nodejs.linux-x64-musl.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./nodejs.linux-x64-musl.node')
} else {
nativeBinding = require('@ironcalc/nodejs-linux-x64-musl')
}
} catch (e) {
loadError = e
}
} else {
localFileExisted = existsSync(
join(__dirname, 'nodejs.linux-x64-gnu.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./nodejs.linux-x64-gnu.node')
} else {
nativeBinding = require('@ironcalc/nodejs-linux-x64-gnu')
}
} catch (e) {
loadError = e
}
}
break
case 'arm64':
if (isMusl()) {
localFileExisted = existsSync(
join(__dirname, 'nodejs.linux-arm64-musl.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./nodejs.linux-arm64-musl.node')
} else {
nativeBinding = require('@ironcalc/nodejs-linux-arm64-musl')
}
} catch (e) {
loadError = e
}
} else {
localFileExisted = existsSync(
join(__dirname, 'nodejs.linux-arm64-gnu.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./nodejs.linux-arm64-gnu.node')
} else {
nativeBinding = require('@ironcalc/nodejs-linux-arm64-gnu')
}
} catch (e) {
loadError = e
}
}
break
case 'arm':
if (isMusl()) {
localFileExisted = existsSync(
join(__dirname, 'nodejs.linux-arm-musleabihf.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./nodejs.linux-arm-musleabihf.node')
} else {
nativeBinding = require('@ironcalc/nodejs-linux-arm-musleabihf')
}
} catch (e) {
loadError = e
}
} else {
localFileExisted = existsSync(
join(__dirname, 'nodejs.linux-arm-gnueabihf.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./nodejs.linux-arm-gnueabihf.node')
} else {
nativeBinding = require('@ironcalc/nodejs-linux-arm-gnueabihf')
}
} catch (e) {
loadError = e
}
}
break
case 'riscv64':
if (isMusl()) {
localFileExisted = existsSync(
join(__dirname, 'nodejs.linux-riscv64-musl.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./nodejs.linux-riscv64-musl.node')
} else {
nativeBinding = require('@ironcalc/nodejs-linux-riscv64-musl')
}
} catch (e) {
loadError = e
}
} else {
localFileExisted = existsSync(
join(__dirname, 'nodejs.linux-riscv64-gnu.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./nodejs.linux-riscv64-gnu.node')
} else {
nativeBinding = require('@ironcalc/nodejs-linux-riscv64-gnu')
}
} catch (e) {
loadError = e
}
}
break
case 's390x':
localFileExisted = existsSync(
join(__dirname, 'nodejs.linux-s390x-gnu.node')
)
try {
if (localFileExisted) {
nativeBinding = require('./nodejs.linux-s390x-gnu.node')
} else {
nativeBinding = require('@ironcalc/nodejs-linux-s390x-gnu')
}
} catch (e) {
loadError = e
}
break
default:
throw new Error(`Unsupported architecture on Linux: ${arch}`)
}
break
default:
throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`)
}
if (!nativeBinding) {
if (loadError) {
throw loadError
}
throw new Error(`Failed to load native binding`)
}
const { Model } = nativeBinding
module.exports.Model = Model

View File

@@ -1,11 +0,0 @@
import { Model } from './index.js'
const model = new Model("Workbook1", "en", "UTC");
model.setUserInput(0, 1, 1, "=1+1");
let t = model.getFormattedCellValue(0, 1, 1);
console.log('From native', t);
let t2 = model.getCellStyle(0, 1, 1);
console.log('From native', t2);

View File

@@ -1,3 +0,0 @@
# `@ironcalc/nodejs-android-arm-eabi`
This is the **armv7-linux-androideabi** binary for `@ironcalc/nodejs`

View File

@@ -1,18 +0,0 @@
{
"name": "@ironcalc/nodejs-android-arm-eabi",
"version": "0.2.0",
"os": [
"android"
],
"cpu": [
"arm"
],
"main": "nodejs.android-arm-eabi.node",
"files": [
"nodejs.android-arm-eabi.node"
],
"license": "MIT",
"engines": {
"node": ">= 10"
}
}

View File

@@ -1,3 +0,0 @@
# `@ironcalc/nodejs-android-arm64`
This is the **aarch64-linux-android** binary for `@ironcalc/nodejs`

View File

@@ -1,18 +0,0 @@
{
"name": "@ironcalc/nodejs-android-arm64",
"version": "0.2.0",
"os": [
"android"
],
"cpu": [
"arm64"
],
"main": "nodejs.android-arm64.node",
"files": [
"nodejs.android-arm64.node"
],
"license": "MIT",
"engines": {
"node": ">= 10"
}
}

View File

@@ -1,3 +0,0 @@
# `@ironcalc/nodejs-darwin-arm64`
This is the **aarch64-apple-darwin** binary for `@ironcalc/nodejs`

View File

@@ -1,18 +0,0 @@
{
"name": "@ironcalc/nodejs-darwin-arm64",
"version": "0.2.0",
"os": [
"darwin"
],
"cpu": [
"arm64"
],
"main": "nodejs.darwin-arm64.node",
"files": [
"nodejs.darwin-arm64.node"
],
"license": "MIT",
"engines": {
"node": ">= 10"
}
}

View File

@@ -1,3 +0,0 @@
# `@ironcalc/nodejs-darwin-universal`
This is the **universal-apple-darwin** binary for `@ironcalc/nodejs`

View File

@@ -1,15 +0,0 @@
{
"name": "@ironcalc/nodejs-darwin-universal",
"version": "0.2.0",
"os": [
"darwin"
],
"main": "nodejs.darwin-universal.node",
"files": [
"nodejs.darwin-universal.node"
],
"license": "MIT",
"engines": {
"node": ">= 10"
}
}

View File

@@ -1,3 +0,0 @@
# `@ironcalc/nodejs-darwin-x64`
This is the **x86_64-apple-darwin** binary for `@ironcalc/nodejs`

View File

@@ -1,18 +0,0 @@
{
"name": "@ironcalc/nodejs-darwin-x64",
"version": "0.2.0",
"os": [
"darwin"
],
"cpu": [
"x64"
],
"main": "nodejs.darwin-x64.node",
"files": [
"nodejs.darwin-x64.node"
],
"license": "MIT",
"engines": {
"node": ">= 10"
}
}

View File

@@ -1,3 +0,0 @@
# `@ironcalc/nodejs-linux-arm-gnueabihf`
This is the **armv7-unknown-linux-gnueabihf** binary for `@ironcalc/nodejs`

View File

@@ -1,18 +0,0 @@
{
"name": "@ironcalc/nodejs-linux-arm-gnueabihf",
"version": "0.2.0",
"os": [
"linux"
],
"cpu": [
"arm"
],
"main": "nodejs.linux-arm-gnueabihf.node",
"files": [
"nodejs.linux-arm-gnueabihf.node"
],
"license": "MIT",
"engines": {
"node": ">= 10"
}
}

View File

@@ -1,3 +0,0 @@
# `@ironcalc/nodejs-linux-arm-musleabihf`
This is the **armv7-unknown-linux-musleabihf** binary for `@ironcalc/nodejs`

View File

@@ -1,18 +0,0 @@
{
"name": "@ironcalc/nodejs-linux-arm-musleabihf",
"version": "0.2.0",
"os": [
"linux"
],
"cpu": [
"arm"
],
"main": "nodejs.linux-arm-musleabihf.node",
"files": [
"nodejs.linux-arm-musleabihf.node"
],
"license": "MIT",
"engines": {
"node": ">= 10"
}
}

View File

@@ -1,3 +0,0 @@
# `@ironcalc/nodejs-linux-arm64-gnu`
This is the **aarch64-unknown-linux-gnu** binary for `@ironcalc/nodejs`

View File

@@ -1,21 +0,0 @@
{
"name": "@ironcalc/nodejs-linux-arm64-gnu",
"version": "0.2.0",
"os": [
"linux"
],
"cpu": [
"arm64"
],
"main": "nodejs.linux-arm64-gnu.node",
"files": [
"nodejs.linux-arm64-gnu.node"
],
"license": "MIT",
"engines": {
"node": ">= 10"
},
"libc": [
"glibc"
]
}

View File

@@ -1,3 +0,0 @@
# `@ironcalc/nodejs-linux-arm64-musl`
This is the **aarch64-unknown-linux-musl** binary for `@ironcalc/nodejs`

View File

@@ -1,21 +0,0 @@
{
"name": "@ironcalc/nodejs-linux-arm64-musl",
"version": "0.2.0",
"os": [
"linux"
],
"cpu": [
"arm64"
],
"main": "nodejs.linux-arm64-musl.node",
"files": [
"nodejs.linux-arm64-musl.node"
],
"license": "MIT",
"engines": {
"node": ">= 10"
},
"libc": [
"musl"
]
}

View File

@@ -1,3 +0,0 @@
# `@ironcalc/nodejs-linux-riscv64-gnu`
This is the **riscv64gc-unknown-linux-gnu** binary for `@ironcalc/nodejs`

View File

@@ -1,21 +0,0 @@
{
"name": "@ironcalc/nodejs-linux-riscv64-gnu",
"version": "0.2.0",
"os": [
"linux"
],
"cpu": [
"riscv64"
],
"main": "nodejs.linux-riscv64-gnu.node",
"files": [
"nodejs.linux-riscv64-gnu.node"
],
"license": "MIT",
"engines": {
"node": ">= 10"
},
"libc": [
"glibc"
]
}

View File

@@ -1,3 +0,0 @@
# `@ironcalc/nodejs-linux-x64-gnu`
This is the **x86_64-unknown-linux-gnu** binary for `@ironcalc/nodejs`

View File

@@ -1,21 +0,0 @@
{
"name": "@ironcalc/nodejs-linux-x64-gnu",
"version": "0.2.0",
"os": [
"linux"
],
"cpu": [
"x64"
],
"main": "nodejs.linux-x64-gnu.node",
"files": [
"nodejs.linux-x64-gnu.node"
],
"license": "MIT",
"engines": {
"node": ">= 10"
},
"libc": [
"glibc"
]
}

View File

@@ -1,3 +0,0 @@
# `@ironcalc/nodejs-linux-x64-musl`
This is the **x86_64-unknown-linux-musl** binary for `@ironcalc/nodejs`

View File

@@ -1,21 +0,0 @@
{
"name": "@ironcalc/nodejs-linux-x64-musl",
"version": "0.2.0",
"os": [
"linux"
],
"cpu": [
"x64"
],
"main": "nodejs.linux-x64-musl.node",
"files": [
"nodejs.linux-x64-musl.node"
],
"license": "MIT",
"engines": {
"node": ">= 10"
},
"libc": [
"musl"
]
}

View File

@@ -1,3 +0,0 @@
# `@ironcalc/nodejs-win32-arm64-msvc`
This is the **aarch64-pc-windows-msvc** binary for `@ironcalc/nodejs`

View File

@@ -1,18 +0,0 @@
{
"name": "@ironcalc/nodejs-win32-arm64-msvc",
"version": "0.2.0",
"os": [
"win32"
],
"cpu": [
"arm64"
],
"main": "nodejs.win32-arm64-msvc.node",
"files": [
"nodejs.win32-arm64-msvc.node"
],
"license": "MIT",
"engines": {
"node": ">= 10"
}
}

View File

@@ -1,3 +0,0 @@
# `@ironcalc/nodejs-win32-x64-msvc`
This is the **x86_64-pc-windows-msvc** binary for `@ironcalc/nodejs`

View File

@@ -1,18 +0,0 @@
{
"name": "@ironcalc/nodejs-win32-x64-msvc",
"version": "0.2.0",
"os": [
"win32"
],
"cpu": [
"x64"
],
"main": "nodejs.win32-x64-msvc.node",
"files": [
"nodejs.win32-x64-msvc.node"
],
"license": "MIT",
"engines": {
"node": ">= 10"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,44 +0,0 @@
{
"name": "@ironcalc/nodejs",
"version": "0.3.0",
"main": "index.js",
"types": "index.d.ts",
"napi": {
"name": "nodejs",
"triples": {
"additional": [
"aarch64-apple-darwin",
"aarch64-linux-android",
"aarch64-unknown-linux-gnu",
"aarch64-unknown-linux-musl",
"aarch64-pc-windows-msvc",
"armv7-unknown-linux-gnueabihf",
"armv7-unknown-linux-musleabihf",
"x86_64-unknown-linux-musl",
"armv7-linux-androideabi",
"universal-apple-darwin",
"riscv64gc-unknown-linux-gnu"
]
}
},
"license": "MIT",
"devDependencies": {
"@napi-rs/cli": "^2.18.4",
"ava": "^6.0.1"
},
"ava": {
"timeout": "3m"
},
"engines": {
"node": ">= 10"
},
"scripts": {
"artifacts": "napi artifacts",
"build": "napi build --platform --release",
"build:debug": "napi build --platform",
"prepublishOnly": "napi prepublish -t npm",
"test": "ava",
"universal": "napi universal",
"version": "napi version"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,2 +0,0 @@
tab_spaces = 2
edition = "2021"

View File

@@ -1,623 +0,0 @@
#![deny(clippy::all)]
use serde::Serialize;
#[macro_use]
extern crate napi_derive;
use napi::{self, bindgen_prelude::*, JsUnknown, Result};
use ironcalc::base::{
expressions::types::Area,
types::{CellType, Style},
BorderArea, ClipboardData, UserModel as BaseModel,
};
#[derive(Serialize)]
struct DefinedName {
name: String,
scope: Option<u32>,
formula: String,
}
fn to_js_error(error: String) -> Error {
Error::new(Status::Unknown, error)
}
#[napi]
pub struct Model {
model: BaseModel,
}
#[napi]
impl Model {
#[napi(constructor)]
pub fn new(name: String, locale: String, timezone: String) -> Result<Self> {
let model = BaseModel::new_empty(&name, &locale, &timezone).map_err(to_js_error)?;
Ok(Self { model })
}
#[napi(factory)]
pub fn from_bytes(bytes: &[u8]) -> Result<Model> {
let model = BaseModel::from_bytes(bytes).map_err(to_js_error)?;
Ok(Model { model })
}
pub fn undo(&mut self) -> Result<()> {
self.model.undo().map_err(to_js_error)
}
pub fn redo(&mut self) -> Result<()> {
self.model.redo().map_err(to_js_error)
}
#[napi(js_name = "canUndo")]
pub fn can_undo(&self) -> bool {
self.model.can_undo()
}
#[napi(js_name = "canRedo")]
pub fn can_redo(&self) -> bool {
self.model.can_redo()
}
#[napi(js_name = "pauseEvaluation")]
pub fn pause_evaluation(&mut self) {
self.model.pause_evaluation()
}
#[napi(js_name = "resumeEvaluation")]
pub fn resume_evaluation(&mut self) {
self.model.resume_evaluation()
}
pub fn evaluate(&mut self) {
self.model.evaluate();
}
#[napi(js_name = "flushSendQueue")]
pub fn flush_send_queue(&mut self) -> Vec<u8> {
self.model.flush_send_queue()
}
#[napi(js_name = "applyExternalDiffs")]
pub fn apply_external_diffs(&mut self, diffs: &[u8]) -> Result<()> {
self.model.apply_external_diffs(diffs).map_err(to_js_error)
}
#[napi(js_name = "getCellContent")]
pub fn get_cell_content(&self, sheet: u32, row: i32, column: i32) -> Result<String> {
self
.model
.get_cell_content(sheet, row, column)
.map_err(to_js_error)
}
#[napi(js_name = "newSheet")]
pub fn new_sheet(&mut self) -> Result<()> {
self.model.new_sheet().map_err(to_js_error)
}
#[napi(js_name = "deleteSheet")]
pub fn delete_sheet(&mut self, sheet: u32) -> Result<()> {
self.model.delete_sheet(sheet).map_err(to_js_error)
}
#[napi(js_name = "hideSheet")]
pub fn hide_sheet(&mut self, sheet: u32) -> Result<()> {
self.model.hide_sheet(sheet).map_err(to_js_error)
}
#[napi(js_name = "unhideSheet")]
pub fn unhide_sheet(&mut self, sheet: u32) -> Result<()> {
self.model.unhide_sheet(sheet).map_err(to_js_error)
}
#[napi(js_name = "renameSheet")]
pub fn rename_sheet(&mut self, sheet: u32, name: String) -> Result<()> {
self.model.rename_sheet(sheet, &name).map_err(to_js_error)
}
#[napi(js_name = "setSheetColor")]
pub fn set_sheet_color(&mut self, sheet: u32, color: String) -> Result<()> {
self
.model
.set_sheet_color(sheet, &color)
.map_err(to_js_error)
}
#[napi(js_name = "rangeClearAll")]
pub fn range_clear_all(
&mut self,
sheet: u32,
start_row: i32,
start_column: i32,
end_row: i32,
end_column: i32,
) -> Result<()> {
let range = Area {
sheet,
row: start_row,
column: start_column,
width: end_column - start_column + 1,
height: end_row - start_row + 1,
};
self.model.range_clear_all(&range).map_err(to_js_error)
}
#[napi(js_name = "rangeClearContents")]
pub fn range_clear_contents(
&mut self,
sheet: u32,
start_row: i32,
start_column: i32,
end_row: i32,
end_column: i32,
) -> Result<()> {
let range = Area {
sheet,
row: start_row,
column: start_column,
width: end_column - start_column + 1,
height: end_row - start_row + 1,
};
self.model.range_clear_contents(&range).map_err(to_js_error)
}
#[napi(js_name = "insertRow")]
pub fn insert_row(&mut self, sheet: u32, row: i32) -> Result<()> {
self.model.insert_row(sheet, row).map_err(to_js_error)
}
#[napi(js_name = "insertColumn")]
pub fn insert_column(&mut self, sheet: u32, column: i32) -> Result<()> {
self.model.insert_column(sheet, column).map_err(to_js_error)
}
#[napi(js_name = "deleteRow")]
pub fn delete_row(&mut self, sheet: u32, row: i32) -> Result<()> {
self.model.delete_row(sheet, row).map_err(to_js_error)
}
#[napi(js_name = "deleteColumn")]
pub fn delete_column(&mut self, sheet: u32, column: i32) -> Result<()> {
self.model.delete_column(sheet, column).map_err(to_js_error)
}
#[napi(js_name = "setRowHeight")]
pub fn set_row_height(&mut self, sheet: u32, row: i32, height: f64) -> Result<()> {
self
.model
.set_row_height(sheet, row, height)
.map_err(to_js_error)
}
#[napi(js_name = "setColumnWidth")]
pub fn set_column_width(&mut self, sheet: u32, column: i32, width: f64) -> Result<()> {
self
.model
.set_column_width(sheet, column, width)
.map_err(to_js_error)
}
#[napi(js_name = "getRowHeight")]
pub fn get_row_height(&mut self, sheet: u32, row: i32) -> Result<f64> {
self.model.get_row_height(sheet, row).map_err(to_js_error)
}
#[napi(js_name = "getColumnWidth")]
pub fn get_column_width(&mut self, sheet: u32, column: i32) -> Result<f64> {
self
.model
.get_column_width(sheet, column)
.map_err(to_js_error)
}
#[napi(js_name = "setUserInput")]
pub fn set_user_input(&mut self, sheet: u32, row: i32, column: i32, input: String) -> Result<()> {
self
.model
.set_user_input(sheet, row, column, &input)
.map_err(to_js_error)
}
#[napi(js_name = "getFormattedCellValue")]
pub fn get_formatted_cell_value(&self, sheet: u32, row: i32, column: i32) -> Result<String> {
self
.model
.get_formatted_cell_value(sheet, row, column)
.map_err(to_js_error)
}
#[napi(js_name = "getFrozenRowsCount")]
pub fn get_frozen_rows_count(&self, sheet: u32) -> Result<i32> {
self.model.get_frozen_rows_count(sheet).map_err(to_js_error)
}
#[napi(js_name = "getFrozenColumnsCount")]
pub fn get_frozen_columns_count(&self, sheet: u32) -> Result<i32> {
self
.model
.get_frozen_columns_count(sheet)
.map_err(to_js_error)
}
#[napi(js_name = "setFrozenRowsCount")]
pub fn set_frozen_rows_count(&mut self, sheet: u32, count: i32) -> Result<()> {
self
.model
.set_frozen_rows_count(sheet, count)
.map_err(to_js_error)
}
#[napi(js_name = "setFrozenColumnsCount")]
pub fn set_frozen_columns_count(&mut self, sheet: u32, count: i32) -> Result<()> {
self
.model
.set_frozen_columns_count(sheet, count)
.map_err(to_js_error)
}
#[napi(js_name = "updateRangeStyle")]
pub fn update_range_style(
&mut self,
env: Env,
range: JsUnknown,
style_path: String,
value: String,
) -> Result<()> {
let range: Area = env
.from_js_value(range)
.map_err(|e| to_js_error(e.to_string()))?;
self
.model
.update_range_style(&range, &style_path, &value)
.map_err(to_js_error)
}
#[napi(js_name = "getCellStyle")]
pub fn get_cell_style(
&mut self,
env: Env,
sheet: u32,
row: i32,
column: i32,
) -> Result<JsUnknown> {
let style = self
.model
.get_cell_style(sheet, row, column)
.map_err(to_js_error)?;
env
.to_js_value(&style)
.map_err(|e| to_js_error(e.to_string()))
}
#[napi(js_name = "onPasteStyles")]
pub fn on_paste_styles(&mut self, env: Env, styles: JsUnknown) -> Result<()> {
let styles: &Vec<Vec<Style>> = &env
.from_js_value(styles)
.map_err(|e| to_js_error(e.to_string()))?;
self.model.on_paste_styles(styles).map_err(to_js_error)
}
#[napi(js_name = "getCellType")]
pub fn get_cell_type(&self, sheet: u32, row: i32, column: i32) -> Result<i32> {
Ok(
match self
.model
.get_cell_type(sheet, row, column)
.map_err(to_js_error)?
{
CellType::Number => 1,
CellType::Text => 2,
CellType::LogicalValue => 4,
CellType::ErrorValue => 16,
CellType::Array => 64,
CellType::CompoundData => 128,
},
)
}
// I don't _think_ serializing to JsUnknown can't fail
// FIXME: Remove this clippy directive
#[napi(js_name = "getWorksheetsProperties")]
#[allow(clippy::unwrap_used)]
pub fn get_worksheets_properties(&self, env: Env) -> JsUnknown {
env
.to_js_value(&self.model.get_worksheets_properties())
.unwrap()
}
#[napi(js_name = "getSelectedSheet")]
pub fn get_selected_sheet(&self) -> u32 {
self.model.get_selected_sheet()
}
#[napi(js_name = "getSelectedCell")]
pub fn get_selected_cell(&self) -> Vec<i32> {
let (sheet, row, column) = self.model.get_selected_cell();
vec![sheet as i32, row, column]
}
// I don't _think_ serializing to JsUnknown can't fail
// FIXME: Remove this clippy directive
#[napi(js_name = "getSelectedView")]
#[allow(clippy::unwrap_used)]
pub fn get_selected_view(&self, env: Env) -> JsUnknown {
env.to_js_value(&self.model.get_selected_view()).unwrap()
}
#[napi(js_name = "setSelectedSheet")]
pub fn set_selected_sheet(&mut self, sheet: u32) -> Result<()> {
self.model.set_selected_sheet(sheet).map_err(to_js_error)
}
#[napi(js_name = "setSelectedCell")]
pub fn set_selected_cell(&mut self, row: i32, column: i32) -> Result<()> {
self
.model
.set_selected_cell(row, column)
.map_err(to_js_error)
}
#[napi(js_name = "setSelectedRange")]
pub fn set_selected_range(
&mut self,
start_row: i32,
start_column: i32,
end_row: i32,
end_column: i32,
) -> Result<()> {
self
.model
.set_selected_range(start_row, start_column, end_row, end_column)
.map_err(to_js_error)
}
#[napi(js_name = "setTopLeftVisibleCell")]
pub fn set_top_left_visible_cell(&mut self, top_row: i32, top_column: i32) -> Result<()> {
self
.model
.set_top_left_visible_cell(top_row, top_column)
.map_err(to_js_error)
}
#[napi(js_name = "setShowGridLines")]
pub fn set_show_grid_lines(&mut self, sheet: u32, show_grid_lines: bool) -> Result<()> {
self
.model
.set_show_grid_lines(sheet, show_grid_lines)
.map_err(to_js_error)
}
#[napi(js_name = "getShowGridLines")]
pub fn get_show_grid_lines(&mut self, sheet: u32) -> Result<bool> {
self.model.get_show_grid_lines(sheet).map_err(to_js_error)
}
#[napi(js_name = "autoFillRows")]
pub fn auto_fill_rows(&mut self, env: Env, source_area: JsUnknown, to_row: i32) -> Result<()> {
let area: Area = env
.from_js_value(source_area)
.map_err(|e| to_js_error(e.to_string()))?;
self
.model
.auto_fill_rows(&area, to_row)
.map_err(to_js_error)
}
#[napi(js_name = "autoFillColumns")]
pub fn auto_fill_columns(
&mut self,
env: Env,
source_area: JsUnknown,
to_column: i32,
) -> Result<()> {
let area: Area = env
.from_js_value(source_area)
.map_err(|e| to_js_error(e.to_string()))?;
self
.model
.auto_fill_columns(&area, to_column)
.map_err(to_js_error)
}
#[napi(js_name = "onArrowRight")]
pub fn on_arrow_right(&mut self) -> Result<()> {
self.model.on_arrow_right().map_err(to_js_error)
}
#[napi(js_name = "onArrowLeft")]
pub fn on_arrow_left(&mut self) -> Result<()> {
self.model.on_arrow_left().map_err(to_js_error)
}
#[napi(js_name = "onArrowUp")]
pub fn on_arrow_up(&mut self) -> Result<()> {
self.model.on_arrow_up().map_err(to_js_error)
}
#[napi(js_name = "onArrowDown")]
pub fn on_arrow_down(&mut self) -> Result<()> {
self.model.on_arrow_down().map_err(to_js_error)
}
#[napi(js_name = "onPageDown")]
pub fn on_page_down(&mut self) -> Result<()> {
self.model.on_page_down().map_err(to_js_error)
}
#[napi(js_name = "onPageUp")]
pub fn on_page_up(&mut self) -> Result<()> {
self.model.on_page_up().map_err(to_js_error)
}
#[napi(js_name = "setWindowWidth")]
pub fn set_window_width(&mut self, window_width: f64) {
self.model.set_window_width(window_width);
}
#[napi(js_name = "setWindowHeight")]
pub fn set_window_height(&mut self, window_height: f64) {
self.model.set_window_height(window_height);
}
#[napi(js_name = "getScrollX")]
pub fn get_scroll_x(&self) -> Result<f64> {
self.model.get_scroll_x().map_err(to_js_error)
}
#[napi(js_name = "getScrollY")]
pub fn get_scroll_y(&self) -> Result<f64> {
self.model.get_scroll_y().map_err(to_js_error)
}
#[napi(js_name = "onExpandSelectedRange")]
pub fn on_expand_selected_range(&mut self, key: String) -> Result<()> {
self
.model
.on_expand_selected_range(&key)
.map_err(to_js_error)
}
#[napi(js_name = "onAreaSelecting")]
pub fn on_area_selecting(&mut self, target_row: i32, target_column: i32) -> Result<()> {
self
.model
.on_area_selecting(target_row, target_column)
.map_err(to_js_error)
}
#[napi(js_name = "setAreaWithBorder")]
pub fn set_area_with_border(
&mut self,
env: Env,
area: JsUnknown,
border_area: JsUnknown,
) -> Result<()> {
let range: Area = env
.from_js_value(area)
.map_err(|e| to_js_error(e.to_string()))?;
let border: BorderArea = env
.from_js_value(border_area)
.map_err(|e| to_js_error(e.to_string()))?;
self
.model
.set_area_with_border(&range, &border)
.map_err(|e| to_js_error(e.to_string()))?;
Ok(())
}
#[napi(js_name = "toBytes")]
pub fn to_bytes(&self) -> Vec<u8> {
self.model.to_bytes()
}
#[napi(js_name = "getName")]
pub fn get_name(&self) -> String {
self.model.get_name()
}
#[napi(js_name = "setName")]
pub fn set_name(&mut self, name: String) {
self.model.set_name(&name);
}
#[napi(js_name = "copyToClipboard")]
pub fn copy_to_clipboard(&self, env: Env) -> Result<JsUnknown> {
let data = self
.model
.copy_to_clipboard()
.map_err(|e| to_js_error(e.to_string()))?;
env
.to_js_value(&data)
.map_err(|e| to_js_error(e.to_string()))
}
#[napi(js_name = "pasteFromClipboard")]
pub fn paste_from_clipboard(
&mut self,
env: Env,
source_sheet: u32,
source_range: JsUnknown,
clipboard: JsUnknown,
is_cut: bool,
) -> Result<()> {
let source_range: (i32, i32, i32, i32) = env
.from_js_value(source_range)
.map_err(|e| to_js_error(e.to_string()))?;
let clipboard: ClipboardData = env
.from_js_value(clipboard)
.map_err(|e| to_js_error(e.to_string()))?;
self
.model
.paste_from_clipboard(source_sheet, source_range, &clipboard, is_cut)
.map_err(|e| to_js_error(e.to_string()))
}
#[napi(js_name = "pasteCsvText")]
pub fn paste_csv_string(&mut self, env: Env, area: JsUnknown, csv: String) -> Result<()> {
let range: Area = env
.from_js_value(area)
.map_err(|e| to_js_error(e.to_string()))?;
self
.model
.paste_csv_string(&range, &csv)
.map_err(|e| to_js_error(e.to_string()))
}
#[napi(js_name = "getDefinedNameList")]
pub fn get_defined_name_list(&self, env: Env) -> Result<JsUnknown> {
let data: Vec<DefinedName> = self
.model
.get_defined_name_list()
.iter()
.map(|s| DefinedName {
name: s.0.to_owned(),
scope: s.1,
formula: s.2.to_owned(),
})
.collect();
env
.to_js_value(&data)
.map_err(|e| to_js_error(e.to_string()))
}
#[napi(js_name = "newDefinedName")]
pub fn new_defined_name(
&mut self,
name: String,
scope: Option<u32>,
formula: String,
) -> Result<()> {
self
.model
.new_defined_name(&name, scope, &formula)
.map_err(|e| to_js_error(e.to_string()))
}
#[napi(js_name = "updateDefinedName")]
pub fn update_defined_name(
&mut self,
name: String,
scope: Option<u32>,
new_name: String,
new_scope: Option<u32>,
new_formula: String,
) -> Result<()> {
self
.model
.update_defined_name(&name, scope, &new_name, new_scope, &new_formula)
.map_err(|e| to_js_error(e.to_string()))
}
#[napi(js_name = "deleteDefinedName")]
pub fn delete_definedname(&mut self, name: String, scope: Option<u32>) -> Result<()> {
self
.model
.delete_defined_name(&name, scope)
.map_err(|e| to_js_error(e.to_string()))
}
}

File diff suppressed because it is too large Load Diff

884
bindings/python/Cargo.lock generated Normal file
View File

@@ -0,0 +1,884 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "aho-corasick"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
dependencies = [
"memchr",
]
[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bumpalo"
version = "3.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "bzip2"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8"
dependencies = [
"bzip2-sys",
"libc",
]
[[package]]
name = "bzip2-sys"
version = "0.1.11+1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc"
dependencies = [
"cc",
"libc",
"pkg-config",
]
[[package]]
name = "cc"
version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
dependencies = [
"libc",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38"
dependencies = [
"android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
"wasm-bindgen",
"windows-targets",
]
[[package]]
name = "chrono-tz"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbc529705a6e0028189c83f0a5dd9fb214105116f7e3c0eeab7ff0369766b0d1"
dependencies = [
"chrono",
"chrono-tz-build",
"phf",
]
[[package]]
name = "chrono-tz-build"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9998fb9f7e9b2111641485bf8beb32f92945f97f92a3d061f744cfef335f751"
dependencies = [
"parse-zoneinfo",
"phf",
"phf_codegen",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
[[package]]
name = "crc32fast"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
dependencies = [
"cfg-if",
]
[[package]]
name = "either"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
[[package]]
name = "flate2"
version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e"
dependencies = [
"crc32fast",
"miniz_oxide",
]
[[package]]
name = "getrandom"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
dependencies = [
"cfg-if",
"libc",
"wasi 0.11.0+wasi-snapshot-preview1",
]
[[package]]
name = "iana-time-zone"
version = "0.1.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "indoc"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306"
[[package]]
name = "instant"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
dependencies = [
"cfg-if",
]
[[package]]
name = "ironcalc"
version = "0.1.0"
dependencies = [
"chrono",
"ironcalc_base",
"itertools",
"roxmltree",
"serde",
"serde_json",
"thiserror",
"zip",
]
[[package]]
name = "ironcalc_base"
version = "0.1.0"
dependencies = [
"chrono",
"chrono-tz",
"js-sys",
"once_cell",
"rand",
"regex",
"ryu",
"serde",
"serde_json",
"serde_repr",
]
[[package]]
name = "itertools"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
[[package]]
name = "js-sys"
version = "0.3.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "libc"
version = "0.2.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
[[package]]
name = "lock_api"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "memchr"
version = "2.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
[[package]]
name = "memoffset"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
dependencies = [
"autocfg",
]
[[package]]
name = "miniz_oxide"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
dependencies = [
"adler",
]
[[package]]
name = "num-traits"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]]
name = "parking_lot"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
dependencies = [
"instant",
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc"
dependencies = [
"cfg-if",
"instant",
"libc",
"redox_syscall",
"smallvec",
"winapi",
]
[[package]]
name = "parse-zoneinfo"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41"
dependencies = [
"regex",
]
[[package]]
name = "phf"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
dependencies = [
"phf_shared",
]
[[package]]
name = "phf_codegen"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a"
dependencies = [
"phf_generator",
"phf_shared",
]
[[package]]
name = "phf_generator"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
dependencies = [
"phf_shared",
"rand",
]
[[package]]
name = "phf_shared"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b"
dependencies = [
"siphasher",
]
[[package]]
name = "pkg-config"
version = "0.3.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro2"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
dependencies = [
"unicode-ident",
]
[[package]]
name = "pyo3"
version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e681a6cfdc4adcc93b4d3cf993749a4552018ee0a9b65fc0ccfad74352c72a38"
dependencies = [
"cfg-if",
"indoc",
"libc",
"memoffset",
"parking_lot",
"pyo3-build-config",
"pyo3-ffi",
"pyo3-macros",
"unindent",
]
[[package]]
name = "pyo3-build-config"
version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "076c73d0bc438f7a4ef6fdd0c3bb4732149136abd952b110ac93e4edb13a6ba5"
dependencies = [
"once_cell",
"target-lexicon",
]
[[package]]
name = "pyo3-ffi"
version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e53cee42e77ebe256066ba8aa77eff722b3bb91f3419177cf4cd0f304d3284d9"
dependencies = [
"libc",
"pyo3-build-config",
]
[[package]]
name = "pyo3-macros"
version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfeb4c99597e136528c6dd7d5e3de5434d1ceaf487436a3f03b2d56b6fc9efd1"
dependencies = [
"proc-macro2",
"pyo3-macros-backend",
"quote",
"syn 1.0.109",
]
[[package]]
name = "pyo3-macros-backend"
version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "947dc12175c254889edc0c02e399476c2f652b4b9ebd123aa655c224de259536"
dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "pyroncalc"
version = "0.1.0"
dependencies = [
"ironcalc",
"pyo3",
"serde",
"serde_json",
]
[[package]]
name = "quote"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "redox_syscall"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
dependencies = [
"bitflags",
]
[[package]]
name = "regex"
version = "1.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]]
name = "roxmltree"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbf7d7b1ea646d380d0e8153158063a6da7efe30ddbf3184042848e3f8a6f671"
dependencies = [
"xmlparser",
]
[[package]]
name = "ryu"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "serde"
version = "1.0.192"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.192"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.39",
]
[[package]]
name = "serde_json"
version = "1.0.108"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "serde_repr"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.39",
]
[[package]]
name = "siphasher"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d"
[[package]]
name = "smallvec"
version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "target-lexicon"
version = "0.12.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a"
[[package]]
name = "thiserror"
version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.39",
]
[[package]]
name = "time"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
dependencies = [
"libc",
"wasi 0.10.0+wasi-snapshot-preview1",
"winapi",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "unindent"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1766d682d402817b5ac4490b3c3002d91dfa0d22812f341609f97b08757359c"
[[package]]
name = "wasi"
version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
version = "0.2.88"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.88"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217"
dependencies = [
"bumpalo",
"log",
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.39",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.88"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.88"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.39",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.88"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-core"
version = "0.51.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "xmlparser"
version = "0.13.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4"
[[package]]
name = "zip"
version = "0.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93ab48844d61251bb3835145c521d88aa4031d7139e8485990f60ca911fa0815"
dependencies = [
"byteorder",
"bzip2",
"crc32fast",
"flate2",
"thiserror",
"time",
]

View File

@@ -1,6 +1,6 @@
[package]
name = "pyroncalc"
version = "0.3.0"
version = "0.1.2"
edition = "2021"
@@ -12,8 +12,8 @@ crate-type = ["cdylib"]
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
xlsx = { package= "ironcalc", path = "../../xlsx", version = "0.3.0" }
pyo3 = { version = "0.23", features = ["extension-module"] }
xlsx = { package= "ironcalc", path = "../../xlsx", version = "0.2.0" }
pyo3 = { version = "0.22.3", features = ["extension-module"] }
[features]

View File

@@ -1,6 +1,6 @@
[project]
name = "ironcalc"
version = "0.3.0"
version = "0.1.2"
description = "Create, edit and evaluate Excel spreadsheets"
requires-python = ">=3.10"
keywords = [

View File

@@ -1,10 +1,10 @@
[package]
name = "wasm"
version = "0.3.0"
version = "0.1.3"
authors = ["Nicolas Hatcher <nicolas@theuniverse.today>"]
description = "IronCalc Web bindings"
license = "MIT/Apache-2.0"
repository = "https://github.com/ironcalc/ironcalc"
repository = "https://github.com/ironcalc/web-bindings"
edition = "2021"
[lib]
@@ -14,7 +14,7 @@ crate-type = ["cdylib"]
# Uses `../ironcalc/base` when used locally, and uses
# the inicated version from crates.io when published.
# https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#multiple-locations
ironcalc_base = { path = "../../base", version = "0.3", features = ["use_regex_lite"] }
ironcalc_base = { path = "../../base", version = "0.2", features = ["use_regex_lite"] }
serde = { version = "1.0", features = ["derive"] }
wasm-bindgen = "0.2.92"
serde-wasm-bindgen = "0.4"

View File

@@ -1,16 +1,8 @@
# In some platforms, python is called python3
PYTHON := $(shell command -v python 2>/dev/null || command -v python3 2>/dev/null)
# If neither is found, fail immediately
ifeq ($(PYTHON),)
$(error No python found. Please install python.)
endif
all:
wasm-pack build --target web --scope ironcalc --release
cp README.pkg.md pkg/README.md
tsc types.ts --target esnext --module esnext
$(PYTHON) fix_types.py
python fix_types.py
rm -f types.js
tests:

View File

@@ -75,9 +75,13 @@ export default defineConfig({
link: "/features/units",
},
{
text: "Serial Numbers",
text: "Dates and serial numbers",
link: "/features/serial-numbers",
},
{
text: "Numbers in IronCalc",
link: "/features/numbers-in-ironcalc",
},
{
text: "Unsupported Features",
link: "/features/unsupported-features",
@@ -588,7 +592,7 @@ export default defineConfig({
},
{
text: "ERF.PRECISE",
link: "/functions/engineering/erf-precise",
link: "/functions/engineering/erf.precise",
},
{
text: "ERFC",
@@ -596,7 +600,7 @@ export default defineConfig({
},
{
text: "ERFC.PRECISE",
link: "/functions/engineering/erfc-precise",
link: "/functions/engineering/erfc.precise",
},
{
text: "GESTEP",
@@ -2028,6 +2032,16 @@ export default defineConfig({
},
],
},
{
text: "Spreadhsheet Engines",
collapsed: true,
items: [
{
text: "Spreadsheet Engines",
link: "/other-spreadsheets/index",
},
],
},
{
text: "Contributing",
collapsed: true,

View File

@@ -0,0 +1,38 @@
---
layout: doc
outline: deep
lang: en-US
---
# Numbers in IronCalc
::: warning
**Note:** This draft page is under construction 🚧
::: warning
**Note:** This page contains technical documentation
Numbers in IronCalc are [IEE 754](https://en.wikipedia.org/wiki/IEEE_754) doubles (64 bit) and are displayed uo to 15 decimal digits.
## Integers
Some Integers are well represented by IEEE 754 doubles. The largest integer that can be stored perfectly as a double is:
$$
2^53 = 9,007,199,254,740,992
$$
## Floating points
The reader should be aware that numbers like 0.1 or 0.3 are not stored perfectly by computers, _only an approximation to them_ is stored.
This results in imperfect operations like the famous `0.1 + 0.2 != 0.3`.
When comparing numbers we also compare up to 15 significant figures. With this 'trick' `=IF(0.2+0.1=0.3,TRUE,FALSE)` is actually `TRUE`.
## Compatibility issues
Excel [mostly follows IEEE 754](https://learn.microsoft.com/en-us/office/troubleshoot/excel/floating-point-arithmetic-inaccurate-result). Like IronCalc displays numbers with 15 significant digits. Excel does a few other undisclosed 'hacks'.
If the result of an addition (or subtraction) of two non very small numbers is a number close to EPS and it is the end of the calculation then it is zero.
That's is how it gets `=0.3-0.2-0.1` as `0`. However `=1*(0.3-0.2-0.1)` in Excel is `-2.77556E-17`

View File

@@ -30,4 +30,21 @@ The fractional part of a serial number represents time, as a fraction of the day
Since date-times are stored as numbers, they can be used for arithmetic operations in formulas. For example, it is possible to determine the difference between two dates by subtracting one serial number from the other.
**Note**: A #VALUE! error is reported if a date-formatted cell contains a number less than 1, or greater than or equal to 2,958,466.
**Note**: A #VALUE! error is reported if a date-formatted cell contains a number less than 1 or greater than 2,958,465.
## Compatibility Notes
Excel has an infamous [feature](https://learn.microsoft.com/en-us/office/troubleshoot/excel/wrongly-assumes-1900-is-leap-year) that was ported from a bug in Lotus 1-2-3 that assumes that the year 1900 is a leap year.
That means that serial numbers 1 to 60 in IronCalc are different than Excel.
In IronCalc, Google Sheets, Libre Office and Zoho Date(1900,1,1) returns 2
In Excel Date(1900,1,1) returns 1.
Gnumeric solves the problem in yet another way. It follows Excel from 1 to 59, skips 60, and it follows Excel (and all other engines from there on).
A formula like `=DAY(60)` produces `#NUM!` in Gnumeric.
Serial number 61 corresponds to 1 March 1900, and from there on most spreadsheet engines agree.
IronCalc, like Excel, doesn't deal with serial numbers outside of the range [1, 2,958,465]. Other engines like Google sheets, do not have an upper limit.

View File

@@ -22,7 +22,7 @@ You can track the progress in this [GitHub issue](https://github.com/ironcalc/Ir
| HOUR | <Badge type="info" text="Not implemented yet" /> | |
| ISOWEEKNUM | <Badge type="info" text="Not implemented yet" /> | |
| MINUTE | <Badge type="info" text="Not implemented yet" /> | |
| MONTH | <Badge type="tip" text="Available" /> | [MONTH](date_and_time/month) |
| MONTH | <Badge type="tip" text="Available" /> | |
| NETWORKDAYS | <Badge type="info" text="Not implemented yet" /> | |
| NETWORKDAYS.INTL | <Badge type="info" text="Not implemented yet" /> | |
| NOW | <Badge type="tip" text="Available" /> | |
@@ -34,5 +34,5 @@ You can track the progress in this [GitHub issue](https://github.com/ironcalc/Ir
| WEEKNUM | <Badge type="info" text="Not implemented yet" /> | |
| WORKDAY | <Badge type="info" text="Not implemented yet" /> | |
| WORKDAY.INTL | <Badge type="info" text="Not implemented yet" /> | |
| YEAR | <Badge type="tip" text="Available" /> | [YEAR](date_and_time/year) |
| YEAR | <Badge type="tip" text="Available" /> | |
| YEARFRAC | <Badge type="info" text="Not implemented yet" /> | |

View File

@@ -7,17 +7,23 @@ lang: en-US
::: warning
**Note:** This draft page is under construction 🚧
:::
## Overview
DAY is a function of the Date and Time category that extracts the day of the month from a valid date [serial number](/features/serial-numbers.md), returning a number in the range [1, 31].
## Usage
### Syntax
**DAY(<span title="Number" style="color:#1E88E5">date</span>) => <span title="Number" style="color:#1E88E5">day</span>**
### Argument descriptions
* *date* ([number](/features/value-types#numbers), required). The date for which the day of the month is to be calculated, expressed as a [serial number](/features/serial-numbers.md) in the range [1, 2958466). The value 1 corresponds to the date 1899-12-31, while 2958465 corresponds to 9999-12-31.
* *date* ([number](/features/value-types#numbers), required). The date for which the day of the month is to be calculated, expressed as a [serial number](/features/serial-numbers.md) in the range [1, 2958465]. The value corresponds to the date 1899-12-31, while 2958465 corresponds to 9999-12-31.
### Additional guidance
If the supplied _date_ argument has a fractional part, DAY uses its [floor value](https://en.wikipedia.org/wiki/Floor_and_ceiling_functions).
### Returned value
DAY returns an integer [number](/features/value-types#numbers) in the range [1, 31], that is the day of the month according to the [Gregorian calendar](https://en.wikipedia.org/wiki/Gregorian_calendar).
### Error conditions
* In common with many other IronCalc functions, DAY propagates errors that are found in its argument.
* If no argument, or more than one argument, is supplied, then DAY returns the [`#ERROR!`](/features/error-types.md#error) error.
@@ -26,9 +32,17 @@ DAY returns an integer [number](/features/value-types#numbers) in the range [1,
* If date is less than 1, or greater than 2,958,465, then DAY returns the [`#NUM!`](/features/error-types.md#num) error.
* At present, DAY does not accept a string representation of a date literal as an argument. For example, the formula `=DAY("2024-12-31")` returns the [`#VALUE!`](/features/error-types.md#value) error.
<!--@include: ../markdown-snippets/error-type-details.txt-->
## Details
IronCalc utilizes Rust's [chrono](https://docs.rs/chrono/latest/chrono/) crate to implement the DAY function.
## Compatibility Notes
In IronCalc the argument of DAY cannot be text. This is confusing, and error prone, as in "10/12/2026" it is not clear if the day is 10 or 12.
Most of all other spreadsheet engines like Excel, Google Sheets, Libre Office and Gnumeric accept text as input.
## Examples
[See some examples in IronCalc](https://app.ironcalc.com/?example=day).
## Links

View File

@@ -3,35 +3,9 @@ layout: doc
outline: deep
lang: en-US
---
# MONTH function
::: warning
**Note:** This draft page is under construction 🚧
:::
## Overview
MONTH is a function of the Date and Time category that extracts the month from a valid date [serial number](/features/serial-numbers.md), returning a number in the range [1, 12].
## Usage
### Syntax
**MONTH(<span title="Number" style="color:#1E88E5">date</span>) => <span title="Number" style="color:#1E88E5">month</span>**
### Argument descriptions
* *date* ([number](/features/value-types#numbers), required). The date for which the month is to be calculated, expressed as a [serial number](/features/serial-numbers.md) in the range [1, 2958466). The value 1 corresponds to the date 1899-12-31, while 2958465 corresponds to 9999-12-31.
### Additional guidance
If the supplied _date_ argument has a fractional part, MONTH uses its [floor value](https://en.wikipedia.org/wiki/Floor_and_ceiling_functions).
### Returned value
MONTH returns an integer [number](/features/value-types#numbers) in the range [1, 12], that is the month according to the [Gregorian calendar](https://en.wikipedia.org/wiki/Gregorian_calendar). The value 1 corresponds to January, 2 corresponds to February and so on.
### Error conditions
* In common with many other IronCalc functions, MONTH propagates errors that are found in its argument.
* If no argument, or more than one argument, is supplied, then MONTH returns the [`#ERROR!`](/features/error-types.md#error) error.
* If the value of the *date* argument is not (or cannot be converted to) a [number](/features/value-types#numbers), then MONTH returns the [`#VALUE!`](/features/error-types.md#value) error.
* For some argument values, MONTH may return the [`#DIV/0!`](/features/error-types.md#div-0) error.
* If date is less than 1, or greater than or equal to 2,958,466, then MONTH returns the [`#NUM!`](/features/error-types.md#num) error.
* At present, MONTH does not accept a string representation of a date literal as an argument. For example, the formula `=MONTH("2024-12-31")` returns the [`#VALUE!`](/features/error-types.md#value) error.
<!--@include: ../markdown-snippets/error-type-details.txt-->
## Details
IronCalc utilizes Rust's [chrono](https://docs.rs/chrono/latest/chrono/) crate to implement the MONTH function.
## Examples
[See some examples in IronCalc](https://app.ironcalc.com/?example=month).
## Links
* See also IronCalc's [DAY](/functions/date_and_time/day.md) and [YEAR](/functions/date_and_time/year.md) functions.
* Visit Microsoft Excel's [MONTH function](https://support.microsoft.com/en-gb/office/month-function-579a2881-199b-48b2-ab90-ddba0eba86e8) page.
* Both [Google Sheets](https://support.google.com/docs/answer/3093052) and [LibreOffice Calc](https://wiki.documentfoundation.org/Documentation/Calc_Functions/MONTH) provide versions of the MONTH function.
# MONTH
::: warning
🚧 This function is implemented but currently lacks detailed documentation. For guidance, you may refer to the equivalent functionality in [Microsoft Excel documentation](https://support.microsoft.com/en-us/office/excel-functions-by-category-5f91f4e9-7b42-46d2-9bd1-63f26a86c0eb).
:::

View File

@@ -3,35 +3,9 @@ layout: doc
outline: deep
lang: en-US
---
# YEAR function
::: warning
**Note:** This draft page is under construction 🚧
:::
## Overview
YEAR is a function of the Date and Time category that extracts the year from a valid date [serial number](/features/serial-numbers.md), returning a number in the range [1899, 9999].
## Usage
### Syntax
**YEAR(<span title="Number" style="color:#1E88E5">date</span>) => <span title="Number" style="color:#1E88E5">year</span>**
### Argument descriptions
* *date* ([number](/features/value-types#numbers), required). The date for which the year is to be calculated, expressed as a [serial number](/features/serial-numbers.md) in the range [1, 2958466). The value 1 corresponds to the date 1899-12-31, while 2958465 corresponds to 9999-12-31.
### Additional guidance
If the supplied _date_ argument has a fractional part, YEAR uses its [floor value](https://en.wikipedia.org/wiki/Floor_and_ceiling_functions).
### Returned value
YEAR returns an integer [number](/features/value-types#numbers) in the range [1899, 9999], that is the year according to the [Gregorian calendar](https://en.wikipedia.org/wiki/Gregorian_calendar).
### Error conditions
* In common with many other IronCalc functions, YEAR propagates errors that are found in its argument.
* If no argument, or more than one argument, is supplied, then YEAR returns the [`#ERROR!`](/features/error-types.md#error) error.
* If the value of the *date* argument is not (or cannot be converted to) a [number](/features/value-types#numbers), then YEAR returns the [`#VALUE!`](/features/error-types.md#value) error.
* For some argument values, YEAR may return the [`#DIV/0!`](/features/error-types.md#div-0) error.
* If date is less than 1, or greater than or equal to 2,958,466, then YEAR returns the [`#NUM!`](/features/error-types.md#num) error.
* At present, YEAR does not accept a string representation of a date literal as an argument. For example, the formula `=YEAR("2024-12-31")` returns the [`#VALUE!`](/features/error-types.md#value) error.
<!--@include: ../markdown-snippets/error-type-details.txt-->
## Details
IronCalc utilizes Rust's [chrono](https://docs.rs/chrono/latest/chrono/) crate to implement the YEAR function.
## Examples
[See some examples in IronCalc](https://app.ironcalc.com/?example=year).
## Links
* See also IronCalc's [DAY](/functions/date_and_time/day.md) and [MONTH](/functions/date_and_time/month.md) functions.
* Visit Microsoft Excel's [YEAR function](https://support.microsoft.com/en-gb/office/year-function-c64f017a-1354-490d-981f-578e8ec8d3b9) page.
* Both [Google Sheets](https://support.google.com/docs/answer/3093061) and [LibreOffice Calc](https://wiki.documentfoundation.org/Documentation/Calc_Functions/YEAR) provide versions of the YEAR function.
# YEAR
::: warning
🚧 This function is implemented but currently lacks detailed documentation. For guidance, you may refer to the equivalent functionality in [Microsoft Excel documentation](https://support.microsoft.com/en-us/office/excel-functions-by-category-5f91f4e9-7b42-46d2-9bd1-63f26a86c0eb).
:::

View File

@@ -27,10 +27,10 @@ All Engineering functions are already supported in IronCalc.
| DEC2BIN | <Badge type="tip" text="Available" /> | |
| DEC2HEX | <Badge type="tip" text="Available" /> | |
| DEC2OCT | <Badge type="tip" text="Available" /> | |
| ERF | <Badge type="tip" text="Available" /> | [ERF](engineering/erf) |
| ERF.PRECISE | <Badge type="tip" text="Available" /> | [ERF.PRECISE](engineering/erf-precise) |
| ERFC | <Badge type="tip" text="Available" /> | [ERFC](engineering/erfc) |
| ERFC.PRECISE | <Badge type="tip" text="Available" /> | [ERFC.PRECISE](engineering/erfc-precise) |
| ERF | <Badge type="tip" text="Available" /> | |
| ERF.PRECISE | <Badge type="tip" text="Available" /> | |
| ERFC | <Badge type="tip" text="Available" /> | |
| ERFC.PRECISE | <Badge type="tip" text="Available" /> | |
| GESTEP | <Badge type="tip" text="Available" /> | |
| HEX2BIN | <Badge type="tip" text="Available" /> | |
| HEX2DEC | <Badge type="tip" text="Available" /> | |

View File

@@ -1,52 +0,0 @@
---
layout: doc
outline: deep
lang: en-US
---
# ERF.PRECISE function
::: warning
**Note:** This draft page is under construction 🚧
:::
## Overview
ERF.PRECISE (<u>ER</u>ror <u>F</u>unction) is a function of the Engineering category that calculates a value for the _error function_. Also known as the _Gauss error function_, the error function represents the probability of a random variable falling within a certain range, given that it follows a specified normal distribution.
ERF.PRECISE is provided for compatibility with other spreadsheets. For all real values of $x$, $\text{ERF.PRECISE}(x)=\text{ERF}(x)$.
## Usage
### Syntax
**ERF.PRECISE(<span title="Number" style="color:#1E88E5">X</span>) => <span title="Number" style="color:#1E88E5">erf.precise</span>**
### Argument descriptions
* *X* ([number](/features/value-types#numbers), required). Integration limit. ERF.PRECISE integrates over the range [0, _X_].
### Additional guidance
None.
### Returned value
ERF.PRECISE returns a [number](/features/value-types#numbers) that is the error function probability for the specified argument. The returned value has a magnitude in the range [0, 1] but may be either positive (integration limit > 0) or negative (integration limit < 0).
### Error conditions
* In common with many other IronCalc functions, ERF.PRECISE propagates errors that are found in its argument.
* If no argument, or more than one argument, is supplied, then ERF.PRECISE returns the [`#ERROR!`](/features/error-types.md#error) error.
* If the value of the argument is not (or cannot be converted to) a [number](/features/value-types#numbers), then ERF.PRECISE returns the [`#VALUE!`](/features/error-types.md#value) error.
* For some argument values, ERF.PRECISE may return the [`#DIV/0!`](/features/error-types.md#div-0) error.
<!--@include: ../markdown-snippets/error-type-details.txt-->
## Details
* The error function arises in many scientific, engineering, and mathematical fields and is commonly defined by the following equation (applicable for any real number $x$):
$$
\text{erf}(x) = \frac{2}{\sqrt{\pi} }\: \int_{0}^{x} e^{-t^2}\:dt
$$
* The figure below illustrates the output of the ERF.PRECISE function for values of $x$ in the range -3 to +3.
<center><img src="/functions/images/error-function-curve.png" width="350" alt="Graph showing erf(x) for x between -3 and +3."></center>
* This figure illustrates some of the key characteristics of the error function:
* $\text{erf}(0) = 0$
* $\text{erf}(x) = -\text{erf}(x)$
* As $x \rightarrow \infty$, $\text{erf}(x) \rightarrow 1$
* As $x \rightarrow -\infty$, $\text{erf}(x) \rightarrow -1$
* The error function is a [transcendental](https://en.wikipedia.org/wiki/Transcendental_function), non-algebraic mathematical function. IronCalc implements the ERF.PRECISE function by numerical approximation using a power series.
## Examples
[See some examples in IronCalc](https://app.ironcalc.com/?example=erf-precise).
## Links
* See also IronCalc's [ERF](/functions/engineering/erf.md), [ERFC](/functions/engineering/erfc.md) and [ERFC.PRECISE](/functions/engineering/erfc-precise.md) functions.
* Visit Microsoft Excel's [ERF.PRECISE function](https://support.microsoft.com/en-gb/office/erf-precise-function-9a349593-705c-4278-9a98-e4122831a8e0) page.
* Both [Google Sheets](https://support.google.com/docs/answer/9386210) and [LibreOffice Calc](https://wiki.documentfoundation.org/Documentation/Calc_Functions/ERF.PRECISE) provide versions of the ERF.PROCESS function.

View File

@@ -3,49 +3,9 @@ layout: doc
outline: deep
lang: en-US
---
# ERF function
# ERF
::: warning
**Note:** This draft page is under construction 🚧
🚧 This function is implemented but currently lacks detailed documentation. For guidance, you may refer to the equivalent functionality in [Microsoft Excel documentation](https://support.microsoft.com/en-us/office/excel-functions-by-category-5f91f4e9-7b42-46d2-9bd1-63f26a86c0eb).
:::
## Overview
ERF (<u>ER</u>ror <u>F</u>unction) is a function of the Engineering category that calculates a value for the _error function_. Also known as the _Gauss error function_, the error function represents the probability of a random variable falling within a certain range, given that it follows a specified normal distribution.
## Usage
### Syntax
**ERF(<span title="Number" style="color:#1E88E5">X</span>, <span title="Number" style="color:#1E88E5">Y</span>) => <span title="Number" style="color:#1E88E5">erf</span>**
### Argument descriptions
* *X* ([number](/features/value-types#numbers), required). Integration limit. If no value is supplied for the _Y_ argument, ERF integrates over the range [0, _X_].
* *Y* ([number](/features/value-types#numbers), [optional](/features/optional-arguments)). Upper integration limit. When a value is supplied for this argument, ERF integrates over the range [_X_, _Y_].
### Additional guidance
None.
### Returned value
ERF returns a [number](/features/value-types#numbers) that is the error function probability for the specified arguments. The returned value has a magnitude in the range [0, 1] but may be either positive (upper integration limit > lower integration limit) or negative (upper integration limit < lower integration limit).
### Error conditions
* In common with many other IronCalc functions, ERF propagates errors that are found in its arguments.
* If no argument, or more than two arguments, are supplied, then ERF returns the [`#ERROR!`](/features/error-types.md#error) error.
* If the value of any argument is not (or cannot be converted to) a [number](/features/value-types#numbers), then ERF returns the [`#VALUE!`](/features/error-types.md#value) error.
* For some argument values, ERF may return the [`#DIV/0!`](/features/error-types.md#div-0) error.
<!--@include: ../markdown-snippets/error-type-details.txt-->
## Details
* The error function arises in many scientific, engineering, and mathematical fields and is commonly defined by the following equation (applicable for any real number $x$):
$$
\text{erf}(x) = \frac{2}{\sqrt{\pi} }\: \int_{0}^{x} e^{-t^2}\:dt
$$
* The figure below illustrates the output of the ERF function for values of $x$ in the range -3 to +3.
<center><img src="/functions/images/error-function-curve.png" width="350" alt="Graph showing erf(x) for x between -3 and +3."></center>
* This figure illustrates some of the key characteristics of the error function:
* $\text{erf}(0) = 0$
* $\text{erf}(x) = -\text{erf}(x)$
* As $x \rightarrow \infty$, $\text{erf}(x) \rightarrow 1$
* As $x \rightarrow -\infty$, $\text{erf}(x) \rightarrow -1$
* The error function is a [transcendental](https://en.wikipedia.org/wiki/Transcendental_function), non-algebraic mathematical function. IronCalc implements the ERF function by numerical approximation using a power series.
## Examples
[See some examples in IronCalc](https://app.ironcalc.com/?example=erf).
## Links
* See also IronCalc's [ERFC](/functions/engineering/erfc.md), [ERF.PRECISE](/functions/engineering/erf-precise.md) and [ERFC.PRECISE](/functions/engineering/erfc-precise.md) functions.
* Visit Microsoft Excel's [ERF function](https://support.microsoft.com/en-gb/office/erf-function-c53c7e7b-5482-4b6c-883e-56df3c9af349) page.
* Both [Google Sheets](https://support.google.com/docs/answer/9116267) and [LibreOffice Calc](https://wiki.documentfoundation.org/Documentation/Calc_Functions/ERF) provide versions of the ERF function.

View File

@@ -0,0 +1,11 @@
---
layout: doc
outline: deep
lang: en-US
---
# ERF.PRECISE
::: warning
🚧 This function is implemented but currently lacks detailed documentation. For guidance, you may refer to the equivalent functionality in [Microsoft Excel documentation](https://support.microsoft.com/en-us/office/excel-functions-by-category-5f91f4e9-7b42-46d2-9bd1-63f26a86c0eb).
:::

View File

@@ -1,52 +0,0 @@
---
layout: doc
outline: deep
lang: en-US
---
# ERFC.PRECISE function
::: warning
**Note:** This draft page is under construction 🚧
:::
## Overview
ERFC.PRECISE (<u>ER</u>ror <u>F</u>unction <u>C</u>omplementary) is a function of the Engineering category that calculates a value for the _complementary error function_, defined by $\text{erfc}(x) = 1 - \text{erf}(x)$. Also known as the _complementary Gauss error function_, the complementary error function represents the probability of a random variable falling outside a certain range, given that it follows a specified normal distribution.
ERFC.PRECISE is provided for compatibility with other spreadsheets. For all real values of $x$, $\text{ERFC.PRECISE}(x)=\text{ERFC}(x)$.
## Usage
### Syntax
**ERFC.PRECISE(<span title="Number" style="color:#1E88E5">X</span>) => <span title="Number" style="color:#1E88E5">erfc.precise</span>**
### Argument descriptions
* *X* ([number](/features/value-types#numbers), required). The lower integration limit to be used to calculate the complementary error function. ERFC.PRECISE integrates over the range [X, $\infty$).
### Additional guidance
None.
### Returned value
ERFC.PRECISE returns a [number](/features/value-types#numbers) that is the complementary error function probability for the specified argument. The returned value lies in range [0, 2].
### Error conditions
* In common with many other IronCalc functions, ERFC.PRECISE propagates errors that are found in its argument.
* If no argument, or more than one argument, is supplied, then ERFC.PRECISE returns the [`#ERROR!`](/features/error-types.md#error) error.
* If the value of any argument is not (or cannot be converted to) a [number](/features/value-types#numbers), then ERFC.PRECISE returns the [`#VALUE!`](/features/error-types.md#value) error.
* For some argument values, ERFC.PRECISE may return the [`#DIV/0!`](/features/error-types.md#div-0) error.
<!--@include: ../markdown-snippets/error-type-details.txt-->
## Details
* The complementary error function arises in many scientific, engineering, and mathematical fields and is commonly defined by the following equation (applicable for any real number $x$):
$$
\text{erfc}(x) = \frac{2}{\sqrt{\pi} }\: \int_{x}^{\infty} e^{-t^2}\:dt
$$
* The figure below illustrates the output of the ERFC.PRECISE function for values of $x$ in the range -3 to +3.
<center><img src="/functions/images/complementary-error-function-curve.png" width="350" alt="Graph showing erfc(x) for x between -3 and +3."></center>
* This figure illustrates some of the key characteristics of the complementary error function:
* $\text{erfc}(0) = 1$
* $\text{erfc}(-x) = 2-\text{erfc}(x)$
* As $x \rightarrow \infty$, $\text{erfc}(x) \rightarrow 0$
* As $x \rightarrow -\infty$, $\text{erfc}(x) \rightarrow 2$
* The complementary error function is a [transcendental](https://en.wikipedia.org/wiki/Transcendental_function), non-algebraic mathematical function. IronCalc implements the ERFC.PRECISE function by numerical approximation using a power series.
## Examples
[See some examples in IronCalc](https://app.ironcalc.com/?example=erfc-precise).
## Links
* See also IronCalc's [ERF](/functions/engineering/erf.md), [ERFC](/functions/engineering/erfc.md) and [ERF.PRECISE](/functions/engineering/erf-precise.md) functions.
* Visit Microsoft Excel's [ERFC.PRECISE function](https://support.microsoft.com/en-gb/office/erfc-precise-function-e90e6bab-f45e-45df-b2ac-cd2eb4d4a273) page.
* Both [Google Sheets](https://support.google.com/docs/answer/9386303) and [LibreOffice Calc](https://wiki.documentfoundation.org/Documentation/Calc_Functions/ERFC.PRECISE) provide versions of the ERFC.PRECISE function.

View File

@@ -3,48 +3,9 @@ layout: doc
outline: deep
lang: en-US
---
# ERFC function
# ERFC
::: warning
**Note:** This draft page is under construction 🚧
🚧 This function is implemented but currently lacks detailed documentation. For guidance, you may refer to the equivalent functionality in [Microsoft Excel documentation](https://support.microsoft.com/en-us/office/excel-functions-by-category-5f91f4e9-7b42-46d2-9bd1-63f26a86c0eb).
:::
## Overview
ERFC (<u>ER</u>ror <u>F</u>unction <u>C</u>omplementary) is a function of the Engineering category that calculates a value for the _complementary error function_, defined by $\text{erfc}(x) = 1 - \text{erf}(x)$. Also known as the _complementary Gauss error function_, the complementary error function represents the probability of a random variable falling outside a certain range, given that it follows a specified normal distribution.
## Usage
### Syntax
**ERFC(<span title="Number" style="color:#1E88E5">X</span>) => <span title="Number" style="color:#1E88E5">erfc</span>**
### Argument descriptions
* *X* ([number](/features/value-types#numbers), required). The lower integration limit to be used to calculate the complementary error function. ERFC integrates over the range [X, $\infty$).
### Additional guidance
None.
### Returned value
ERFC returns a [number](/features/value-types#numbers) that is the complementary error function probability for the specified argument. The returned value lies in range [0, 2].
### Error conditions
* In common with many other IronCalc functions, ERFC propagates errors that are found in its argument.
* If no argument, or more than one argument, is supplied, then ERFC returns the [`#ERROR!`](/features/error-types.md#error) error.
* If the value of any argument is not (or cannot be converted to) a [number](/features/value-types#numbers), then ERFC returns the [`#VALUE!`](/features/error-types.md#value) error.
* For some argument values, ERFC may return the [`#DIV/0!`](/features/error-types.md#div-0) error.
<!--@include: ../markdown-snippets/error-type-details.txt-->
## Details
* The complementary error function arises in many scientific, engineering, and mathematical fields and is commonly defined by the following equation (applicable for any real number $x$):
$$
\text{erfc}(x) = \frac{2}{\sqrt{\pi} }\: \int_{x}^{\infty} e^{-t^2}\:dt
$$
* The figure below illustrates the output of the ERFC function for values of $x$ in the range -3 to +3.
<center><img src="/functions/images/complementary-error-function-curve.png" width="350" alt="Graph showing erfc(x) for x between -3 and +3."></center>
* This figure illustrates some of the key characteristics of the complementary error function:
* $\text{erfc}(0) = 1$
* $\text{erfc}(-x) = 2-\text{erfc}(x)$
* As $x \rightarrow \infty$, $\text{erfc}(x) \rightarrow 0$
* As $x \rightarrow -\infty$, $\text{erfc}(x) \rightarrow 2$
* The complementary error function is a [transcendental](https://en.wikipedia.org/wiki/Transcendental_function), non-algebraic mathematical function. IronCalc implements the ERFC function by numerical approximation using a power series.
## Examples
[See some examples in IronCalc](https://app.ironcalc.com/?example=erfc).
## Links
* See also IronCalc's [ERF](/functions/engineering/erf.md), [ERF.PRECISE](/functions/engineering/erf-precise.md) and [ERFC.PRECISE](/functions/engineering/erfc-precise.md) functions.
* Visit Microsoft Excel's [ERFC function](https://support.microsoft.com/en-gb/office/erfc-function-736e0318-70ba-4e8b-8d08-461fe68b71b3) page.
* Both [Google Sheets](https://support.google.com/docs/answer/3093407) and [LibreOffice Calc](https://wiki.documentfoundation.org/Documentation/Calc_Functions/ERFC) provide versions of the ERFC function.

View File

@@ -0,0 +1,11 @@
---
layout: doc
outline: deep
lang: en-US
---
# ERFC.PRECISE
::: warning
🚧 This function is implemented but currently lacks detailed documentation. For guidance, you may refer to the equivalent functionality in [Microsoft Excel documentation](https://support.microsoft.com/en-us/office/excel-functions-by-category-5f91f4e9-7b42-46d2-9bd1-63f26a86c0eb).
:::

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

View File

@@ -0,0 +1,30 @@
---
layout: doc
outline: deep
lang: en-US
---
::: warning
**Note:** This draft page is under construction 🚧
:::
# Other spreadsheet engines
There are numerous spreadsheet engines out there
## Excel, the Friendly Giant
## Google Sheets
## LibreOffice
## Gnumeric
# Links
For a list of spreadsheet software you can consult [wikipedia](https://en.wikipedia.org/wiki/List_of_spreadsheet_software).

View File

@@ -1,4 +0,0 @@
node_modules/*
dist/*
*storybook.log

View File

@@ -1,26 +0,0 @@
import type { StorybookConfig } from "@storybook/react-vite";
const config: StorybookConfig = {
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
addons: [
"@storybook/addon-onboarding",
"@storybook/addon-essentials",
"@chromatic-com/storybook",
"@storybook/addon-interactions",
],
framework: {
name: "@storybook/react-vite",
options: {},
},
viteFinal: (config) => {
if (!config.server) {
config.server = {};
}
if (!config.server.fs) {
config.server.fs = {};
}
config.server.fs.allow = ["../.."];
return config;
}
};
export default config;

View File

@@ -1,18 +0,0 @@
<style>
/* inter-regular - latin */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: "Inter";
font-style: normal;
font-weight: 400;
src: url("fonts/inter-v13-latin-regular.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
/* inter-600 - latin */
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: "Inter";
font-style: normal;
font-weight: 600;
src: url("fonts/inter-v13-latin-600.woff2") format("woff2"); /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
}
</style>

View File

@@ -1,14 +0,0 @@
import type { Preview } from "@storybook/react";
const preview: Preview = {
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
},
};
export default preview;

File diff suppressed because it is too large Load Diff

View File

@@ -1,57 +0,0 @@
{
"name": "@ironcalc/workbook",
"version": "0.3.1",
"type": "module",
"main": "./dist/ironcalc.js",
"module": "./dist/ironcalc.js",
"source": "./src/index.ts",
"types": "./dist/index.d.ts",
"scripts": {
"dev": "vite",
"build": "vite build && tsc",
"check": "biome check ./src",
"check-write": "biome check --write ./src",
"test": "vitest run",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
},
"dependencies": {
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.0",
"@ironcalc/wasm": "file:../../bindings/wasm/pkg",
"@mui/material": "^6.4",
"@mui/system": "^6.4",
"i18next": "^23.11.1",
"lucide-react": "^0.473.0",
"react-colorful": "^5.6.1",
"react-i18next": "^15.4.0"
},
"devDependencies": {
"@biomejs/biome": "1.8.3",
"@chromatic-com/storybook": "^3.2.4",
"@storybook/addon-essentials": "^8.6.0-alpha.0",
"@storybook/addon-interactions": "^8.6.0-alpha.0",
"@storybook/addon-onboarding": "^8.6.0-alpha.0",
"@storybook/blocks": "^8.6.0-alpha.0",
"@storybook/react": "^8.6.0-alpha.0",
"@storybook/react-vite": "^8.6.0-alpha.0",
"@storybook/test": "^8.6.0-alpha.0",
"@vitejs/plugin-react": "^4.2.1",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"storybook": "^8.6.0-alpha.0",
"ts-node": "^10.9.2",
"typescript": "~5.6.2",
"vite": "^6.0.5",
"vite-plugin-svgr": "^4.2.0",
"vitest": "^2.0.5"
},
"peerDependencies": {
"@types/react": "^18.0.0",
"react": "^18.0.0",
"react-dom": "^18.0.0"
},
"files": [
"dist"
]
}

View File

@@ -1,2 +0,0 @@
"@ironcalc/wasm": "^0.3.0",
"@ironcalc/wasm": "file:../../bindings/wasm/pkg",

View File

@@ -1,21 +0,0 @@
import "./index.css";
import type { Model } from "@ironcalc/wasm";
import ThemeProvider from "@mui/material/styles/ThemeProvider";
import Workbook from "./components/workbook.tsx";
import { WorkbookState } from "./components/workbookState.ts";
import { theme } from "./theme.ts";
import "./i18n";
interface IronCalcProperties {
model: Model;
}
function IronCalc(properties: IronCalcProperties) {
return (
<ThemeProvider theme={theme}>
<Workbook model={properties.model} workbookState={new WorkbookState()} />
</ThemeProvider>
);
}
export default IronCalc;

View File

@@ -1,5 +0,0 @@
import init, { Model } from "@ironcalc/wasm";
import IronCalc from "./IronCalc";
import { IronCalcIcon, IronCalcLogo } from "./icons";
export { init, Model, IronCalc, IronCalcIcon, IronCalcLogo };

View File

@@ -1,28 +0,0 @@
import type { Meta, StoryObj } from "@storybook/react";
import { Workbook } from "./Workbook";
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta = {
title: "Example/Workbook",
component: Workbook,
parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout
layout: "fullscreen",
},
// More on argTypes: https://storybook.js.org/docs/api/argtypes
argTypes: {},
// Use `fn` to spy on the onClick arg, which will appear in the actions panel once invoked: https://storybook.js.org/docs/essentials/actions#action-args
args: {},
} satisfies Meta<typeof Workbook>;
export default meta;
type Story = StoryObj<typeof meta>;
// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
export const Primary: Story = {
args: {
primary: true,
label: "Button",
},
};

View File

@@ -1,34 +0,0 @@
import { useEffect, useState } from "react";
import { IronCalc, Model, init } from "../index";
// export interface IronCalcProps {}
/** Primary UI component for user interaction */
export const Workbook = () => {
const [model, setModel] = useState<Model | null>(null);
useEffect(() => {
async function start() {
await init();
setModel(new Model("Workbook1", "en", "UTC"));
}
start();
}, []);
if (!model) {
return <div>Loading...</div>;
}
return (
<div
style={{
position: "absolute",
top: "0px",
bottom: "0px",
left: "0px",
right: "0px",
}}
>
<IronCalc model={model} />
</div>
);
};

View File

@@ -1,37 +0,0 @@
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import svgr from 'vite-plugin-svgr';
import { resolve } from 'node:path';
// https://vitejs.dev/config/
export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'src/index.ts'),
name: 'IronCalc',
// the proper extensions will be added
fileName: 'ironcalc',
},
rollupOptions: {
// make sure to externalize deps that shouldn't be bundled
// into your library
external: ['react', 'react-dom', '@ironcalc/wasm'],
output: {
// Provide global variables to use in the UMD build
// for externalized deps
globals: {
react: 'React',
'react-dom': 'ReactDOM',
'@ironcalc/wasm': 'IronCalc',
},
},
},
},
plugins: [react(), svgr()],
server: {
fs: {
// Allow serving files from one level up to the project root
allow: ['..'],
},
},
});

View File

@@ -1,7 +0,0 @@
:2080
# rocket API
reverse_proxy /api/* 127.0.0.1:8000
# everything else is the frontend
reverse_proxy :5173

View File

@@ -1,44 +0,0 @@
# IronCalc service application
This directory contains the code (frontend and backend) to run the code deployed at https://app.ironcalc.com
## Development build:
1. Run in this folder `caddy run` (that just just a proxy for the front end and backend).
You will need to leave it running all the time.
2. In the server folder run `cargo run`
3. In the frontend folder `npm install` and `npm run dev`
That's it if you point your browser to localhost:2080 you should see the app.
Note that step three involves alo building thw wasm bindings and the widget
## Deployment
The development environment is very close to a deployment environment.
### Build the server binary:
In the server directory run:
```
cargo build --release
```
You will find a single binary in target/release/ironcalc_server
### Build the frontend files
In the frontend folder:
```
npm install
npm run build
```
That will create a bunch of files that you should copy to your server
## TODO
Deployment details, brotli, logs, stats, Postgres, systemctl files, ...

View File

@@ -1,24 +0,0 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist/*
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

View File

@@ -1,17 +0,0 @@
# IronCalc application
This is the front end deployed at https:://app.ironcalc.com
To build for production:
```
npm install
npm run build
```
A development build:
```
npm run dev
```

View File

@@ -1,19 +0,0 @@
{
"organizeImports": { "enabled": true },
"linter": {
"enabled": true,
"rules": {
"correctness": { "noUnusedImports": "error" }
}
},
"formatter": {
"indentStyle": "space",
"indentWidth": 2
},
"css": {
"formatter": {
"enabled": true
}
}
}

View File

@@ -1,32 +0,0 @@
{
"name": "frontend",
"private": true,
"version": "0.3.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"preview": "vite preview",
"check": "biome check ./src",
"check-write": "biome check --write ./src"
},
"dependencies": {
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.0",
"@ironcalc/workbook": "^0.3.1",
"@mui/material": "^6.3.1",
"lucide": "^0.469.0",
"lucide-react": "^0.469.0",
"react": "^18.3.1",
"react-dom": "^18.3.1"
},
"devDependencies": {
"@biomejs/biome": "1.8.3",
"@types/react": "^18.3.18",
"@types/react-dom": "^18.3.5",
"@vitejs/plugin-react": "^4.3.4",
"typescript": "~5.6.2",
"vite": "^6.0.5",
"vite-plugin-svgr": "^4.2.0"
}
}

View File

@@ -1,2 +0,0 @@
"@ironcalc/ironcalc": "file:../../IronCalc",
"@ironcalc/workbook": "^0.3.1",

View File

@@ -1,5 +0,0 @@
body {
inset: 0px;
margin: 0;
padding: 0;
}

View File

@@ -1,12 +0,0 @@
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "./index.css";
import App from "./App.tsx";
import "./fonts.css";
// biome-ignore lint: we know the 'root' element exists.
createRoot(document.getElementById("root")!).render(
<StrictMode>
<App />
</StrictMode>,
);

Some files were not shown because too many files have changed in this diff Show More