diff --git a/.changeset/empty-owls-add.md b/.changeset/empty-owls-add.md
new file mode 100644
index 00000000..427b35bc
--- /dev/null
+++ b/.changeset/empty-owls-add.md
@@ -0,0 +1,5 @@
+---
+'@lottiefiles/dotlottie-web': minor
+---
+
+refactor: 💡 dotlottie-rs wasm bindings integration
diff --git a/.changeset/little-dingos-happen.md b/.changeset/little-dingos-happen.md
new file mode 100644
index 00000000..0e581a7b
--- /dev/null
+++ b/.changeset/little-dingos-happen.md
@@ -0,0 +1,5 @@
+---
+'@lottiefiles/dotlottie-web': minor
+---
+
+feat: 🎸 emit `render` event when a new frame is rendered
diff --git a/.changeset/pre.json b/.changeset/pre.json
new file mode 100644
index 00000000..08834c89
--- /dev/null
+++ b/.changeset/pre.json
@@ -0,0 +1,11 @@
+{
+ "mode": "pre",
+ "tag": "beta",
+ "initialVersions": {
+ "@lottiefiles/dotlottie-react": "0.2.3",
+ "@lottiefiles/dotlottie-vue": "0.1.4",
+ "@lottiefiles/dotlottie-wc": "0.0.7",
+ "@lottiefiles/dotlottie-web": "0.12.3"
+ },
+ "changesets": []
+}
diff --git a/.eslintignore b/.eslintignore
index 74ca1491..53075f17 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -42,4 +42,4 @@ next-env.d.ts
# Ignore renderer releases
releases/
-renderer.js
+dotlottie-player.js
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 08a955c7..0ff3d1da 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -3,6 +3,7 @@ on:
push:
branches:
- 'main'
+ - 'beta'
pull_request:
jobs:
diff --git a/.size-limit.cjs b/.size-limit.cjs
index 03ad2044..2d18729f 100644
--- a/.size-limit.cjs
+++ b/.size-limit.cjs
@@ -6,7 +6,7 @@ module.exports = [
},
{
name: '@lottiefiles/dotlottie-web WASM',
- path: 'packages/web/dist/wasm/*.wasm',
+ path: 'packages/web/dist/*.wasm',
modifyWebpackConfig: (config) => {
config.experiments = {
asyncWebAssembly: true,
diff --git a/apps/dotlottie-vue-example/package.json b/apps/dotlottie-vue-example/package.json
index 69e86aab..44fd5ce3 100644
--- a/apps/dotlottie-vue-example/package.json
+++ b/apps/dotlottie-vue-example/package.json
@@ -1,6 +1,5 @@
{
- "name": "dotlottie-vue-example",
- "version": "0.0.0",
+ "name": "@lottiefiles/dotlottie-vue-example",
"type": "module",
"private": true,
"scripts": {
diff --git a/apps/dotlottie-wc-example/package.json b/apps/dotlottie-wc-example/package.json
index 3ed1e2a7..ebe169aa 100644
--- a/apps/dotlottie-wc-example/package.json
+++ b/apps/dotlottie-wc-example/package.json
@@ -1,6 +1,5 @@
{
- "name": "dotlottie-wc-example",
- "version": "0.0.0",
+ "name": "@lottiefiles/dotlottie-wc-example",
"type": "module",
"private": true,
"scripts": {
diff --git a/apps/dotlottie-web-example/src/main.ts b/apps/dotlottie-web-example/src/main.ts
index 62821520..1061a87b 100644
--- a/apps/dotlottie-web-example/src/main.ts
+++ b/apps/dotlottie-web-example/src/main.ts
@@ -8,7 +8,7 @@ import './styles.css';
import type { Mode } from '@lottiefiles/dotlottie-web';
import { DotLottie } from '@lottiefiles/dotlottie-web';
-import wasmUrl from '../../../packages/web/dist/wasm/renderer.wasm?url';
+import wasmUrl from '../../../packages/web/dist/dotlottie-player.wasm?url';
const app = document.getElementById('app') as HTMLDivElement;
@@ -63,7 +63,7 @@ app.innerHTML = `
@@ -103,9 +103,11 @@ allCanvas.forEach((canvas) => {
loop: true,
autoplay: true,
backgroundColor,
- useFrameInterpolation: false,
+ // useFrameInterpolation: false,
});
+ dotLottie.addEventListener('loadError', console.error);
+
window.addEventListener('resize', () => {
dotLottie.resize();
});
@@ -127,9 +129,11 @@ fetch('/hamster.lottie')
segments: [10, 90],
speed: 1,
backgroundColor: '#800080ff',
- useFrameInterpolation: false,
+ // useFrameInterpolation: false,
});
+ dotLottie.addEventListener('loadError', console.error);
+
const playPauseButton = document.getElementById('playPause') as HTMLButtonElement;
const stopButton = document.getElementById('stop') as HTMLButtonElement;
const currentFrameSpan = document.getElementById('current-frame') as HTMLSpanElement;
@@ -196,7 +200,7 @@ fetch('/hamster.lottie')
src: 'https://lottie.host/f315768c-a29b-41fd-b5a8-a1c1dfb36cd2/CRiiNg8fqQ.lottie',
loop: true,
autoplay: true,
- mode: 'bounce-reverse',
+ mode: 'reverse-bounce',
renderConfig: {
devicePixelRatio: 0.2,
},
diff --git a/apps/dotlottie-web-node-example/index.ts b/apps/dotlottie-web-node-example/index.ts
index 0625d984..26ec49e4 100644
--- a/apps/dotlottie-web-node-example/index.ts
+++ b/apps/dotlottie-web-node-example/index.ts
@@ -12,7 +12,7 @@ import GIFEncoder from 'gif-encoder';
import minimist from 'minimist';
const wasmBase64 = fs
- .readFileSync('./node_modules/@lottiefiles/dotlottie-web/dist/wasm/renderer.wasm')
+ .readFileSync('./node_modules/@lottiefiles/dotlottie-web/dist/dotlottie-player.wasm')
.toString('base64');
const wasmDataUri = `data:application/octet-stream;base64,${wasmBase64}`;
@@ -120,7 +120,7 @@ dotLottie.addEventListener('load', () => {
dotLottie.addEventListener('frame', (event) => {
const frame = ctx.getImageData(0, 0, args.width, args.height).data;
- if (event.currentFrame >= dotLottie.totalFrames - 1) {
+ if (event.currentFrame >= dotLottie.totalFrames) {
console.log('Finished recording GIF');
gif.finish();
} else {
diff --git a/packages/react/README.md b/packages/react/README.md
index 1bdeda3f..2915eee6 100644
--- a/packages/react/README.md
+++ b/packages/react/README.md
@@ -78,7 +78,7 @@ The `DotLottieReactProps` extends the `HTMLCanvasElement` Props and accepts all
| `src` | string | | undefined | URL to the animation data (`.json` or `.lottie`). | |
| `speed` | number | | 1 | Animation playback speed. 1 is regular speed. | |
| `data` | string \| ArrayBuffer | | undefined | Animation data provided either as a Lottie JSON string or as an ArrayBuffer for .lottie animations. | |
-| `mode` | string | | "forward" | Animation play mode. Accepts "forward", "reverse", "bounce", "bounce-reverse". | |
+| `mode` | string | | "forward" | Animation play mode. Accepts "forward", "reverse", "bounce", "reverse-bounce". | |
| `backgroundColor` | string | | undefined | Background color of the canvas. Accepts 6-digit or 8-digit hex color string (e.g., "#000000", "#000000FF"), | |
| `segments` | \[number, number] | | \[0, totalFrames - 1] | Animation segments. Accepts an array of two numbers, where the first number is the start frame and the second number is the end frame. | |
| `renderConfig` | RenderConfig | | `{}` | Configuration for rendering the animation. | |
diff --git a/packages/vue/README.md b/packages/vue/README.md
index 013f2950..273fec84 100644
--- a/packages/vue/README.md
+++ b/packages/vue/README.md
@@ -69,7 +69,7 @@ import { DotLottieVue } from '@lottiefiles/dotlottie-vue'
| `src` | string | | undefined | URL to the animation data (`.json` or `.lottie`). |
| `speed` | number | | 1 | Animation playback speed. 1 is regular speed. |
| `data` | string \| ArrayBuffer | | undefined | Animation data provided either as a Lottie JSON string or as an ArrayBuffer for .lottie animations. |
-| `mode` | string | | "forward" | Animation play mode. Accepts "forward", "reverse", "bounce", "bounce-reverse". |
+| `mode` | string | | "forward" | Animation play mode. Accepts "forward", "reverse", "bounce", "reverse-bounce". |
| `backgroundColor` | string | | undefined | Background color of the canvas. Accepts 6-digit or 8-digit hex color string (e.g., "#000000", "#000000FF"), |
| `segments` | \[number, number] | | \[0, totalFrames - 1] | Animation segments. Accepts an array of two numbers, where the first number is the start frame and the second number is the end frame. |
| `renderConfig` | RenderConfig | | `{}` | Configuration for rendering the animation. |
diff --git a/packages/web/.dockerignore b/packages/web/.dockerignore
deleted file mode 100644
index 3c3629e6..00000000
--- a/packages/web/.dockerignore
+++ /dev/null
@@ -1 +0,0 @@
-node_modules
diff --git a/packages/web/Dockerfile b/packages/web/Dockerfile
deleted file mode 100644
index a06c8103..00000000
--- a/packages/web/Dockerfile
+++ /dev/null
@@ -1,11 +0,0 @@
-FROM emscripten/emsdk:latest
-
-WORKDIR /package
-
-RUN apt-get update \
- && apt-get install -y meson ninja-build git bash \
- && rm -rf /var/lib/apt/lists/*
-
-COPY . .
-
-CMD ["/bin/bash", "./build_wasm.sh", "/emsdk/"]
diff --git a/packages/web/README.md b/packages/web/README.md
index bf901dd2..01fe6f2b 100644
--- a/packages/web/README.md
+++ b/packages/web/README.md
@@ -121,7 +121,7 @@ The `DotLottie` constructor accepts a config object with the following propertie
| `src` | string | | undefined | URL to the animation data (`.json` or `.lottie`). |
| `speed` | number | | 1 | Animation playback speed. 1 is regular speed. |
| `data` | string \| ArrayBuffer | | undefined | Animation data provided either as a Lottie JSON string or as an ArrayBuffer for .lottie animations. |
-| `mode` | string | | "forward" | Animation play mode. Accepts "forward", "reverse", "bounce", "bounce-reverse". |
+| `mode` | string | | "forward" | Animation play mode. Accepts "forward", "reverse", "bounce", "reverse-bounce". |
| `backgroundColor` | string | | undefined | Background color of the canvas. Accepts 6-digit or 8-digit hex color string (e.g., "#000000", "#000000FF"), |
| `segments` | \[number, number] | | \[0, totalFrames - 1] | Animation segments. Accepts an array of two numbers, where the first number is the start frame and the second number is the end frame. |
| `renderConfig` | [RenderConfig](#renderconfig) | | `{}` | Configuration for rendering the animation. |
@@ -197,19 +197,20 @@ The `DotLottie` class exposes the following static methods:
The `DotLottie` instance emits the following events that can be listened to via the `addEventListener` method:
-| Event | Description | Event Parameter (Type and Fields) |
-| ----------- | ----------------------------------------------------------------------- | ---------------------------------------------------- |
-| `load` | Emitted when the animation is loaded. | `LoadEvent { type: 'load' }` |
-| `loadError` | Emitted when there's an error loading the animation. | `LoadErrorEvent { type: 'loadError', error: Error }` |
-| `play` | Emitted when the animation starts playing. | `PlayEvent { type: 'play' }` |
-| `pause` | Emitted when the animation is paused. | `PauseEvent { type: 'pause' }` |
-| `stop` | Emitted when the animation is stopped. | `StopEvent { type: 'stop' }` |
-| `loop` | Emitted when the animation completes a loop. | `LoopEvent { type: 'loop', loopCount: number }` |
-| `complete` | Emitted when the animation completes. | `CompleteEvent { type: 'complete' }` |
-| `frame` | Emitted when the animation reaches a new frame. | `FrameEvent { type: 'frame', currentFrame: number }` |
-| `destroy` | Emitted when the animation is destroyed. | `DestroyEvent { type: 'destroy' }` |
-| `freeze` | Emitted when the animation is freezed and the animation loop stops. | `FreezeEvent { type: 'freeze' }` |
-| `unfreeze` | Emitted when the animation is unfreezed and the animation loop resumes. | `UnfreezeEvent { type: 'unfreeze' }` |
+| Event | Description | Event Parameter (Type and Fields) |
+| ----------- | ----------------------------------------------------------------------- | ------------------------------------------------------ |
+| `load` | Emitted when the animation is loaded. | `LoadEvent { type: 'load' }` |
+| `loadError` | Emitted when there's an error loading the animation. | `LoadErrorEvent { type: 'loadError', error: Error }` |
+| `play` | Emitted when the animation starts playing. | `PlayEvent { type: 'play' }` |
+| `pause` | Emitted when the animation is paused. | `PauseEvent { type: 'pause' }` |
+| `stop` | Emitted when the animation is stopped. | `StopEvent { type: 'stop' }` |
+| `loop` | Emitted when the animation completes a loop. | `LoopEvent { type: 'loop', loopCount: number }` |
+| `complete` | Emitted when the animation completes. | `CompleteEvent { type: 'complete' }` |
+| `frame` | Emitted when the animation reaches a new frame. | `FrameEvent { type: 'frame', currentFrame: number }` |
+| `destroy` | Emitted when the animation is destroyed. | `DestroyEvent { type: 'destroy' }` |
+| `freeze` | Emitted when the animation is freezed and the animation loop stops. | `FreezeEvent { type: 'freeze' }` |
+| `unfreeze` | Emitted when the animation is unfreezed and the animation loop resumes. | `UnfreezeEvent { type: 'unfreeze' }` |
+| `render` | Emitted when a new frame is rendered to the canvas. | `RenderEvent { type: 'render', currentFrame: number }` |
## Development
diff --git a/packages/web/build_wasm.sh b/packages/web/build_wasm.sh
deleted file mode 100755
index 52847351..00000000
--- a/packages/web/build_wasm.sh
+++ /dev/null
@@ -1,96 +0,0 @@
-#!/bin/bash
-
-# Store positional arguments in descriptive variables for clarity
-SCRIPT_NAME="$0"
-EMSDK_PATH="$1"
-THORVG_TAG_OR_BRANCH="${2:-v0.12.x}"
-
-# Ensure we always execute from the directory the script resides in
-DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-cd "$DIR"
-
-# Ensure the user provides the EMSDK path as an argument to the script
-#if [ "$#" -lt 1 ]; then
-if [ -z "$EMSDK_PATH" ]; then
- echo "
- Oops! It seems you forgot to provide the emsdk path argument.
-
- Please install emsdk and then specify its path when running this script.
- For emsdk installation guidance, visit: https://emscripten.org/docs/getting_started/downloads.html
-
- Usage: $SCRIPT_NAME [optional_thorvg_tag_or_branch]
- ex. -> $SCRIPT_NAME /home/user/emsdk/ tags/v0.11.1
- "
- exit 1
-fi
-
-# Function for checking command status and printing an error
-check_command_success() {
- if [ $? -ne 0 ]; then
- echo "$1"
- exit 1
- fi
-}
-
-# Check if essential tools are available in the system
-command -v git > /dev/null 2>&1 || {
- echo "Error: git is not installed. Please ensure you have git installed and try again."
- exit 1
-}
-command -v meson > /dev/null 2>&1 || {
- echo "Error: meson is not installed. Please install meson and try again."
- exit 1
-}
-command -v ninja > /dev/null 2>&1 || {
- echo "Error: ninja is not installed. Please install ninja and try again."
- exit 1
-}
-
-# Clone the thorvg repository if it's not already present
-if [ ! -d "$DIR/thorvg" ]; then
- git clone https://github.com/thorvg/thorvg.git
- check_command_success "Error cloning the repository"
-fi
-
-# Remove the build_wasm directory inside thorvg if it exists
-if [ -d "$DIR/thorvg/build_wasm" ]; then
- rm -r "$DIR/thorvg/build_wasm"
-fi
-
-# Change directory to thorvg to run the wasm_build.sh script
-cd "$DIR/thorvg"
-git fetch origin
-# git checkout $THORVG_TAG_OR_BRANCH
-git checkout "$THORVG_TAG_OR_BRANCH"
-check_command_success "Error switching to the desired tag/branch: $THORVG_TAG_OR_BRANCH"
-
-sed "s|EMSDK:|$EMSDK_PATH|g" cross/wasm_x86_i686.txt > /tmp/.wasm_cross.txt
-meson -Db_lto=true -Ddefault_library=static -Dstatic=true -Dthreads=false -Dloaders="lottie, png, jpg" --cross-file /tmp/.wasm_cross.txt build_wasm
-ninja -C build_wasm/
-
-# Change back to the parent directory
-cd "$DIR"
-
-# Create a unique temporary file to hold the cross file after substitution
-TMPFILE=$(mktemp /tmp/wasm_cross.XXXXXX)
-
-# Ensure the temp file is always cleaned up on exit
-trap 'rm -f "$TMPFILE"' EXIT
-
-# Substitute the EMSDK path in the wasm_cross.txt file and save to the temporary file
-sed "s|EMSDK:|$EMSDK_PATH|g" "$DIR/wasm_cross.txt" > "$TMPFILE"
-check_command_success "Error substituting EMSDK path in wasm_cross.txt"
-
-# Setup meson build with the cross file
-meson --cross-file "$TMPFILE" src/wasm
-check_command_success "Error setting up meson"
-
-# Build using ninja
-ninja -C src/wasm/
-check_command_success "Error during ninja build"
-
-# Remove all non .js, .ts and .wasm files
-find "$DIR/src/wasm" -type f ! \( -name "*.js" -o -name "*.wasm" -o -name "*.ts" \) -delete
-
-# Remove unwanted directories
-rm -rf "$DIR/src/wasm/meson-info" "$DIR/src/wasm/meson-logs" "$DIR/src/wasm/meson-private" "$DIR/src/wasm/renderer.js.p"
diff --git a/packages/web/cpp/renderer.cpp b/packages/web/cpp/renderer.cpp
deleted file mode 100644
index 6bac1bd0..00000000
--- a/packages/web/cpp/renderer.cpp
+++ /dev/null
@@ -1,271 +0,0 @@
-#include
-#include
-
-using namespace emscripten;
-using namespace std;
-using namespace tvg;
-
-static const char *NoError = "None";
-
-class __attribute__((visibility("default"))) Renderer
-{
-
-public:
- ~Renderer()
- {
- free(buffer);
- Initializer::term(CanvasEngine::Sw);
- }
-
- static unique_ptr create()
- {
- return unique_ptr(new Renderer());
- }
-
- string error()
- {
- return errorMsg;
- }
-
- bool load(string data, int width, int height)
- {
-
- errorMsg = NoError;
-
- if (!canvas)
- {
- errorMsg = "Invalid canvas";
- return false;
- }
-
- if (data.empty())
- {
- errorMsg = "Invalid data";
- return false;
- }
-
- canvas->clear(true);
-
- animation = Animation::gen();
-
- if (animation->picture()->load(data.c_str(), data.size(), "lottie", false) != Result::Success)
- {
- errorMsg = "load() fail";
- return false;
- }
-
- animation->picture()->size(&psize[0], &psize[1]);
-
- /* need to reset size to calculate scale in Picture.size internally before calling resize() */
- this->width = 0;
- this->height = 0;
-
- resize(width, height);
-
- // create background shape
- auto background = Shape::gen();
- this->background = background.get();
-
- background->appendRect(0, 0, psize[0], psize[1]);
- uint8_t r = (bgColor >> 24) & 0xFF;
- uint8_t g = (bgColor >> 16) & 0xFF;
- uint8_t b = (bgColor >> 8) & 0xFF;
- uint8_t a = bgColor & 0xFF;
- background->fill(r, g, b, a);
- canvas->push(std::move(background));
-
- std::unique_ptr picturePaint(animation->picture());
-
- if (canvas->push(std::move(picturePaint)) != Result::Success)
- {
- errorMsg = "push() fail";
- return false;
- }
-
- updated = true;
-
- return true;
- }
-
- bool update()
- {
- if (!updated)
- return true;
-
- errorMsg = NoError;
-
- if (canvas->update() != Result::Success)
- {
- errorMsg = "update() fail";
- return false;
- }
-
- return true;
- }
-
- val render()
- {
- errorMsg = NoError;
-
- if (!canvas || !animation)
- {
- errorMsg = "Invalid canvas or animation";
- return val(typed_memory_view(0, nullptr));
- }
-
- if (!updated)
- {
-
- return val(typed_memory_view(width * height * 4, buffer));
- }
-
- if (canvas->draw() != Result::Success)
- {
- errorMsg = "draw() fail";
- return val(typed_memory_view(0, nullptr));
- }
-
- canvas->sync();
-
- updated = false;
-
- return val(typed_memory_view(width * height * 4, buffer));
- }
-
- val size()
- {
- return val(typed_memory_view(2, psize));
- }
-
- val duration()
- {
- if (!canvas || !animation)
- return val(0);
- return val(animation->duration());
- }
-
- val totalFrames()
- {
- if (!canvas || !animation)
- return val(0);
- return val(animation->totalFrame());
- }
-
- bool frame(float no)
- {
- if (!canvas || !animation)
- return false;
- if (animation->frame(no) == Result::Success)
- {
-
- updated = true;
-
- return true;
- }
-
- return false;
- }
-
- void setBgColor(uint32_t color)
- {
- if (!canvas)
- return;
-
- if (color == bgColor)
- return;
-
- this->bgColor = color;
-
- if (background)
- {
- uint8_t r = (bgColor >> 24) & 0xFF;
- uint8_t g = (bgColor >> 16) & 0xFF;
- uint8_t b = (bgColor >> 8) & 0xFF;
- uint8_t a = bgColor & 0xFF;
-
- background->fill(r, g, b, a);
- }
-
- updated = true;
- }
-
- void resize(int width, int height)
- {
- if (!canvas || !animation)
- return;
- if (this->width == width && this->height == height)
- return;
-
- this->width = width;
- this->height = height;
-
- free(buffer);
- buffer = (uint8_t *)malloc(width * height * sizeof(uint32_t));
- canvas->target((uint32_t *)buffer, width, width, height, SwCanvas::ABGR8888S);
-
- float scale;
- float shiftX = 0.0f, shiftY = 0.0f;
- if (psize[0] > psize[1])
- {
- scale = width / psize[0];
- shiftY = (height - psize[1] * scale) * 0.5f;
- }
- else
- {
- scale = height / psize[1];
- shiftX = (width - psize[0] * scale) * 0.5f;
- }
- animation->picture()->scale(scale);
- animation->picture()->translate(shiftX, shiftY);
-
- updated = true;
- }
-
-private:
- explicit Renderer()
- {
- errorMsg = NoError;
-
- if (Initializer::init(CanvasEngine::Sw, 0) != Result::Success)
- {
- errorMsg = "init() fail";
- return;
- }
-
- canvas = SwCanvas::gen();
- if (!canvas)
- errorMsg = "Invalid canvas";
-
- animation = Animation::gen();
- if (!animation)
- errorMsg = "Invalid animation";
- }
-
-private:
- string errorMsg;
- unique_ptr canvas = nullptr;
- unique_ptr animation = nullptr;
- Shape *background = nullptr;
- uint8_t *buffer = nullptr;
- uint32_t width = 0;
- uint32_t height = 0;
- uint32_t bgColor = 0x00000000;
- float psize[2]; // picture size
- bool updated = false;
-};
-
-EMSCRIPTEN_BINDINGS(Renderer)
-{
- class_("Renderer")
- .constructor(&Renderer::create)
- .function("error", &Renderer::error, allow_raw_pointers())
- .function("load", &Renderer::load)
- .function("update", &Renderer::update)
- .function("resize", &Renderer::resize)
- .function("render", &Renderer::render)
- .function("size", &Renderer::size)
- .function("duration", &Renderer::duration)
- .function("totalFrames", &Renderer::totalFrames)
- .function("frame", &Renderer::frame)
- .function("setBgColor", &Renderer::setBgColor);
-}
\ No newline at end of file
diff --git a/packages/web/docker_build_wasm.sh b/packages/web/docker_build_wasm.sh
deleted file mode 100644
index 34d3a13c..00000000
--- a/packages/web/docker_build_wasm.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash
-
-docker --log-level=debug build -t $0 . && docker run --rm -v $(pwd):/package $0
diff --git a/packages/web/meson.build b/packages/web/meson.build
deleted file mode 100644
index a5ada8eb..00000000
--- a/packages/web/meson.build
+++ /dev/null
@@ -1,20 +0,0 @@
-project('Renderer', 'cpp')
-
-cc = meson.get_compiler('cpp')
-
-if cc.get_id() == 'emscripten'
- thorvg_wasm_lib_path = join_paths(meson.current_source_dir(), 'thorvg', 'build_wasm', 'src')
- thorvg_wasm_lib = cc.find_library('thorvg', dirs: thorvg_wasm_lib_path)
-
- headers = include_directories('thorvg/inc')
-
- thorvg_wasm_dep = declare_dependency(dependencies: thorvg_wasm_lib, include_directories: headers)
-
- executable('renderer',
- 'cpp/renderer.cpp',
- include_directories: headers,
- dependencies: [thorvg_wasm_dep],
- )
-else
- message('The compiler is not Emscripten.')
-endif
diff --git a/packages/web/package.json b/packages/web/package.json
index 2ad3b3be..a25601bc 100644
--- a/packages/web/package.json
+++ b/packages/web/package.json
@@ -18,21 +18,9 @@
"engines": {
"node": ">=18"
},
- "main": "dist/index.js",
- "exports": {
- ".": "./dist/index.js",
- "./*": "./dist/*.js",
- "./package.json": "./package.json"
- },
+ "main": "dist/index.cjs",
+ "module": "dist/index.js",
"types": "dist/index.d.ts",
- "typesVersions": {
- "*": {
- "*": [
- "dist/*",
- "dist/index.d.ts"
- ]
- }
- },
"files": [
"dist"
],
@@ -59,9 +47,6 @@
"test:watch": "vitest",
"type-check": "tsc --noEmit"
},
- "dependencies": {
- "@dotlottie/dotlottie-js": "^0.6.2"
- },
"devDependencies": {
"@types/node": "^20.10.5",
"@vitest/browser": "^1.1.0",
diff --git a/packages/web/src/wasm/renderer.js b/packages/web/src/core/dotlottie-player.js
similarity index 65%
rename from packages/web/src/wasm/renderer.js
rename to packages/web/src/core/dotlottie-player.js
index 2acb419d..b19bd948 100644
--- a/packages/web/src/wasm/renderer.js
+++ b/packages/web/src/core/dotlottie-player.js
@@ -1,4 +1,4 @@
-var createRendererModule = (() => {
+var createDotLottiePlayerModule = (() => {
var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;
return function (moduleArg = {}) {
@@ -226,7 +226,7 @@ var createRendererModule = (() => {
var wasmBinaryFile;
- wasmBinaryFile = 'renderer.wasm';
+ wasmBinaryFile = 'DotLottiePlayer.wasm';
if (!isDataURI(wasmBinaryFile)) {
wasmBinaryFile = locateFile(wasmBinaryFile);
@@ -297,10 +297,10 @@ var createRendererModule = (() => {
};
/** @param {WebAssembly.Module=} module*/ function receiveInstance(instance, module) {
wasmExports = instance.exports;
- wasmMemory = wasmExports['I'];
+ wasmMemory = wasmExports['Aa'];
updateMemoryViews();
- wasmTable = wasmExports['N'];
- addOnInit(wasmExports['J']);
+ wasmTable = wasmExports['Da'];
+ addOnInit(wasmExports['Ba']);
removeRunDependency('wasm-instantiate');
return wasmExports;
}
@@ -400,6 +400,129 @@ var createRendererModule = (() => {
);
};
+ var exceptionCaught = [];
+
+ var uncaughtExceptionCount = 0;
+
+ var ___cxa_begin_catch = (ptr) => {
+ var info = new ExceptionInfo(ptr);
+ if (!info.get_caught()) {
+ info.set_caught(true);
+ uncaughtExceptionCount--;
+ }
+ info.set_rethrown(false);
+ exceptionCaught.push(info);
+ ___cxa_increment_exception_refcount(info.excPtr);
+ return info.get_exception_ptr();
+ };
+
+ var exceptionLast = 0;
+
+ var ___cxa_end_catch = () => {
+ _setThrew(0, 0);
+ var info = exceptionCaught.pop();
+ ___cxa_decrement_exception_refcount(info.excPtr);
+ exceptionLast = 0;
+ };
+
+ /** @constructor */ function ExceptionInfo(excPtr) {
+ this.excPtr = excPtr;
+ this.ptr = excPtr - 24;
+ this.set_type = function (type) {
+ HEAPU32[(this.ptr + 4) >> 2] = type;
+ };
+ this.get_type = function () {
+ return HEAPU32[(this.ptr + 4) >> 2];
+ };
+ this.set_destructor = function (destructor) {
+ HEAPU32[(this.ptr + 8) >> 2] = destructor;
+ };
+ this.get_destructor = function () {
+ return HEAPU32[(this.ptr + 8) >> 2];
+ };
+ this.set_caught = function (caught) {
+ caught = caught ? 1 : 0;
+ HEAP8[(this.ptr + 12) >> 0] = caught;
+ };
+ this.get_caught = function () {
+ return HEAP8[(this.ptr + 12) >> 0] != 0;
+ };
+ this.set_rethrown = function (rethrown) {
+ rethrown = rethrown ? 1 : 0;
+ HEAP8[(this.ptr + 13) >> 0] = rethrown;
+ };
+ this.get_rethrown = function () {
+ return HEAP8[(this.ptr + 13) >> 0] != 0;
+ };
+ this.init = function (type, destructor) {
+ this.set_adjusted_ptr(0);
+ this.set_type(type);
+ this.set_destructor(destructor);
+ };
+ this.set_adjusted_ptr = function (adjustedPtr) {
+ HEAPU32[(this.ptr + 16) >> 2] = adjustedPtr;
+ };
+ this.get_adjusted_ptr = function () {
+ return HEAPU32[(this.ptr + 16) >> 2];
+ };
+ this.get_exception_ptr = function () {
+ var isPointer = ___cxa_is_pointer_type(this.get_type());
+ if (isPointer) {
+ return HEAPU32[this.excPtr >> 2];
+ }
+ var adjusted = this.get_adjusted_ptr();
+ if (adjusted !== 0) return adjusted;
+ return this.excPtr;
+ };
+ }
+
+ var ___resumeException = (ptr) => {
+ if (!exceptionLast) {
+ exceptionLast = ptr;
+ }
+ throw exceptionLast;
+ };
+
+ var findMatchingCatch = (args) => {
+ var thrown = exceptionLast;
+ if (!thrown) {
+ setTempRet0(0);
+ return 0;
+ }
+ var info = new ExceptionInfo(thrown);
+ info.set_adjusted_ptr(thrown);
+ var thrownType = info.get_type();
+ if (!thrownType) {
+ setTempRet0(0);
+ return thrown;
+ }
+ for (var arg in args) {
+ var caughtType = args[arg];
+ if (caughtType === 0 || caughtType === thrownType) {
+ break;
+ }
+ var adjusted_ptr_addr = info.ptr + 16;
+ if (___cxa_can_catch(caughtType, thrownType, adjusted_ptr_addr)) {
+ setTempRet0(caughtType);
+ return thrown;
+ }
+ }
+ setTempRet0(thrownType);
+ return thrown;
+ };
+
+ var ___cxa_find_matching_catch_2 = () => findMatchingCatch([]);
+
+ var ___cxa_find_matching_catch_4 = (arg0, arg1) => findMatchingCatch([arg0, arg1]);
+
+ var ___cxa_throw = (ptr, type, destructor) => {
+ var info = new ExceptionInfo(ptr);
+ info.init(type, destructor);
+ exceptionLast = ptr;
+ uncaughtExceptionCount++;
+ throw exceptionLast;
+ };
+
var SYSCALLS = {
varargs: undefined,
get() {
@@ -421,6 +544,62 @@ var createRendererModule = (() => {
return 0;
}
+ var lengthBytesUTF8 = (str) => {
+ var len = 0;
+ for (var i = 0; i < str.length; ++i) {
+ var c = str.charCodeAt(i);
+ if (c <= 127) {
+ len++;
+ } else if (c <= 2047) {
+ len += 2;
+ } else if (c >= 55296 && c <= 57343) {
+ len += 4;
+ ++i;
+ } else {
+ len += 3;
+ }
+ }
+ return len;
+ };
+
+ var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
+ if (!(maxBytesToWrite > 0)) return 0;
+ var startIdx = outIdx;
+ var endIdx = outIdx + maxBytesToWrite - 1;
+ for (var i = 0; i < str.length; ++i) {
+ var u = str.charCodeAt(i);
+ if (u >= 55296 && u <= 57343) {
+ var u1 = str.charCodeAt(++i);
+ u = (65536 + ((u & 1023) << 10)) | (u1 & 1023);
+ }
+ if (u <= 127) {
+ if (outIdx >= endIdx) break;
+ heap[outIdx++] = u;
+ } else if (u <= 2047) {
+ if (outIdx + 1 >= endIdx) break;
+ heap[outIdx++] = 192 | (u >> 6);
+ heap[outIdx++] = 128 | (u & 63);
+ } else if (u <= 65535) {
+ if (outIdx + 2 >= endIdx) break;
+ heap[outIdx++] = 224 | (u >> 12);
+ heap[outIdx++] = 128 | ((u >> 6) & 63);
+ heap[outIdx++] = 128 | (u & 63);
+ } else {
+ if (outIdx + 3 >= endIdx) break;
+ heap[outIdx++] = 240 | (u >> 18);
+ heap[outIdx++] = 128 | ((u >> 12) & 63);
+ heap[outIdx++] = 128 | ((u >> 6) & 63);
+ heap[outIdx++] = 128 | (u & 63);
+ }
+ }
+ heap[outIdx] = 0;
+ return outIdx - startIdx;
+ };
+
+ var stringToUTF8 = (str, outPtr, maxBytesToWrite) => stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);
+
+ var ___syscall_getcwd = (buf, size) => {};
+
function ___syscall_ioctl(fd, op, varargs) {
SYSCALLS.varargs = varargs;
return 0;
@@ -430,26 +609,19 @@ var createRendererModule = (() => {
SYSCALLS.varargs = varargs;
}
- var __embind_register_bigint = (primitiveType, name, size, minRange, maxRange) => {};
+ var structRegistrations = {};
- var embind_init_charCodes = () => {
- var codes = new Array(256);
- for (var i = 0; i < 256; ++i) {
- codes[i] = String.fromCharCode(i);
+ var runDestructors = (destructors) => {
+ while (destructors.length) {
+ var ptr = destructors.pop();
+ var del = destructors.pop();
+ del(ptr);
}
- embind_charCodes = codes;
};
- var embind_charCodes;
-
- var readLatin1String = (ptr) => {
- var ret = '';
- var c = ptr;
- while (HEAPU8[c]) {
- ret += embind_charCodes[HEAPU8[c++]];
- }
- return ret;
- };
+ /** @suppress {globalThis} */ function simpleReadValueFromPointer(pointer) {
+ return this['fromWireType'](HEAP32[pointer >> 2]);
+ }
var awaitingDependencies = {};
@@ -457,12 +629,6 @@ var createRendererModule = (() => {
var typeDependencies = {};
- var BindingError;
-
- var throwBindingError = (message) => {
- throw new BindingError(message);
- };
-
var InternalError;
var throwInternalError = (message) => {
@@ -507,6 +673,95 @@ var createRendererModule = (() => {
}
};
+ var __embind_finalize_value_object = (structType) => {
+ var reg = structRegistrations[structType];
+ delete structRegistrations[structType];
+ var rawConstructor = reg.rawConstructor;
+ var rawDestructor = reg.rawDestructor;
+ var fieldRecords = reg.fields;
+ var fieldTypes = fieldRecords
+ .map((field) => field.getterReturnType)
+ .concat(fieldRecords.map((field) => field.setterArgumentType));
+ whenDependentTypesAreResolved([structType], fieldTypes, (fieldTypes) => {
+ var fields = {};
+ fieldRecords.forEach((field, i) => {
+ var fieldName = field.fieldName;
+ var getterReturnType = fieldTypes[i];
+ var getter = field.getter;
+ var getterContext = field.getterContext;
+ var setterArgumentType = fieldTypes[i + fieldRecords.length];
+ var setter = field.setter;
+ var setterContext = field.setterContext;
+ fields[fieldName] = {
+ read: (ptr) => getterReturnType['fromWireType'](getter(getterContext, ptr)),
+ write: (ptr, o) => {
+ var destructors = [];
+ setter(setterContext, ptr, setterArgumentType['toWireType'](destructors, o));
+ runDestructors(destructors);
+ },
+ };
+ });
+ return [
+ {
+ name: reg.name,
+ fromWireType: (ptr) => {
+ var rv = {};
+ for (var i in fields) {
+ rv[i] = fields[i].read(ptr);
+ }
+ rawDestructor(ptr);
+ return rv;
+ },
+ toWireType: (destructors, o) => {
+ for (var fieldName in fields) {
+ if (!(fieldName in o)) {
+ throw new TypeError(`Missing field: "${fieldName}"`);
+ }
+ }
+ var ptr = rawConstructor();
+ for (fieldName in fields) {
+ fields[fieldName].write(ptr, o[fieldName]);
+ }
+ if (destructors !== null) {
+ destructors.push(rawDestructor, ptr);
+ }
+ return ptr;
+ },
+ argPackAdvance: GenericWireTypeSize,
+ readValueFromPointer: simpleReadValueFromPointer,
+ destructorFunction: rawDestructor,
+ },
+ ];
+ });
+ };
+
+ var __embind_register_bigint = (primitiveType, name, size, minRange, maxRange) => {};
+
+ var embind_init_charCodes = () => {
+ var codes = new Array(256);
+ for (var i = 0; i < 256; ++i) {
+ codes[i] = String.fromCharCode(i);
+ }
+ embind_charCodes = codes;
+ };
+
+ var embind_charCodes;
+
+ var readLatin1String = (ptr) => {
+ var ret = '';
+ var c = ptr;
+ while (HEAPU8[c]) {
+ ret += embind_charCodes[HEAPU8[c++]];
+ }
+ return ret;
+ };
+
+ var BindingError;
+
+ var throwBindingError = (message) => {
+ throw new BindingError(message);
+ };
+
/** @param {Object=} options */ function sharedRegisterType(rawType, registeredInstance, options = {}) {
var name = registeredInstance.name;
if (!rawType) {
@@ -1321,13 +1576,14 @@ var createRendererModule = (() => {
return array;
};
- var runDestructors = (destructors) => {
- while (destructors.length) {
- var ptr = destructors.pop();
- var del = destructors.pop();
- del(ptr);
+ function usesDestructorStack(argTypes) {
+ for (var i = 1; i < argTypes.length; ++i) {
+ if (argTypes[i] !== null && argTypes[i].destructorFunction === undefined) {
+ return true;
+ }
}
- };
+ return false;
+ }
function usesDestructorStack(argTypes) {
for (var i = 1; i < argTypes.length; ++i) {
@@ -1598,24 +1854,97 @@ var createRendererModule = (() => {
},
};
- /** @suppress {globalThis} */ function simpleReadValueFromPointer(pointer) {
- return this['fromWireType'](HEAP32[pointer >> 2]);
- }
+ var __embind_register_emval = (rawType, name) => {
+ name = readLatin1String(name);
+ registerType(rawType, {
+ name: name,
+ fromWireType: (handle) => {
+ var rv = Emval.toValue(handle);
+ __emval_decref(handle);
+ return rv;
+ },
+ toWireType: (destructors, value) => Emval.toHandle(value),
+ argPackAdvance: GenericWireTypeSize,
+ readValueFromPointer: simpleReadValueFromPointer,
+ destructorFunction: null,
+ });
+ };
- var EmValType = {
- name: 'emscripten::val',
- fromWireType: (handle) => {
- var rv = Emval.toValue(handle);
- __emval_decref(handle);
- return rv;
- },
- toWireType: (destructors, value) => Emval.toHandle(value),
- argPackAdvance: GenericWireTypeSize,
- readValueFromPointer: simpleReadValueFromPointer,
- destructorFunction: null,
+ var enumReadValueFromPointer = (name, width, signed) => {
+ switch (width) {
+ case 1:
+ return signed
+ ? function (pointer) {
+ return this['fromWireType'](HEAP8[pointer >> 0]);
+ }
+ : function (pointer) {
+ return this['fromWireType'](HEAPU8[pointer >> 0]);
+ };
+
+ case 2:
+ return signed
+ ? function (pointer) {
+ return this['fromWireType'](HEAP16[pointer >> 1]);
+ }
+ : function (pointer) {
+ return this['fromWireType'](HEAPU16[pointer >> 1]);
+ };
+
+ case 4:
+ return signed
+ ? function (pointer) {
+ return this['fromWireType'](HEAP32[pointer >> 2]);
+ }
+ : function (pointer) {
+ return this['fromWireType'](HEAPU32[pointer >> 2]);
+ };
+
+ default:
+ throw new TypeError(`invalid integer width (${width}): ${name}`);
+ }
+ };
+
+ /** @suppress {globalThis} */ var __embind_register_enum = (rawType, name, size, isSigned) => {
+ name = readLatin1String(name);
+ function ctor() {}
+ ctor.values = {};
+ registerType(rawType, {
+ name: name,
+ constructor: ctor,
+ fromWireType: function (c) {
+ return this.constructor.values[c];
+ },
+ toWireType: (destructors, c) => c.value,
+ argPackAdvance: GenericWireTypeSize,
+ readValueFromPointer: enumReadValueFromPointer(name, size, isSigned),
+ destructorFunction: null,
+ });
+ exposePublicSymbol(name, ctor);
+ };
+
+ var requireRegisteredType = (rawType, humanName) => {
+ var impl = registeredTypes[rawType];
+ if (undefined === impl) {
+ throwBindingError(humanName + ' has unknown type ' + getTypeName(rawType));
+ }
+ return impl;
};
- var __embind_register_emval = (rawType) => registerType(rawType, EmValType);
+ var __embind_register_enum_value = (rawEnumType, name, enumValue) => {
+ var enumType = requireRegisteredType(rawEnumType, 'enum');
+ name = readLatin1String(name);
+ var Enum = enumType.constructor;
+ var Value = Object.create(enumType.constructor.prototype, {
+ value: {
+ value: enumValue,
+ },
+ constructor: {
+ value: createNamedFunction(`${enumType.name}_${name}`, function () {}),
+ },
+ });
+ Enum.values[enumValue] = Value;
+ Enum[name] = Value;
+ };
var embindRepr = (v) => {
if (v === null) {
@@ -1740,58 +2069,42 @@ var createRendererModule = (() => {
);
};
- var stringToUTF8Array = (str, heap, outIdx, maxBytesToWrite) => {
- if (!(maxBytesToWrite > 0)) return 0;
- var startIdx = outIdx;
- var endIdx = outIdx + maxBytesToWrite - 1;
- for (var i = 0; i < str.length; ++i) {
- var u = str.charCodeAt(i);
- if (u >= 55296 && u <= 57343) {
- var u1 = str.charCodeAt(++i);
- u = (65536 + ((u & 1023) << 10)) | (u1 & 1023);
- }
- if (u <= 127) {
- if (outIdx >= endIdx) break;
- heap[outIdx++] = u;
- } else if (u <= 2047) {
- if (outIdx + 1 >= endIdx) break;
- heap[outIdx++] = 192 | (u >> 6);
- heap[outIdx++] = 128 | (u & 63);
- } else if (u <= 65535) {
- if (outIdx + 2 >= endIdx) break;
- heap[outIdx++] = 224 | (u >> 12);
- heap[outIdx++] = 128 | ((u >> 6) & 63);
- heap[outIdx++] = 128 | (u & 63);
- } else {
- if (outIdx + 3 >= endIdx) break;
- heap[outIdx++] = 240 | (u >> 18);
- heap[outIdx++] = 128 | ((u >> 12) & 63);
- heap[outIdx++] = 128 | ((u >> 6) & 63);
- heap[outIdx++] = 128 | (u & 63);
- }
- }
- heap[outIdx] = 0;
- return outIdx - startIdx;
- };
-
- var stringToUTF8 = (str, outPtr, maxBytesToWrite) => stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);
-
- var lengthBytesUTF8 = (str) => {
- var len = 0;
- for (var i = 0; i < str.length; ++i) {
- var c = str.charCodeAt(i);
- if (c <= 127) {
- len++;
- } else if (c <= 2047) {
- len += 2;
- } else if (c >= 55296 && c <= 57343) {
- len += 4;
- ++i;
- } else {
- len += 3;
- }
- }
- return len;
+ var __embind_register_smart_ptr = (
+ rawType,
+ rawPointeeType,
+ name,
+ sharingPolicy,
+ getPointeeSignature,
+ rawGetPointee,
+ constructorSignature,
+ rawConstructor,
+ shareSignature,
+ rawShare,
+ destructorSignature,
+ rawDestructor,
+ ) => {
+ name = readLatin1String(name);
+ rawGetPointee = embind__requireFunction(getPointeeSignature, rawGetPointee);
+ rawConstructor = embind__requireFunction(constructorSignature, rawConstructor);
+ rawShare = embind__requireFunction(shareSignature, rawShare);
+ rawDestructor = embind__requireFunction(destructorSignature, rawDestructor);
+ whenDependentTypesAreResolved([rawType], [rawPointeeType], function (pointeeType) {
+ pointeeType = pointeeType[0];
+ var registeredPointer = new RegisteredPointer(
+ name,
+ pointeeType.registeredClass,
+ false,
+ false,
+ true,
+ pointeeType,
+ sharingPolicy,
+ rawGetPointee,
+ rawConstructor,
+ rawShare,
+ rawDestructor,
+ );
+ return [registeredPointer];
+ });
};
var __embind_register_std_string = (rawType, name) => {
@@ -2026,6 +2339,45 @@ var createRendererModule = (() => {
});
};
+ var __embind_register_value_object = (
+ rawType,
+ name,
+ constructorSignature,
+ rawConstructor,
+ destructorSignature,
+ rawDestructor,
+ ) => {
+ structRegistrations[rawType] = {
+ name: readLatin1String(name),
+ rawConstructor: embind__requireFunction(constructorSignature, rawConstructor),
+ rawDestructor: embind__requireFunction(destructorSignature, rawDestructor),
+ fields: [],
+ };
+ };
+
+ var __embind_register_value_object_field = (
+ structType,
+ fieldName,
+ getterReturnType,
+ getterSignature,
+ getter,
+ getterContext,
+ setterArgumentType,
+ setterSignature,
+ setter,
+ setterContext,
+ ) => {
+ structRegistrations[structType].fields.push({
+ fieldName: readLatin1String(fieldName),
+ getterReturnType: getterReturnType,
+ getter: embind__requireFunction(getterSignature, getter),
+ getterContext: getterContext,
+ setterArgumentType: setterArgumentType,
+ setter: embind__requireFunction(setterSignature, setter),
+ setterContext: setterContext,
+ });
+ };
+
var __embind_register_void = (rawType, name) => {
name = readLatin1String(name);
registerType(rawType, {
@@ -2041,18 +2393,70 @@ var createRendererModule = (() => {
throw Infinity;
};
+ var emval_methodCallers = [];
+
+ var __emval_call = (caller, handle, destructorsRef, args) => {
+ caller = emval_methodCallers[caller];
+ handle = Emval.toValue(handle);
+ return caller(null, handle, destructorsRef, args);
+ };
+
+ var emval_addMethodCaller = (caller) => {
+ var id = emval_methodCallers.length;
+ emval_methodCallers.push(caller);
+ return id;
+ };
+
+ var emval_lookupTypes = (argCount, argTypes) => {
+ var a = new Array(argCount);
+ for (var i = 0; i < argCount; ++i) {
+ a[i] = requireRegisteredType(HEAPU32[(argTypes + i * 4) >> 2], 'parameter ' + i);
+ }
+ return a;
+ };
+
+ var reflectConstruct = Reflect.construct;
+
+ var emval_returnValue = (returnType, destructorsRef, handle) => {
+ var destructors = [];
+ var result = returnType['toWireType'](destructors, handle);
+ if (destructors.length) {
+ HEAPU32[destructorsRef >> 2] = Emval.toHandle(destructors);
+ }
+ return result;
+ };
+
+ var __emval_get_method_caller = (argCount, argTypes, kind) => {
+ var types = emval_lookupTypes(argCount, argTypes);
+ var retType = types.shift();
+ argCount--;
+ var argN = new Array(argCount);
+ var invokerFunction = (obj, func, destructorsRef, args) => {
+ var offset = 0;
+ for (var i = 0; i < argCount; ++i) {
+ argN[i] = types[i]['readValueFromPointer'](args + offset);
+ offset += types[i]['argPackAdvance'];
+ }
+ var rv = kind === /* CONSTRUCTOR */ 1 ? reflectConstruct(func, argN) : func.apply(obj, argN);
+ for (var i = 0; i < argCount; ++i) {
+ types[i].deleteObject?.(argN[i]);
+ }
+ return emval_returnValue(retType, destructorsRef, rv);
+ };
+ var functionName = `methodCaller<(${types.map((t) => t.name).join(', ')}) => ${retType.name}>`;
+ return emval_addMethodCaller(createNamedFunction(functionName, invokerFunction));
+ };
+
var __emval_incref = (handle) => {
if (handle > 4) {
emval_handles.get(handle).refcount += 1;
}
};
- var requireRegisteredType = (rawType, humanName) => {
- var impl = registeredTypes[rawType];
- if (undefined === impl) {
- throwBindingError(humanName + ' has unknown type ' + getTypeName(rawType));
- }
- return impl;
+ var __emval_run_destructors = (handle) => {
+ var destructors = Emval.toValue(handle);
+ runDestructors(destructors);
+ __emval_decref(handle);
};
var __emval_take_value = (type, arg) => {
@@ -2065,6 +2469,10 @@ var createRendererModule = (() => {
abort('');
};
+ var _emscripten_get_now;
+
+ _emscripten_get_now = () => performance.now();
+
var _emscripten_memcpy_js = (dest, src, num) => HEAPU8.copyWithin(dest, src, src + num);
var getHeapMax = () => 2147483648;
@@ -2099,6 +2507,64 @@ var createRendererModule = (() => {
return false;
};
+ var ENV = {};
+
+ var getExecutableName = () => thisProgram || './this.program';
+
+ var getEnvStrings = () => {
+ if (!getEnvStrings.strings) {
+ var lang =
+ ((typeof navigator == 'object' && navigator.languages && navigator.languages[0]) || 'C').replace('-', '_') +
+ '.UTF-8';
+ var env = {
+ USER: 'web_user',
+ LOGNAME: 'web_user',
+ PATH: '/',
+ PWD: '/',
+ HOME: '/home/web_user',
+ LANG: lang,
+ _: getExecutableName(),
+ };
+ for (var x in ENV) {
+ if (ENV[x] === undefined) delete env[x];
+ else env[x] = ENV[x];
+ }
+ var strings = [];
+ for (var x in env) {
+ strings.push(`${x}=${env[x]}`);
+ }
+ getEnvStrings.strings = strings;
+ }
+ return getEnvStrings.strings;
+ };
+
+ var stringToAscii = (str, buffer) => {
+ for (var i = 0; i < str.length; ++i) {
+ HEAP8[buffer++ >> 0] = str.charCodeAt(i);
+ }
+ HEAP8[buffer >> 0] = 0;
+ };
+
+ var _environ_get = (__environ, environ_buf) => {
+ var bufSize = 0;
+ getEnvStrings().forEach((string, i) => {
+ var ptr = environ_buf + bufSize;
+ HEAPU32[(__environ + i * 4) >> 2] = ptr;
+ stringToAscii(string, ptr);
+ bufSize += string.length + 1;
+ });
+ return 0;
+ };
+
+ var _environ_sizes_get = (penviron_count, penviron_buf_size) => {
+ var strings = getEnvStrings();
+ HEAPU32[penviron_count >> 2] = strings.length;
+ var bufSize = 0;
+ strings.forEach((string) => (bufSize += string.length + 1));
+ HEAPU32[penviron_buf_size >> 2] = bufSize;
+ return 0;
+ };
+
var _fd_close = (fd) => 52;
var _fd_read = (fd, iov, iovcnt, pnum) => 52;
@@ -2138,15 +2604,285 @@ var createRendererModule = (() => {
return 0;
};
- embind_init_charCodes();
+ var initRandomFill = () => {
+ if (typeof crypto == 'object' && typeof crypto['getRandomValues'] == 'function') {
+ return (view) => crypto.getRandomValues(view);
+ } else abort('initRandomDevice');
+ };
- BindingError = Module['BindingError'] = class BindingError extends Error {
- constructor(message) {
- super(message);
- this.name = 'BindingError';
+ var randomFill = (view) => (randomFill = initRandomFill())(view);
+
+ var _getentropy = (buffer, size) => {
+ randomFill(HEAPU8.subarray(buffer, buffer + size));
+ return 0;
+ };
+
+ var _llvm_eh_typeid_for = (type) => type;
+
+ var isLeapYear = (year) => year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
+
+ var arraySum = (array, index) => {
+ var sum = 0;
+ for (var i = 0; i <= index; sum += array[i++]) {}
+ return sum;
+ };
+
+ var MONTH_DAYS_LEAP = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+
+ var MONTH_DAYS_REGULAR = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+
+ var addDays = (date, days) => {
+ var newDate = new Date(date.getTime());
+ while (days > 0) {
+ var leap = isLeapYear(newDate.getFullYear());
+ var currentMonth = newDate.getMonth();
+ var daysInCurrentMonth = (leap ? MONTH_DAYS_LEAP : MONTH_DAYS_REGULAR)[currentMonth];
+ if (days > daysInCurrentMonth - newDate.getDate()) {
+ days -= daysInCurrentMonth - newDate.getDate() + 1;
+ newDate.setDate(1);
+ if (currentMonth < 11) {
+ newDate.setMonth(currentMonth + 1);
+ } else {
+ newDate.setMonth(0);
+ newDate.setFullYear(newDate.getFullYear() + 1);
+ }
+ } else {
+ newDate.setDate(newDate.getDate() + days);
+ return newDate;
+ }
}
+ return newDate;
};
+ /** @type {function(string, boolean=, number=)} */ function intArrayFromString(stringy, dontAddNull, length) {
+ var len = length > 0 ? length : lengthBytesUTF8(stringy) + 1;
+ var u8array = new Array(len);
+ var numBytesWritten = stringToUTF8Array(stringy, u8array, 0, u8array.length);
+ if (dontAddNull) u8array.length = numBytesWritten;
+ return u8array;
+ }
+
+ var writeArrayToMemory = (array, buffer) => {
+ HEAP8.set(array, buffer);
+ };
+
+ var _strftime = (s, maxsize, format, tm) => {
+ var tm_zone = HEAPU32[(tm + 40) >> 2];
+ var date = {
+ tm_sec: HEAP32[tm >> 2],
+ tm_min: HEAP32[(tm + 4) >> 2],
+ tm_hour: HEAP32[(tm + 8) >> 2],
+ tm_mday: HEAP32[(tm + 12) >> 2],
+ tm_mon: HEAP32[(tm + 16) >> 2],
+ tm_year: HEAP32[(tm + 20) >> 2],
+ tm_wday: HEAP32[(tm + 24) >> 2],
+ tm_yday: HEAP32[(tm + 28) >> 2],
+ tm_isdst: HEAP32[(tm + 32) >> 2],
+ tm_gmtoff: HEAP32[(tm + 36) >> 2],
+ tm_zone: tm_zone ? UTF8ToString(tm_zone) : '',
+ };
+ var pattern = UTF8ToString(format);
+ var EXPANSION_RULES_1 = {
+ '%c': '%a %b %d %H:%M:%S %Y',
+ '%D': '%m/%d/%y',
+ '%F': '%Y-%m-%d',
+ '%h': '%b',
+ '%r': '%I:%M:%S %p',
+ '%R': '%H:%M',
+ '%T': '%H:%M:%S',
+ '%x': '%m/%d/%y',
+ '%X': '%H:%M:%S',
+ '%Ec': '%c',
+ '%EC': '%C',
+ '%Ex': '%m/%d/%y',
+ '%EX': '%H:%M:%S',
+ '%Ey': '%y',
+ '%EY': '%Y',
+ '%Od': '%d',
+ '%Oe': '%e',
+ '%OH': '%H',
+ '%OI': '%I',
+ '%Om': '%m',
+ '%OM': '%M',
+ '%OS': '%S',
+ '%Ou': '%u',
+ '%OU': '%U',
+ '%OV': '%V',
+ '%Ow': '%w',
+ '%OW': '%W',
+ '%Oy': '%y',
+ };
+ for (var rule in EXPANSION_RULES_1) {
+ pattern = pattern.replace(new RegExp(rule, 'g'), EXPANSION_RULES_1[rule]);
+ }
+ var WEEKDAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
+ var MONTHS = [
+ 'January',
+ 'February',
+ 'March',
+ 'April',
+ 'May',
+ 'June',
+ 'July',
+ 'August',
+ 'September',
+ 'October',
+ 'November',
+ 'December',
+ ];
+ function leadingSomething(value, digits, character) {
+ var str = typeof value == 'number' ? value.toString() : value || '';
+ while (str.length < digits) {
+ str = character[0] + str;
+ }
+ return str;
+ }
+ function leadingNulls(value, digits) {
+ return leadingSomething(value, digits, '0');
+ }
+ function compareByDay(date1, date2) {
+ function sgn(value) {
+ return value < 0 ? -1 : value > 0 ? 1 : 0;
+ }
+ var compare;
+ if ((compare = sgn(date1.getFullYear() - date2.getFullYear())) === 0) {
+ if ((compare = sgn(date1.getMonth() - date2.getMonth())) === 0) {
+ compare = sgn(date1.getDate() - date2.getDate());
+ }
+ }
+ return compare;
+ }
+ function getFirstWeekStartDate(janFourth) {
+ switch (janFourth.getDay()) {
+ case 0:
+ return new Date(janFourth.getFullYear() - 1, 11, 29);
+
+ case 1:
+ return janFourth;
+
+ case 2:
+ return new Date(janFourth.getFullYear(), 0, 3);
+
+ case 3:
+ return new Date(janFourth.getFullYear(), 0, 2);
+
+ case 4:
+ return new Date(janFourth.getFullYear(), 0, 1);
+
+ case 5:
+ return new Date(janFourth.getFullYear() - 1, 11, 31);
+
+ case 6:
+ return new Date(janFourth.getFullYear() - 1, 11, 30);
+ }
+ }
+ function getWeekBasedYear(date) {
+ var thisDate = addDays(new Date(date.tm_year + 1900, 0, 1), date.tm_yday);
+ var janFourthThisYear = new Date(thisDate.getFullYear(), 0, 4);
+ var janFourthNextYear = new Date(thisDate.getFullYear() + 1, 0, 4);
+ var firstWeekStartThisYear = getFirstWeekStartDate(janFourthThisYear);
+ var firstWeekStartNextYear = getFirstWeekStartDate(janFourthNextYear);
+ if (compareByDay(firstWeekStartThisYear, thisDate) <= 0) {
+ if (compareByDay(firstWeekStartNextYear, thisDate) <= 0) {
+ return thisDate.getFullYear() + 1;
+ }
+ return thisDate.getFullYear();
+ }
+ return thisDate.getFullYear() - 1;
+ }
+ var EXPANSION_RULES_2 = {
+ '%a': (date) => WEEKDAYS[date.tm_wday].substring(0, 3),
+ '%A': (date) => WEEKDAYS[date.tm_wday],
+ '%b': (date) => MONTHS[date.tm_mon].substring(0, 3),
+ '%B': (date) => MONTHS[date.tm_mon],
+ '%C': (date) => {
+ var year = date.tm_year + 1900;
+ return leadingNulls((year / 100) | 0, 2);
+ },
+ '%d': (date) => leadingNulls(date.tm_mday, 2),
+ '%e': (date) => leadingSomething(date.tm_mday, 2, ' '),
+ '%g': (date) => getWeekBasedYear(date).toString().substring(2),
+ '%G': (date) => getWeekBasedYear(date),
+ '%H': (date) => leadingNulls(date.tm_hour, 2),
+ '%I': (date) => {
+ var twelveHour = date.tm_hour;
+ if (twelveHour == 0) twelveHour = 12;
+ else if (twelveHour > 12) twelveHour -= 12;
+ return leadingNulls(twelveHour, 2);
+ },
+ '%j': (date) =>
+ leadingNulls(
+ date.tm_mday +
+ arraySum(isLeapYear(date.tm_year + 1900) ? MONTH_DAYS_LEAP : MONTH_DAYS_REGULAR, date.tm_mon - 1),
+ 3,
+ ),
+ '%m': (date) => leadingNulls(date.tm_mon + 1, 2),
+ '%M': (date) => leadingNulls(date.tm_min, 2),
+ '%n': () => '\n',
+ '%p': (date) => {
+ if (date.tm_hour >= 0 && date.tm_hour < 12) {
+ return 'AM';
+ }
+ return 'PM';
+ },
+ '%S': (date) => leadingNulls(date.tm_sec, 2),
+ '%t': () => '\t',
+ '%u': (date) => date.tm_wday || 7,
+ '%U': (date) => {
+ var days = date.tm_yday + 7 - date.tm_wday;
+ return leadingNulls(Math.floor(days / 7), 2);
+ },
+ '%V': (date) => {
+ var val = Math.floor((date.tm_yday + 7 - ((date.tm_wday + 6) % 7)) / 7);
+ if ((date.tm_wday + 371 - date.tm_yday - 2) % 7 <= 2) {
+ val++;
+ }
+ if (!val) {
+ val = 52;
+ var dec31 = (date.tm_wday + 7 - date.tm_yday - 1) % 7;
+ if (dec31 == 4 || (dec31 == 5 && isLeapYear((date.tm_year % 400) - 1))) {
+ val++;
+ }
+ } else if (val == 53) {
+ var jan1 = (date.tm_wday + 371 - date.tm_yday) % 7;
+ if (jan1 != 4 && (jan1 != 3 || !isLeapYear(date.tm_year))) val = 1;
+ }
+ return leadingNulls(val, 2);
+ },
+ '%w': (date) => date.tm_wday,
+ '%W': (date) => {
+ var days = date.tm_yday + 7 - ((date.tm_wday + 6) % 7);
+ return leadingNulls(Math.floor(days / 7), 2);
+ },
+ '%y': (date) => (date.tm_year + 1900).toString().substring(2),
+ '%Y': (date) => date.tm_year + 1900,
+ '%z': (date) => {
+ var off = date.tm_gmtoff;
+ var ahead = off >= 0;
+ off = Math.abs(off) / 60;
+ off = (off / 60) * 100 + (off % 60);
+ return (ahead ? '+' : '-') + String('0000' + off).slice(-4);
+ },
+ '%Z': (date) => date.tm_zone,
+ '%%': () => '%',
+ };
+ pattern = pattern.replace(/%%/g, '\0\0');
+ for (var rule in EXPANSION_RULES_2) {
+ if (pattern.includes(rule)) {
+ pattern = pattern.replace(new RegExp(rule, 'g'), EXPANSION_RULES_2[rule](date));
+ }
+ }
+ pattern = pattern.replace(/\0\0/g, '%');
+ var bytes = intArrayFromString(pattern, false);
+ if (bytes.length > maxsize) {
+ return 0;
+ }
+ writeArrayToMemory(bytes, s);
+ return bytes.length - 1;
+ };
+
+ var _strftime_l = (s, maxsize, format, tm, loc) => _strftime(s, maxsize, format, tm);
+
InternalError = Module['InternalError'] = class InternalError extends Error {
constructor(message) {
super(message);
@@ -2154,6 +2890,15 @@ var createRendererModule = (() => {
}
};
+ embind_init_charCodes();
+
+ BindingError = Module['BindingError'] = class BindingError extends Error {
+ constructor(message) {
+ super(message);
+ this.name = 'BindingError';
+ }
+ };
+
init_ClassHandle();
init_embind();
@@ -2165,68 +2910,169 @@ var createRendererModule = (() => {
init_emval();
var wasmImports = {
- /** @export */ b: ___assert_fail,
- /** @export */ n: ___syscall_fcntl64,
- /** @export */ D: ___syscall_ioctl,
- /** @export */ E: ___syscall_openat,
- /** @export */ w: __embind_register_bigint,
- /** @export */ q: __embind_register_bool,
- /** @export */ H: __embind_register_class,
- /** @export */ G: __embind_register_class_constructor,
- /** @export */ e: __embind_register_class_function,
- /** @export */ F: __embind_register_emval,
- /** @export */ o: __embind_register_float,
- /** @export */ f: __embind_register_integer,
- /** @export */ d: __embind_register_memory_view,
- /** @export */ p: __embind_register_std_string,
- /** @export */ k: __embind_register_std_wstring,
- /** @export */ r: __embind_register_void,
- /** @export */ y: __emscripten_throw_longjmp,
- /** @export */ s: __emval_decref,
- /** @export */ t: __emval_incref,
- /** @export */ g: __emval_take_value,
- /** @export */ h: _abort,
- /** @export */ A: _emscripten_memcpy_js,
- /** @export */ z: _emscripten_resize_heap,
- /** @export */ m: _fd_close,
- /** @export */ C: _fd_read,
- /** @export */ v: _fd_seek,
- /** @export */ B: _fd_write,
- /** @export */ j: invoke_ii,
- /** @export */ i: invoke_iiii,
- /** @export */ l: invoke_iiiiii,
- /** @export */ a: invoke_vi,
+ /** @export */ m: ___assert_fail,
+ /** @export */ qa: ___cxa_begin_catch,
+ /** @export */ pa: ___cxa_end_catch,
+ /** @export */ a: ___cxa_find_matching_catch_2,
+ /** @export */ f: ___cxa_find_matching_catch_4,
+ /** @export */ v: ___cxa_throw,
+ /** @export */ d: ___resumeException,
+ /** @export */ I: ___syscall_fcntl64,
+ /** @export */ ea: ___syscall_getcwd,
+ /** @export */ ga: ___syscall_ioctl,
+ /** @export */ ha: ___syscall_openat,
+ /** @export */ za: __embind_finalize_value_object,
+ /** @export */ T: __embind_register_bigint,
+ /** @export */ na: __embind_register_bool,
+ /** @export */ P: __embind_register_class,
+ /** @export */ O: __embind_register_class_constructor,
+ /** @export */ q: __embind_register_class_function,
+ /** @export */ la: __embind_register_emval,
+ /** @export */ $: __embind_register_enum,
+ /** @export */ z: __embind_register_enum_value,
+ /** @export */ K: __embind_register_float,
+ /** @export */ s: __embind_register_integer,
+ /** @export */ p: __embind_register_memory_view,
+ /** @export */ ya: __embind_register_smart_ptr,
+ /** @export */ L: __embind_register_std_string,
+ /** @export */ F: __embind_register_std_wstring,
+ /** @export */ Q: __embind_register_value_object,
+ /** @export */ y: __embind_register_value_object_field,
+ /** @export */ oa: __embind_register_void,
+ /** @export */ ba: __emscripten_throw_longjmp,
+ /** @export */ xa: __emval_call,
+ /** @export */ ma: __emval_decref,
+ /** @export */ wa: __emval_get_method_caller,
+ /** @export */ G: __emval_incref,
+ /** @export */ va: __emval_run_destructors,
+ /** @export */ E: __emval_take_value,
+ /** @export */ N: _abort,
+ /** @export */ w: _emscripten_get_now,
+ /** @export */ ia: _emscripten_memcpy_js,
+ /** @export */ da: _emscripten_resize_heap,
+ /** @export */ ja: _environ_get,
+ /** @export */ ka: _environ_sizes_get,
+ /** @export */ J: _fd_close,
+ /** @export */ fa: _fd_read,
+ /** @export */ S: _fd_seek,
+ /** @export */ D: _fd_write,
+ /** @export */ ra: _getentropy,
+ /** @export */ u: invoke_d,
+ /** @export */ B: invoke_fi,
+ /** @export */ H: invoke_i,
+ /** @export */ h: invoke_ii,
+ /** @export */ A: invoke_iif,
+ /** @export */ g: invoke_iii,
+ /** @export */ k: invoke_iiii,
+ /** @export */ o: invoke_iiiii,
+ /** @export */ r: invoke_iiiiii,
+ /** @export */ ua: invoke_iiiiiii,
+ /** @export */ M: invoke_iiiiiiii,
+ /** @export */ aa: invoke_ji,
+ /** @export */ Y: invoke_jii,
+ /** @export */ l: invoke_v,
+ /** @export */ b: invoke_vi,
+ /** @export */ t: invoke_vid,
+ /** @export */ x: invoke_vif,
/** @export */ c: invoke_vii,
- /** @export */ x: invoke_viiii,
- /** @export */ u: invoke_viiij,
+ /** @export */ ta: invoke_viif,
+ /** @export */ sa: invoke_viiff,
+ /** @export */ e: invoke_viii,
+ /** @export */ n: invoke_viiii,
+ /** @export */ i: invoke_viiiii,
+ /** @export */ C: invoke_viiiiii,
+ /** @export */ R: invoke_viiij,
+ /** @export */ V: invoke_viiiji,
+ /** @export */ W: invoke_viij,
+ /** @export */ U: invoke_viiji,
+ /** @export */ X: invoke_viijj,
+ /** @export */ Z: invoke_vij,
+ /** @export */ _: invoke_vijiji,
+ /** @export */ j: _llvm_eh_typeid_for,
+ /** @export */ ca: _strftime_l,
};
var wasmExports = createWasm();
- var ___wasm_call_ctors = () => (___wasm_call_ctors = wasmExports['J'])();
+ var ___wasm_call_ctors = () => (___wasm_call_ctors = wasmExports['Ba'])();
+
+ var _malloc = (a0) => (_malloc = wasmExports['Ca'])(a0);
- var _free = (a0) => (_free = wasmExports['K'])(a0);
+ var _free = (a0) => (_free = wasmExports['Ea'])(a0);
- var _malloc = (a0) => (_malloc = wasmExports['L'])(a0);
+ var stackSave = () => (stackSave = wasmExports['P'])();
- var ___getTypeName = (a0) => (___getTypeName = wasmExports['M'])(a0);
+ var ___getTypeName = (a0) => (___getTypeName = wasmExports['Fa'])(a0);
- var _setThrew = (a0, a1) => (_setThrew = wasmExports['O'])(a0, a1);
+ var _htonl = (a0) => (_htonl = wasmExports['htonl'])(a0);
- var stackSave = () => (stackSave = wasmExports['P'])();
+ var _htons = (a0) => (_htons = wasmExports['htons'])(a0);
+
+ var _ntohs = (a0) => (_ntohs = wasmExports['ntohs'])(a0);
+
+ var _setThrew = (a0, a1) => (_setThrew = wasmExports['Ga'])(a0, a1);
+
+ var setTempRet0 = (a0) => (setTempRet0 = wasmExports['Ha'])(a0);
+
+ var stackSave = () => (stackSave = wasmExports['Ia'])();
+
+ var stackRestore = (a0) => (stackRestore = wasmExports['Ja'])(a0);
+
+ var ___cxa_decrement_exception_refcount = (a0) => (___cxa_decrement_exception_refcount = wasmExports['Ka'])(a0);
+
+ var ___cxa_increment_exception_refcount = (a0) => (___cxa_increment_exception_refcount = wasmExports['La'])(a0);
+
+ var ___cxa_can_catch = (a0, a1, a2) => (___cxa_can_catch = wasmExports['Ma'])(a0, a1, a2);
+
+ var ___cxa_is_pointer_type = (a0) => (___cxa_is_pointer_type = wasmExports['Na'])(a0);
+
+ var dynCall_iijj = (Module['dynCall_iijj'] = (a0, a1, a2, a3, a4, a5) =>
+ (dynCall_iijj = Module['dynCall_iijj'] = wasmExports['Oa'])(a0, a1, a2, a3, a4, a5));
+
+ var dynCall_vijj = (Module['dynCall_vijj'] = (a0, a1, a2, a3, a4, a5) =>
+ (dynCall_vijj = Module['dynCall_vijj'] = wasmExports['Pa'])(a0, a1, a2, a3, a4, a5));
+
+ var dynCall_ji = (Module['dynCall_ji'] = (a0, a1) =>
+ (dynCall_ji = Module['dynCall_ji'] = wasmExports['Qa'])(a0, a1));
+
+ var dynCall_vijiji = (Module['dynCall_vijiji'] = (a0, a1, a2, a3, a4, a5, a6, a7) =>
+ (dynCall_vijiji = Module['dynCall_vijiji'] = wasmExports['Ra'])(a0, a1, a2, a3, a4, a5, a6, a7));
+
+ var dynCall_vij = (Module['dynCall_vij'] = (a0, a1, a2, a3) =>
+ (dynCall_vij = Module['dynCall_vij'] = wasmExports['Sa'])(a0, a1, a2, a3));
- var stackRestore = (a0) => (stackRestore = wasmExports['Q'])(a0);
+ var dynCall_jii = (Module['dynCall_jii'] = (a0, a1, a2) =>
+ (dynCall_jii = Module['dynCall_jii'] = wasmExports['Ta'])(a0, a1, a2));
- var ___cxa_increment_exception_refcount = (a0) =>
- (___cxa_increment_exception_refcount = wasmExports['__cxa_increment_exception_refcount'])(a0);
+ var dynCall_viijj = (Module['dynCall_viijj'] = (a0, a1, a2, a3, a4, a5, a6) =>
+ (dynCall_viijj = Module['dynCall_viijj'] = wasmExports['Ua'])(a0, a1, a2, a3, a4, a5, a6));
- var ___cxa_is_pointer_type = (a0) => (___cxa_is_pointer_type = wasmExports['__cxa_is_pointer_type'])(a0);
+ var dynCall_viij = (Module['dynCall_viij'] = (a0, a1, a2, a3, a4) =>
+ (dynCall_viij = Module['dynCall_viij'] = wasmExports['Va'])(a0, a1, a2, a3, a4));
+
+ var dynCall_viiiji = (Module['dynCall_viiiji'] = (a0, a1, a2, a3, a4, a5, a6) =>
+ (dynCall_viiiji = Module['dynCall_viiiji'] = wasmExports['Wa'])(a0, a1, a2, a3, a4, a5, a6));
+
+ var dynCall_viiji = (Module['dynCall_viiji'] = (a0, a1, a2, a3, a4, a5) =>
+ (dynCall_viiji = Module['dynCall_viiji'] = wasmExports['Xa'])(a0, a1, a2, a3, a4, a5));
var dynCall_viiij = (Module['dynCall_viiij'] = (a0, a1, a2, a3, a4, a5) =>
- (dynCall_viiij = Module['dynCall_viiij'] = wasmExports['R'])(a0, a1, a2, a3, a4, a5));
+ (dynCall_viiij = Module['dynCall_viiij'] = wasmExports['Ya'])(a0, a1, a2, a3, a4, a5));
var dynCall_jiji = (Module['dynCall_jiji'] = (a0, a1, a2, a3, a4) =>
- (dynCall_jiji = Module['dynCall_jiji'] = wasmExports['S'])(a0, a1, a2, a3, a4));
+ (dynCall_jiji = Module['dynCall_jiji'] = wasmExports['Za'])(a0, a1, a2, a3, a4));
+
+ var dynCall_viijii = (Module['dynCall_viijii'] = (a0, a1, a2, a3, a4, a5, a6) =>
+ (dynCall_viijii = Module['dynCall_viijii'] = wasmExports['_a'])(a0, a1, a2, a3, a4, a5, a6));
+
+ var dynCall_iiiiij = (Module['dynCall_iiiiij'] = (a0, a1, a2, a3, a4, a5, a6) =>
+ (dynCall_iiiiij = Module['dynCall_iiiiij'] = wasmExports['$a'])(a0, a1, a2, a3, a4, a5, a6));
+
+ var dynCall_iiiiijj = (Module['dynCall_iiiiijj'] = (a0, a1, a2, a3, a4, a5, a6, a7, a8) =>
+ (dynCall_iiiiijj = Module['dynCall_iiiiijj'] = wasmExports['ab'])(a0, a1, a2, a3, a4, a5, a6, a7, a8));
+
+ var dynCall_iiiiiijj = (Module['dynCall_iiiiiijj'] = (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) =>
+ (dynCall_iiiiiijj = Module['dynCall_iiiiiijj'] = wasmExports['bb'])(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9));
function invoke_vi(index, a1) {
var sp = stackSave();
@@ -2250,10 +3096,10 @@ var createRendererModule = (() => {
}
}
- function invoke_ii(index, a1) {
+ function invoke_viii(index, a1, a2, a3) {
var sp = stackSave();
try {
- return getWasmTableEntry(index)(a1);
+ getWasmTableEntry(index)(a1, a2, a3);
} catch (e) {
stackRestore(sp);
if (e !== e + 0) throw e;
@@ -2272,6 +3118,83 @@ var createRendererModule = (() => {
}
}
+ function invoke_ii(index, a1) {
+ var sp = stackSave();
+ try {
+ return getWasmTableEntry(index)(a1);
+ } catch (e) {
+ stackRestore(sp);
+ if (e !== e + 0) throw e;
+ _setThrew(1, 0);
+ }
+ }
+
+ function invoke_viiiii(index, a1, a2, a3, a4, a5) {
+ var sp = stackSave();
+ try {
+ getWasmTableEntry(index)(a1, a2, a3, a4, a5);
+ } catch (e) {
+ stackRestore(sp);
+ if (e !== e + 0) throw e;
+ _setThrew(1, 0);
+ }
+ }
+
+ function invoke_i(index) {
+ var sp = stackSave();
+ try {
+ return getWasmTableEntry(index)();
+ } catch (e) {
+ stackRestore(sp);
+ if (e !== e + 0) throw e;
+ _setThrew(1, 0);
+ }
+ }
+
+ function invoke_v(index) {
+ var sp = stackSave();
+ try {
+ getWasmTableEntry(index)();
+ } catch (e) {
+ stackRestore(sp);
+ if (e !== e + 0) throw e;
+ _setThrew(1, 0);
+ }
+ }
+
+ function invoke_viiiiii(index, a1, a2, a3, a4, a5, a6) {
+ var sp = stackSave();
+ try {
+ getWasmTableEntry(index)(a1, a2, a3, a4, a5, a6);
+ } catch (e) {
+ stackRestore(sp);
+ if (e !== e + 0) throw e;
+ _setThrew(1, 0);
+ }
+ }
+
+ function invoke_fi(index, a1) {
+ var sp = stackSave();
+ try {
+ return getWasmTableEntry(index)(a1);
+ } catch (e) {
+ stackRestore(sp);
+ if (e !== e + 0) throw e;
+ _setThrew(1, 0);
+ }
+ }
+
+ function invoke_iif(index, a1, a2) {
+ var sp = stackSave();
+ try {
+ return getWasmTableEntry(index)(a1, a2);
+ } catch (e) {
+ stackRestore(sp);
+ if (e !== e + 0) throw e;
+ _setThrew(1, 0);
+ }
+ }
+
function invoke_iiiiii(index, a1, a2, a3, a4, a5) {
var sp = stackSave();
try {
@@ -2283,6 +3206,50 @@ var createRendererModule = (() => {
}
}
+ function invoke_iiiii(index, a1, a2, a3, a4) {
+ var sp = stackSave();
+ try {
+ return getWasmTableEntry(index)(a1, a2, a3, a4);
+ } catch (e) {
+ stackRestore(sp);
+ if (e !== e + 0) throw e;
+ _setThrew(1, 0);
+ }
+ }
+
+ function invoke_iii(index, a1, a2) {
+ var sp = stackSave();
+ try {
+ return getWasmTableEntry(index)(a1, a2);
+ } catch (e) {
+ stackRestore(sp);
+ if (e !== e + 0) throw e;
+ _setThrew(1, 0);
+ }
+ }
+
+ function invoke_d(index) {
+ var sp = stackSave();
+ try {
+ return getWasmTableEntry(index)();
+ } catch (e) {
+ stackRestore(sp);
+ if (e !== e + 0) throw e;
+ _setThrew(1, 0);
+ }
+ }
+
+ function invoke_vid(index, a1, a2) {
+ var sp = stackSave();
+ try {
+ getWasmTableEntry(index)(a1, a2);
+ } catch (e) {
+ stackRestore(sp);
+ if (e !== e + 0) throw e;
+ _setThrew(1, 0);
+ }
+ }
+
function invoke_viiii(index, a1, a2, a3, a4) {
var sp = stackSave();
try {
@@ -2294,6 +3261,149 @@ var createRendererModule = (() => {
}
}
+ function invoke_vif(index, a1, a2) {
+ var sp = stackSave();
+ try {
+ getWasmTableEntry(index)(a1, a2);
+ } catch (e) {
+ stackRestore(sp);
+ if (e !== e + 0) throw e;
+ _setThrew(1, 0);
+ }
+ }
+
+ function invoke_iiiiiii(index, a1, a2, a3, a4, a5, a6) {
+ var sp = stackSave();
+ try {
+ return getWasmTableEntry(index)(a1, a2, a3, a4, a5, a6);
+ } catch (e) {
+ stackRestore(sp);
+ if (e !== e + 0) throw e;
+ _setThrew(1, 0);
+ }
+ }
+
+ function invoke_viif(index, a1, a2, a3) {
+ var sp = stackSave();
+ try {
+ getWasmTableEntry(index)(a1, a2, a3);
+ } catch (e) {
+ stackRestore(sp);
+ if (e !== e + 0) throw e;
+ _setThrew(1, 0);
+ }
+ }
+
+ function invoke_viiff(index, a1, a2, a3, a4) {
+ var sp = stackSave();
+ try {
+ getWasmTableEntry(index)(a1, a2, a3, a4);
+ } catch (e) {
+ stackRestore(sp);
+ if (e !== e + 0) throw e;
+ _setThrew(1, 0);
+ }
+ }
+
+ function invoke_iiiiiiii(index, a1, a2, a3, a4, a5, a6, a7) {
+ var sp = stackSave();
+ try {
+ return getWasmTableEntry(index)(a1, a2, a3, a4, a5, a6, a7);
+ } catch (e) {
+ stackRestore(sp);
+ if (e !== e + 0) throw e;
+ _setThrew(1, 0);
+ }
+ }
+
+ function invoke_ji(index, a1) {
+ var sp = stackSave();
+ try {
+ return dynCall_ji(index, a1);
+ } catch (e) {
+ stackRestore(sp);
+ if (e !== e + 0) throw e;
+ _setThrew(1, 0);
+ }
+ }
+
+ function invoke_vijiji(index, a1, a2, a3, a4, a5, a6, a7) {
+ var sp = stackSave();
+ try {
+ dynCall_vijiji(index, a1, a2, a3, a4, a5, a6, a7);
+ } catch (e) {
+ stackRestore(sp);
+ if (e !== e + 0) throw e;
+ _setThrew(1, 0);
+ }
+ }
+
+ function invoke_vij(index, a1, a2, a3) {
+ var sp = stackSave();
+ try {
+ dynCall_vij(index, a1, a2, a3);
+ } catch (e) {
+ stackRestore(sp);
+ if (e !== e + 0) throw e;
+ _setThrew(1, 0);
+ }
+ }
+
+ function invoke_jii(index, a1, a2) {
+ var sp = stackSave();
+ try {
+ return dynCall_jii(index, a1, a2);
+ } catch (e) {
+ stackRestore(sp);
+ if (e !== e + 0) throw e;
+ _setThrew(1, 0);
+ }
+ }
+
+ function invoke_viijj(index, a1, a2, a3, a4, a5, a6) {
+ var sp = stackSave();
+ try {
+ dynCall_viijj(index, a1, a2, a3, a4, a5, a6);
+ } catch (e) {
+ stackRestore(sp);
+ if (e !== e + 0) throw e;
+ _setThrew(1, 0);
+ }
+ }
+
+ function invoke_viij(index, a1, a2, a3, a4) {
+ var sp = stackSave();
+ try {
+ dynCall_viij(index, a1, a2, a3, a4);
+ } catch (e) {
+ stackRestore(sp);
+ if (e !== e + 0) throw e;
+ _setThrew(1, 0);
+ }
+ }
+
+ function invoke_viiiji(index, a1, a2, a3, a4, a5, a6) {
+ var sp = stackSave();
+ try {
+ dynCall_viiiji(index, a1, a2, a3, a4, a5, a6);
+ } catch (e) {
+ stackRestore(sp);
+ if (e !== e + 0) throw e;
+ _setThrew(1, 0);
+ }
+ }
+
+ function invoke_viiji(index, a1, a2, a3, a4, a5) {
+ var sp = stackSave();
+ try {
+ dynCall_viiji(index, a1, a2, a3, a4, a5);
+ } catch (e) {
+ stackRestore(sp);
+ if (e !== e + 0) throw e;
+ _setThrew(1, 0);
+ }
+ }
+
function invoke_viiij(index, a1, a2, a3, a4, a5) {
var sp = stackSave();
try {
@@ -2355,4 +3465,4 @@ var createRendererModule = (() => {
return moduleArg.ready;
};
})();
-export default createRendererModule;
+export default createDotLottiePlayerModule;
diff --git a/packages/web/src/core/dotlottie-player.types.ts b/packages/web/src/core/dotlottie-player.types.ts
new file mode 100644
index 00000000..cfcc0ab6
--- /dev/null
+++ b/packages/web/src/core/dotlottie-player.types.ts
@@ -0,0 +1,75 @@
+/**
+ * Copyright 2024 Design Barn Inc.
+ */
+
+export interface VectorFloat {
+ delete(): void;
+ get(_0: number): unknown;
+ // eslint-disable-next-line @typescript-eslint/naming-convention
+ push_back(_0: number): void;
+ resize(_0: number, _1: number): void;
+ set(_0: number, _1: number): boolean;
+ size(): number;
+}
+
+export interface ModeValue {
+ value: T;
+}
+export type Mode = ModeValue<1> | ModeValue<2> | ModeValue<3> | ModeValue<4>;
+
+export interface DotLottiePlayer {
+ buffer(): unknown;
+ clear(): void;
+ config(): Config;
+ currentFrame(): number;
+ delete(): void;
+ duration(): number;
+ isComplete(): boolean;
+ isLoaded(): boolean;
+ isPaused(): boolean;
+ isPlaying(): boolean;
+ isStopped(): boolean;
+ loadAnimation(_0: ArrayBuffer | Uint8Array | Uint8ClampedArray | Int8Array | string, _1: number, _2: number): boolean;
+ loadAnimationData(
+ _0: ArrayBuffer | Uint8Array | Uint8ClampedArray | Int8Array | string,
+ _1: number,
+ _2: number,
+ ): boolean;
+ loadAnimationPath(
+ _0: ArrayBuffer | Uint8Array | Uint8ClampedArray | Int8Array | string,
+ _1: number,
+ _2: number,
+ ): boolean;
+ loadDotLottieData(
+ _0: ArrayBuffer | Uint8Array | Uint8ClampedArray | Int8Array | string,
+ _1: number,
+ _2: number,
+ ): boolean;
+ loopCount(): number;
+ manifestString(): string;
+ pause(): boolean;
+ play(): boolean;
+ render(): boolean;
+ requestFrame(): number;
+ resize(_0: number, _1: number): boolean;
+ setConfig(_0: Config): void;
+ setFrame(_0: number): boolean;
+ stop(): boolean;
+ totalFrames(): number;
+}
+
+export interface Config {
+ autoplay: boolean;
+ backgroundColor: number;
+ loopAnimation: boolean;
+ mode: Mode;
+ segments: VectorFloat;
+ speed: number;
+ useFrameInterpolation: boolean;
+}
+
+export interface MainModule {
+ DotLottiePlayer: { new (_0: Config): DotLottiePlayer };
+ Mode: { Bounce: ModeValue<3>; Forward: ModeValue<1>; Reverse: ModeValue<2>; ReverseBounce: ModeValue<4> };
+ VectorFloat: { new (): VectorFloat };
+}
diff --git a/packages/web/src/core/dotlottie-player.wasm b/packages/web/src/core/dotlottie-player.wasm
new file mode 100755
index 00000000..4bd00f39
Binary files /dev/null and b/packages/web/src/core/dotlottie-player.wasm differ
diff --git a/packages/web/src/renderer-loader.ts b/packages/web/src/core/dotlottie-wasm-loader.ts
similarity index 71%
rename from packages/web/src/renderer-loader.ts
rename to packages/web/src/core/dotlottie-wasm-loader.ts
index 502f5591..a497d419 100644
--- a/packages/web/src/renderer-loader.ts
+++ b/packages/web/src/core/dotlottie-wasm-loader.ts
@@ -1,30 +1,26 @@
/**
- * Copyright 2023 Design Barn Inc.
+ * Copyright 2024 Design Barn Inc.
*/
-import pkg from '../package.json';
+import pkg from '../../package.json';
-import type { Module } from './wasm';
-import { createRendererModule } from './wasm';
+import createDotLottiePlayerModule from './dotlottie-player';
+import type { MainModule } from './dotlottie-player.types';
-/**
- * RendererLoader is a utility class for loading WebAssembly modules.
- * It provides methods to load modules with a primary URL and a backup URL.
- */
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
-export class RendererLoader {
+export class DotLottieWasmLoader {
// eslint-disable-next-line @typescript-eslint/naming-convention
- private static _ModulePromise: Promise | null = null;
+ private static _ModulePromise: Promise | null = null;
// URL for the WASM file, constructed using package information
- private static _wasmURL = `https://cdn.jsdelivr.net/npm/${pkg.name}@${pkg.version}/dist/wasm/renderer.wasm`;
+ private static _wasmURL = `https://cdn.jsdelivr.net/npm/${pkg.name}@${pkg.version}/dist/dotlottie-player.wasm`;
private constructor() {
throw new Error('RendererLoader is a static class and cannot be instantiated.');
}
- private static async _tryLoad(url: string): Promise {
- const module = await createRendererModule({ locateFile: () => url });
+ private static async _tryLoad(url: string): Promise {
+ const module = await createDotLottiePlayerModule({ locateFile: () => url });
return module;
}
@@ -34,10 +30,10 @@ export class RendererLoader {
* Throws an error if both URLs fail to load the module.
* @returns Promise - A promise that resolves to the loaded module.
*/
- private static async _loadWithBackup(): Promise {
+ private static async _loadWithBackup(): Promise {
if (!this._ModulePromise) {
- this._ModulePromise = this._tryLoad(this._wasmURL).catch(async (initialError): Promise => {
- const backupUrl = `https://unpkg.com/${pkg.name}@${pkg.version}/dist/wasm/renderer.wasm`;
+ this._ModulePromise = this._tryLoad(this._wasmURL).catch(async (initialError): Promise => {
+ const backupUrl = `https://unpkg.com/${pkg.name}@${pkg.version}/dist/dotlottie-player.wasm`;
console.warn(`Trying backup URL for WASM loading: ${backupUrl}`);
try {
@@ -61,7 +57,7 @@ export class RendererLoader {
* Utilizes a primary and backup URL for robustness.
* @returns Promise - A promise that resolves to the loaded module.
*/
- public static async load(): Promise {
+ public static async load(): Promise {
return this._loadWithBackup();
}
diff --git a/packages/web/src/core/index.ts b/packages/web/src/core/index.ts
new file mode 100644
index 00000000..6423cf4e
--- /dev/null
+++ b/packages/web/src/core/index.ts
@@ -0,0 +1,6 @@
+/**
+ * Copyright 2024 Design Barn Inc.
+ */
+
+export type * from './dotlottie-player.types';
+export * from './dotlottie-wasm-loader';
diff --git a/packages/web/src/dotlottie.ts b/packages/web/src/dotlottie.ts
index 81fe682b..29df673e 100644
--- a/packages/web/src/dotlottie.ts
+++ b/packages/web/src/dotlottie.ts
@@ -1,902 +1,478 @@
/**
- * Copyright 2023 Design Barn Inc.
+ * Copyright 2024 Design Barn Inc.
*/
-/* eslint-disable promise/prefer-await-to-then */
-/* eslint-disable @typescript-eslint/unbound-method */
-
import { AnimationFrameManager } from './animation-frame-manager';
-import { IS_BROWSER, MS_TO_SEC_FACTOR, DEFAULT_BG_COLOR } from './constants';
+import { IS_BROWSER } from './constants';
+import type { DotLottiePlayer, MainModule, Mode as CoreMode, VectorFloat } from './core';
+import { DotLottieWasmLoader } from './core';
import type { EventListener, EventType } from './event-manager';
import { EventManager } from './event-manager';
-import { RendererLoader } from './renderer-loader';
-import { getAnimationJSONFromDotLottie, loadAnimationJSONFromURL, hexStringToRGBAInt } from './utils';
-import type { Renderer } from './wasm';
-
-export type Mode = 'forward' | 'reverse' | 'bounce' | 'bounce-reverse';
-
-type PlaybackState = 'playing' | 'paused' | 'stopped';
interface RenderConfig {
- /**
- * The device pixel ratio to use when resizing the canvas.
- *
- * Default is window.devicePixelRatio or 1.
- */
devicePixelRatio?: number;
}
+export type Mode = 'forward' | 'reverse' | 'bounce' | 'reverse-bounce';
+
export interface Config {
- /**
- * Boolean indicating if the animation should start playing automatically.
- */
autoplay?: boolean;
- /**
- * Animation canvas background color.
- *
- * Default is #00000000.
- */
backgroundColor?: string;
- /**
- * The canvas element to render the animation on.
- */
canvas: HTMLCanvasElement;
- /**
- * The animation data.
- * string: The JSON string of the animation data.
- * ArrayBuffer: The ArrayBuffer of the .lottie file.
- *
- * If the data is an ArrayBuffer, the JSON string will be extracted from the .lottie file.
- */
data?: string | ArrayBuffer;
- /**
- * Boolean indicating if the animation should loop.
- */
loop?: boolean;
- /**
- * The playback mode of the animation.
- *
- * forward: The animation will play from start to end.
- * reverse: The animation will play from end to start.
- * bounce: The animation will play from start to end and then from end to start.
- * bounce-reverse: The animation will play from end to start and then from start to end.
- *
- */
mode?: Mode;
- /**
- * The render configuration.
- */
renderConfig?: RenderConfig;
- /**
- * The frame boundaries of the animation.
- *
- * The animation will only play between the given start and end frames.
- *
- * e.g. [0, 10] will play the first 10 frames of the animation only.
- *
- */
segments?: [number, number];
- /**
- * The speed of the animation.
- */
speed?: number;
- /**
- * The source URL of the animation.
- *
- * If the data is provided, the src will be ignored.
- */
src?: string;
- /**
- *
- * If true, it will update on every requestAnimationFrame with intermediate values.
- * If false, it will respect the original AE fps.
- *
- * Default is true.
- */
useFrameInterpolation?: boolean;
}
-export class DotLottie {
- private readonly _canvas: HTMLCanvasElement | OffscreenCanvas;
-
- private _context: CanvasRenderingContext2D | null;
-
- private readonly _eventManager = new EventManager();
-
- private _renderer: Renderer | null = null;
-
- private _beginTime = 0;
-
- private _elapsedTime = 0;
-
- private _totalFrames = 0;
-
- private _loop = false;
-
- private _speed = 1;
+const createCoreMode = (mode: Mode, module: MainModule): CoreMode => {
+ if (mode === 'reverse') {
+ return module.Mode.Reverse;
+ } else if (mode === 'bounce') {
+ return module.Mode.Bounce;
+ } else if (mode === 'reverse-bounce') {
+ return module.Mode.ReverseBounce;
+ } else {
+ return module.Mode.Forward;
+ }
+};
- private _currentFrame = 0;
+const createCoreSegments = (segments: number[], module: MainModule): VectorFloat => {
+ const coreSegments = new module.VectorFloat();
- private _duration = 0;
+ if (segments.length !== 2) return coreSegments;
- private _loopCount = 0;
+ coreSegments.push_back(segments[0] as number);
+ coreSegments.push_back(segments[1] as number);
- private _autoplay = false;
+ return coreSegments;
+};
- private _mode: Mode = 'forward';
+export class DotLottie {
+ private readonly _canvas: HTMLCanvasElement;
- private _direction = 1;
+ private _context: CanvasRenderingContext2D | null;
- private _bounceCount = 0;
+ private readonly _eventManager: EventManager;
- private _animationFrameId?: number | null = null;
+ private _animationFrameId: number | null = null;
- private _segments: [number, number] | null = null;
+ private readonly _frameManager: AnimationFrameManager;
- private _playbackState: PlaybackState = 'stopped';
+ private _dotLottieCore: DotLottiePlayer | null = null;
- private _backgroundColor: string = DEFAULT_BG_COLOR;
+ private _wasmModule: MainModule | null = null;
private _renderConfig: RenderConfig = {};
- private _isFrozen = false;
+ private _isFrozen: boolean = false;
- private _isLoaded = false;
-
- private readonly _animationFrameManager = new AnimationFrameManager();
-
- private _useFrameInterpolation = true;
-
- private _imageData: ImageData | null = null;
+ private _backgroundColor: string | null = null;
public constructor(config: Config) {
- this._animationLoop = this._animationLoop.bind(this);
-
this._canvas = config.canvas;
this._context = this._canvas.getContext('2d');
- this._loop = config.loop ?? false;
- this._speed = config.speed ?? 1;
- this._autoplay = config.autoplay ?? false;
- this._mode = config.mode ?? 'forward';
- this._segments = config.segments ?? null;
- this._backgroundColor = config.backgroundColor ?? DEFAULT_BG_COLOR;
+ this._eventManager = new EventManager();
+ this._frameManager = new AnimationFrameManager();
this._renderConfig = config.renderConfig ?? {};
- this._useFrameInterpolation = config.useFrameInterpolation ?? true;
- this._direction = this._mode.includes('reverse') ? -1 : 1;
- RendererLoader.load()
+ DotLottieWasmLoader.load()
.then((module) => {
- this._renderer = new module.Renderer();
+ this._wasmModule = module;
+
+ this._dotLottieCore = new module.DotLottiePlayer({
+ autoplay: config.autoplay ?? false,
+ backgroundColor: 0,
+ loopAnimation: config.loop ?? false,
+ mode: createCoreMode(config.mode ?? 'forward', module),
+ segments: createCoreSegments(config.segments ?? [], module),
+ speed: config.speed ?? 1,
+ useFrameInterpolation: config.useFrameInterpolation ?? true,
+ });
- this.setBackgroundColor(this._backgroundColor);
+ if (config.data) {
+ this._loadFromData(config.data);
+ } else if (config.src) {
+ this._loadFromSrc(config.src);
+ }
- if (config.src) {
- this._loadAnimationFromURL(config.src);
- } else if (config.data) {
- this._initializeAnimationFromData(config.data);
+ if (config.backgroundColor) {
+ this.setBackgroundColor(config.backgroundColor);
}
})
.catch((error) => {
this._eventManager.dispatch({
type: 'loadError',
- error: error as Error,
+ error: new Error(`Failed to load wasm module: ${error}`),
});
});
}
- // #region Getters and Setters
-
- public get renderConfig(): RenderConfig {
- return this._renderConfig;
- }
-
- public get canvas(): HTMLCanvasElement | OffscreenCanvas {
- return this._canvas;
- }
-
- public get mode(): Mode {
- return this._mode;
- }
-
- /**
- * Gets the autoplay status of the animation.
- *
- * @returns The autoplay status of the animation.
- */
- public get autoplay(): boolean {
- return this._autoplay;
- }
-
- /**
- * Gets the background color of the canvas.
- *
- * @returns The background color of the canvas.
- */
- public get backgroundColor(): string {
- return this._backgroundColor;
- }
-
- /**
- * Gets the current direction of the animation.
- *
- * @returns The current direction of the animation.
- */
- public get direction(): number {
- return this._direction;
- }
-
- /**
- * Gets the current frame number.
- *
- * @returns The current frame number.
- */
- public get currentFrame(): number {
- return this._currentFrame;
- }
-
- /**
- * Gets the duration of the animation in seconds.
- *
- * @returns The duration of the animation in seconds.
- */
- public get duration(): number {
- return this._duration;
- }
-
- /**
- * Gets the number of frames in the animation.
- *
- * @returns The number of frames in the animation.
- */
- public get totalFrames(): number {
- return this._totalFrames;
- }
-
- /**
- * Gets the loop status of the animation.
- *
- * @returns The loop status of the animation.
- */
- public get loop(): boolean {
- return this._loop;
- }
-
- /**
- * Gets the speed of the animation.
- *
- * @returns The speed of the animation.
- */
- public get speed(): number {
- return this._speed;
- }
-
- /**
- * Gets the loop count of the animation.
- *
- * @returns The loop count of the animation.
- */
- public get loopCount(): number {
- return this._loopCount;
- }
-
- /**
- * Gets the segments of the animation if any are set.
- * Default is 0 to total frames. but if segments are set, it will be the start and end frames.
- *
- */
- public get segments(): [number, number] | null {
- return this._segments;
- }
+ private _loadFromSrc(src: string): void {
+ async function load(): Promise {
+ const response = await fetch(src);
- public get isPlaying(): boolean {
- return this._playbackState === 'playing';
- }
+ if (!response.ok) {
+ throw new Error(
+ `Failed to fetch the animation data from URL: ${src}. ${response.status}: ${response.statusText}`,
+ );
+ }
- public get isPaused(): boolean {
- return this._playbackState === 'paused';
- }
+ const contentType = response.headers.get('content-type');
- public get isStopped(): boolean {
- return this._playbackState === 'stopped';
- }
+ let data: string | ArrayBuffer;
- public get isLoaded(): boolean {
- return this._isLoaded;
- }
+ if (contentType?.includes('application/json')) {
+ data = await response.text();
+ } else {
+ data = await response.arrayBuffer();
+ }
- public get isFrozen(): boolean {
- return this._isFrozen;
- }
+ return data;
+ }
- public get useFrameInterpolation(): boolean {
- return this._useFrameInterpolation;
- }
-
- // #endregion Getters and Setters
-
- // #region Private Methods
- /**
- * Loads and initializes the animation from a given URL.
- *
- * @public
- * @param animationURL - The source URL of the animation.
- */
- private _loadAnimationFromURL(animationURL: string): void {
- loadAnimationJSONFromURL(animationURL)
- .then((animationJSON) => {
- this._initializeAnimationFromData(animationJSON);
+ load()
+ .then((data) => {
+ this._loadFromData(data);
})
.catch((error) => {
this._eventManager.dispatch({
type: 'loadError',
- error: error as Error,
+ error: new Error(`Failed to load animation data from URL: ${src}. ${error}`),
});
});
}
- /**
- * Initializes the animation from the given data.
- *
- * @public
- * @param data - The animation data.
- */
- private _initializeAnimationFromData(data: string | ArrayBuffer): void {
- const loadAnimation = (animationData: string): void => {
- try {
- if (this._renderer?.load(animationData, this._canvas.width, this._canvas.height)) {
- this._setupAnimationDetails();
- this._isLoaded = true;
- this._eventManager.dispatch({ type: 'load' });
-
- if (IS_BROWSER) {
- this.resize();
- }
+ private _loadFromData(data: string | ArrayBuffer): void {
+ if (this._dotLottieCore === null) return;
- // render the first frame of the animation
- this._currentFrame = this._mode.includes('reverse')
- ? this._getEffectiveEndFrame()
- : this._getEffectiveStartFrame();
+ try {
+ const width = this._canvas.width;
+ const height = this._canvas.height;
- this._eventManager.dispatch({
- type: 'frame',
- currentFrame: this._currentFrame,
- });
- this._renderer.frame(this._currentFrame);
- this._render();
+ let loaded = false;
- if (this._autoplay) {
- this.play();
- }
- } else {
- this._eventManager.dispatch({
- type: 'loadError',
- error: new Error('Error encountered while initializing animation from data.'),
- });
- }
- } catch (error) {
+ // clear the buffer
+ this._dotLottieCore.clear();
+
+ if (typeof data === 'string') {
+ loaded = this._dotLottieCore.loadAnimationData(data, width, height);
+ } else if (data instanceof ArrayBuffer) {
+ loaded = this._dotLottieCore.loadDotLottieData(data, width, height);
+ } else {
this._eventManager.dispatch({
type: 'loadError',
- error: error as Error,
- });
- }
- };
-
- if (typeof data === 'string') {
- loadAnimation(data);
- } else if (data instanceof ArrayBuffer) {
- getAnimationJSONFromDotLottie(data)
- .then(loadAnimation)
- .catch((error) => {
- this._eventManager.dispatch({
- type: 'loadError',
- error: error as Error,
- });
+ error: new Error('Unsupported data type for animation data. Expected a string or ArrayBuffer.'),
});
- } else {
- console.error('Unsupported data type for animation data. Expected a string or ArrayBuffer.');
- }
- }
-
- /**
- * Sets up animation details like total frames and duration.
- */
- private _setupAnimationDetails(): void {
- if (this._renderer) {
- this._totalFrames = this._renderer.totalFrames();
- this._duration = this._renderer.duration();
- this._segments = [
- Math.max(0, this._segments?.[0] ?? 0),
- Math.min(this._totalFrames - 1, this.segments?.[1] ?? this._totalFrames - 1),
- ];
- }
- }
-
- /**
- * Renders the animation frame on the canvas.
- */
- private _render(): void {
- if (!this._context || !this._renderer) {
- return;
- }
-
- const width = this._canvas.width;
- const height = this._canvas.height;
- if (width <= 0 || height <= 0) return;
-
- this._renderer.resize(width, height);
-
- if (this._renderer.update()) {
- const buffer = this._renderer.render();
-
- if (this._imageData?.data.length !== buffer.length) {
- this._imageData = this._context.createImageData(width, height);
+ return;
}
- this._imageData.data.set(buffer);
-
- this._context.putImageData(this._imageData, 0, 0);
- }
- }
-
- /**
- * Updates the current frame and animation state.
- * @returns Boolean indicating if the frame was updated.
- */
- private _update(): boolean {
- // animation is not loaded yet
- if (!this._isLoaded || this._duration === 0 || this._totalFrames === 0) return false;
-
- const effectiveStartFrame = this._getEffectiveStartFrame();
- const effectiveEndFrame = this._getEffectiveEndFrame();
- const effectiveDuration = this._getEffectiveDuration();
- const frameDuration = effectiveDuration / (effectiveEndFrame - effectiveStartFrame);
-
- this._elapsedTime = (Date.now() / MS_TO_SEC_FACTOR - this._beginTime) * this._speed;
- const frameProgress = this._elapsedTime / frameDuration;
-
- let currentRawFrame = 0;
-
- if (this._mode === 'forward') {
- currentRawFrame = effectiveStartFrame + frameProgress;
- } else if (this._mode === 'reverse') {
- currentRawFrame = effectiveEndFrame - frameProgress;
- } else {
- // handle bounce or bounce-reverse mode
- const isForward = this._direction === 1;
-
- currentRawFrame = isForward ? effectiveStartFrame + frameProgress : effectiveEndFrame - frameProgress;
- }
-
- if (!this._useFrameInterpolation) {
- currentRawFrame = Math.round(currentRawFrame);
- }
-
- // update current frame only if it's different
- if (this._currentFrame !== currentRawFrame) {
- this._currentFrame = currentRawFrame;
- // ensure the current frame is within the effective range
- this._currentFrame = Math.max(effectiveStartFrame, Math.min(this._currentFrame, effectiveEndFrame));
+ if (loaded) {
+ this._eventManager.dispatch({ type: 'load' });
- let shouldUpdate = false;
+ if (IS_BROWSER) {
+ this.resize();
+ }
- if (this._renderer?.frame(this._currentFrame)) {
this._eventManager.dispatch({
type: 'frame',
- currentFrame: this._currentFrame,
+ currentFrame: this._dotLottieCore.currentFrame(),
});
- shouldUpdate = true;
- }
+ this._render();
- // check if the animation should loop or complete
- if (
- (this._mode === 'forward' && this._currentFrame >= effectiveEndFrame) ||
- (this._mode === 'reverse' && this._currentFrame <= effectiveStartFrame)
- ) {
- this._handleLoopOrCompletion();
- } else if (
- this._mode.includes('bounce') &&
- (this._currentFrame <= effectiveStartFrame || this._currentFrame >= effectiveEndFrame)
- ) {
- // change the direction if the animation reaches the start or end frame
- this._direction *= -1;
-
- // increment the bounce cycle count, 2 cycles means 1 loop
- this._bounceCount += 1;
-
- if (this._bounceCount % 2 === 0) {
- this._bounceCount = 0;
- this._handleLoopOrCompletion();
- } else {
- this._beginTime = Date.now() / MS_TO_SEC_FACTOR;
+ if (this._dotLottieCore.config().autoplay) {
+ this._dotLottieCore.play();
+ if (this._dotLottieCore.isPlaying()) {
+ this._eventManager.dispatch({ type: 'play' });
+ this._animationFrameId = this._frameManager.requestAnimationFrame(this._draw.bind(this));
+ } else {
+ console.error('something went wrong, the animation was suppose to autoplay');
+ }
}
+ } else {
+ this._eventManager.dispatch({
+ type: 'loadError',
+ error: new Error('Failed to load animation data'),
+ });
}
-
- return shouldUpdate;
+ } catch (error) {
+ this._eventManager.dispatch({
+ type: 'loadError',
+ error: error as Error,
+ });
}
-
- return false;
}
- /**
- * Handles the loop or completion logic for the animation.
- */
- private _handleLoopOrCompletion(): void {
- if (this._loop) {
- this._loopCount += 1;
- this._eventManager.dispatch({ type: 'loop', loopCount: this._loopCount });
- this._beginTime = Date.now() / MS_TO_SEC_FACTOR;
- } else {
- this._playbackState = 'stopped';
- this._eventManager.dispatch({ type: 'complete' });
- this._stopAnimationLoop();
- }
+ public get renderConfig(): RenderConfig {
+ return this._renderConfig;
}
- /**
- * Loop that handles the animation playback.
- */
- private _animationLoop(): void {
- const updated = this._update();
+ public get segments(): [number, number] | undefined {
+ const segments = this._dotLottieCore?.config().segments;
- if (updated) {
- this._render();
+ if (segments && segments.size() === 2) {
+ return [segments.get(0) as number, segments.get(1) as number];
}
- // check if the animation is still playing before requesting the next frame
- if (this.isPlaying) {
- this._animationFrameId = this._animationFrameManager.requestAnimationFrame(this._animationLoop);
- }
+ return undefined;
}
- /**
- * Stops the animation loop.
- *
- * This is used to ensure that the animation loop is only stopped once.
- */
- private _stopAnimationLoop(): void {
- if (this._animationFrameId) {
- this._animationFrameManager.cancelAnimationFrame(this._animationFrameId);
- this._animationFrameId = null;
- }
+ public get loop(): boolean {
+ return this._dotLottieCore?.config().loopAnimation ?? false;
}
- /**
- * Starts the animation loop.
- *
- * This is used to ensure that the animation loop is only started once.
- */
- private _startAnimationLoop(): void {
- if (!this._animationFrameId) {
- this._animationFrameId = this._animationFrameManager.requestAnimationFrame(this._animationLoop);
+ public get mode(): Mode {
+ const mode = this._dotLottieCore?.config().mode;
+
+ if (mode === this._wasmModule?.Mode.Reverse) {
+ return 'reverse';
+ } else if (mode === this._wasmModule?.Mode.Bounce) {
+ return 'bounce';
+ } else if (mode === this._wasmModule?.Mode.ReverseBounce) {
+ return 'reverse-bounce';
+ } else {
+ return 'forward';
}
}
- private _getEffectiveStartFrame(): number {
- return this._segments ? this._segments[0] : 0;
+ public get isFrozen(): boolean {
+ return this._isFrozen;
}
- private _getEffectiveEndFrame(): number {
- return this._segments ? this._segments[1] : this._totalFrames - 1;
+ public get backgroundColor(): string {
+ return this._backgroundColor ?? '';
}
- private _getEffectiveTotalFrames(): number {
- return this._segments ? this._segments[1] - this._segments[0] : this._totalFrames;
+ public get autoplay(): boolean {
+ return this._dotLottieCore?.config().autoplay ?? false;
}
- private _getEffectiveDuration(): number {
- return this._segments
- ? this._duration * ((this._segments[1] - this._segments[0]) / this._totalFrames)
- : this._duration;
+ public get useFrameInterpolation(): boolean {
+ return this._dotLottieCore?.config().useFrameInterpolation ?? false;
}
- /**
- * Synchronizes the animation timing based on the current frame, direction, and speed settings.
- * This method calculates the appropriate begin time for the animation loop, ensuring that the
- * animation's playback is consistent with the specified parameters.
- *
- * @param frame - The current frame number from which the animation timing will be synchronized.
- * This frame number is used to calculate the correct position in the animation timeline.
- *
- * Usage:
- * - This function should be called whenever there is a change in the frame, speed, or direction
- * of the animation to maintain the correct timing.
- * - It is used internally in methods like `play`, `setFrame`, and `setMode` to ensure that the
- * animation's playback remains smooth and accurate.
- */
- private _synchronizeAnimationTiming(frame: number): void {
- const effectiveDuration = this._getEffectiveDuration();
- const effectiveTotalFrames = this._getEffectiveTotalFrames();
- const frameDuration = effectiveDuration / effectiveTotalFrames;
- let frameTime = (frame - this._getEffectiveStartFrame()) * frameDuration;
-
- if (this._direction === -1) {
- frameTime = effectiveDuration - frameTime;
- }
-
- this._beginTime = Date.now() / MS_TO_SEC_FACTOR - frameTime / this._speed;
+ public get speed(): number {
+ return this._dotLottieCore?.config().speed ?? 0;
}
- // #endregion
-
- // #region Public Methods
-
- /**
- * Starts the animation playback.
- */
- public play(): void {
- if (!this._isLoaded || this.isPlaying) return;
-
- const effectiveStartFrame = this._getEffectiveStartFrame();
- const effectiveEndFrame = this._getEffectiveEndFrame();
+ public get isLoaded(): boolean {
+ return this._dotLottieCore?.isLoaded() ?? false;
+ }
- // reset begin time and loop count if starting from the beginning
- // eslint-disable-next-line no-negated-condition
- if (this._playbackState !== 'paused') {
- this._currentFrame =
- this._mode === 'reverse' || this._mode === 'bounce-reverse' ? effectiveEndFrame : effectiveStartFrame;
- this._beginTime = Date.now() / MS_TO_SEC_FACTOR;
- } else {
- this._synchronizeAnimationTiming(this._currentFrame);
- }
+ public get isPlaying(): boolean {
+ return this._dotLottieCore?.isPlaying() ?? false;
+ }
- this._playbackState = 'playing';
+ public get isPaused(): boolean {
+ return this._dotLottieCore?.isPaused() ?? false;
+ }
- // auto unfreeze if the animation on play
- if (this._isFrozen) {
- this._isFrozen = false;
+ public get isStopped(): boolean {
+ return this._dotLottieCore?.isStopped() ?? false;
+ }
- this._eventManager.dispatch({ type: 'unfreeze' });
- }
+ public get currentFrame(): number {
+ return this._dotLottieCore?.currentFrame() ?? 0;
+ }
- this._eventManager.dispatch({
- type: 'play',
- });
+ public get loopCount(): number {
+ return this._dotLottieCore?.loopCount() ?? 0;
+ }
- this._animationFrameId = this._animationFrameManager.requestAnimationFrame(this._animationLoop);
+ public get totalFrames(): number {
+ return this._dotLottieCore?.totalFrames() ?? 0;
}
- /**
- * Stops the animation playback and resets the current frame.
- */
- public stop(): void {
- if (!this._isLoaded || this.isStopped) return;
+ public get duration(): number {
+ return this._dotLottieCore?.duration() ?? 0;
+ }
- this._stopAnimationLoop();
- this._playbackState = 'stopped';
- this._bounceCount = 0;
+ public load(config: Omit): void {
+ if (this._dotLottieCore === null || this._wasmModule === null) return;
+
+ this._dotLottieCore.setConfig({
+ autoplay: config.autoplay ?? false,
+ backgroundColor: 0,
+ loopAnimation: config.loop ?? false,
+ mode: createCoreMode(config.mode ?? 'forward', this._wasmModule),
+ segments: createCoreSegments(config.segments ?? [], this._wasmModule),
+ speed: config.speed ?? 1,
+ useFrameInterpolation: config.useFrameInterpolation ?? true,
+ });
- if (this._mode === 'reverse' || this._mode === 'bounce-reverse') {
- this._currentFrame = this._getEffectiveEndFrame();
- this._direction = -1;
- } else {
- this._currentFrame = this._getEffectiveStartFrame();
- this._direction = 1;
+ if (config.data) {
+ this._loadFromData(config.data);
+ } else if (config.src) {
+ this._loadFromSrc(config.src);
}
- this.setFrame(this._currentFrame);
- this._render();
-
- this._eventManager.dispatch({
- type: 'stop',
- });
+ this.setBackgroundColor(config.backgroundColor ?? '');
}
- /**
- * Pauses the animation playback.
- */
- public pause(): void {
- if (!this._isLoaded || !this.isPlaying) return;
+ private _render(): boolean {
+ if (this._dotLottieCore === null || this._context === null) return false;
- this._stopAnimationLoop();
+ const rendered = this._dotLottieCore.render();
- this._playbackState = 'paused';
+ if (rendered) {
+ const buffer = this._dotLottieCore.buffer() as Uint8ClampedArray;
- this._eventManager.dispatch({
- type: 'pause',
- });
- }
+ const imageData = this._context.createImageData(this._canvas.width, this._canvas.height);
- /**
- * Sets the speed for animation playback.
- * @param speed - Speed multiplier for playback.
- */
- public setSpeed(speed: number): void {
- if (!this._isLoaded || speed <= 0 || speed >= Number.MAX_SAFE_INTEGER) return;
+ imageData.data.set(buffer);
- if (this._speed === speed) return;
+ this._context.putImageData(imageData, 0, 0);
- if (this.isPlaying) {
- // recalculate the begin time based on the new speed to maintain the current position
- const currentTime = Date.now() / MS_TO_SEC_FACTOR;
+ this._eventManager.dispatch({
+ type: 'render',
+ currentFrame: this._dotLottieCore.currentFrame(),
+ });
- this._beginTime = currentTime - this._elapsedTime / speed;
+ return true;
}
- this._speed = speed;
+ return false;
}
- /**
- * Sets the loop state for animation playback.
- * @param loop - Boolean indicating if the animation should loop.
- */
- public setLoop(loop: boolean): void {
- if (!this._isLoaded) return;
+ private _draw(): void {
+ if (this._dotLottieCore === null || this._context === null || !this._dotLottieCore.isPlaying()) return;
- this._loop = loop;
- }
-
- /**
- * Sets the current frame of the animation.
- * @param frame - Frame number to set.
- */
- public setFrame(frame: number): void {
- if (!this._isLoaded) return;
+ const nextFrame = this._dotLottieCore.requestFrame();
- const effectiveStartFrame = this._getEffectiveStartFrame();
- const effectiveEndFrame = this._getEffectiveEndFrame();
+ const updated = this._dotLottieCore.setFrame(nextFrame);
- // validate the frame number within the effective frame range
- if (frame < effectiveStartFrame || frame > effectiveEndFrame) {
- console.error(
- `Invalid frame number: ${frame}. It should be between ${effectiveStartFrame} and ${effectiveEndFrame}.`,
- );
+ if (updated) {
+ this._eventManager.dispatch({
+ type: 'frame',
+ currentFrame: this._dotLottieCore.currentFrame(),
+ });
- return;
+ const rendered = this._render();
+
+ if (rendered) {
+ // handle loop or complete
+ if (this._dotLottieCore.isComplete()) {
+ if (this._dotLottieCore.config().loopAnimation) {
+ this._eventManager.dispatch({
+ type: 'loop',
+ loopCount: this._dotLottieCore.loopCount(),
+ });
+ } else {
+ this._eventManager.dispatch({ type: 'complete' });
+ }
+ }
+ }
}
- this._currentFrame = frame;
+ this._animationFrameId = this._frameManager.requestAnimationFrame(this._draw.bind(this));
+ }
- if (this.isPlaying) {
- this._synchronizeAnimationTiming(frame);
- }
+ public play(): void {
+ if (this._dotLottieCore === null) return;
- if (this._renderer?.frame(this._currentFrame)) {
- this._eventManager.dispatch({
- type: 'frame',
- currentFrame: this._currentFrame,
- });
- this._render();
+ const ok = this._dotLottieCore.play();
+
+ this._isFrozen = false;
+
+ if (ok) {
+ this._eventManager.dispatch({ type: 'play' });
+ this._animationFrameId = this._frameManager.requestAnimationFrame(this._draw.bind(this));
}
}
- /**
- *
- * Sets the playback mode of the animation.
- *
- */
- public setMode(mode: Mode): void {
- if (!this._isLoaded || this._mode === mode) {
- return;
- }
+ public pause(): void {
+ if (this._dotLottieCore === null) return;
- this._mode = mode;
- this._bounceCount = 0;
- this._direction = mode.includes('reverse') ? -1 : 1;
+ const ok = this._dotLottieCore.pause();
- if (this.isPlaying) {
- this._synchronizeAnimationTiming(this._currentFrame);
+ if (ok) {
+ this._eventManager.dispatch({ type: 'pause' });
}
}
- public load(config: Omit): void {
- if (!this._renderer || !this._context) {
- return;
- }
+ public stop(): void {
+ if (this._dotLottieCore === null) return;
- if (!config.src && !config.data) {
- console.error('Either "src" or "data" must be provided.');
+ const ok = this._dotLottieCore.stop();
- return;
- }
+ if (ok) {
+ this._eventManager.dispatch({ type: 'frame', currentFrame: this._dotLottieCore.currentFrame() });
- this._stopAnimationLoop();
- this._playbackState = 'stopped';
- this._isLoaded = false;
-
- this._loop = config.loop ?? false;
- this._speed = config.speed ?? 1;
- this._autoplay = config.autoplay ?? false;
- this._mode = config.mode ?? 'forward';
- this._segments = config.segments ?? null;
- this._loopCount = 0;
- this._bounceCount = 0;
- this._direction = this._mode.includes('reverse') ? -1 : 1;
- this._renderConfig = config.renderConfig ?? {};
- this._useFrameInterpolation = config.useFrameInterpolation ?? true;
+ this._render();
- const effectiveStartFrame = this._getEffectiveStartFrame();
- const effectiveEndFrame = this._getEffectiveEndFrame();
+ this._eventManager.dispatch({ type: 'stop' });
+ }
+ }
- this._currentFrame =
- this._mode === 'reverse' || this._mode === 'bounce-reverse' ? effectiveEndFrame : effectiveStartFrame;
+ public setFrame(frame: number): void {
+ if (this._dotLottieCore === null) return;
- this._beginTime = 0;
- this._totalFrames = 0;
- this._duration = 0;
- this._backgroundColor = config.backgroundColor ?? DEFAULT_BG_COLOR;
+ if (frame < 0 || frame > this._dotLottieCore.totalFrames()) return;
- this.setBackgroundColor(this._backgroundColor);
+ const ok = this._dotLottieCore.setFrame(frame);
- this._context.clearRect(0, 0, this._canvas.width, this._canvas.height);
+ if (ok) {
+ this._eventManager.dispatch({ type: 'frame', currentFrame: this._dotLottieCore.currentFrame() });
- if (config.src) {
- this._loadAnimationFromURL(config.src);
- } else if (config.data) {
- this._initializeAnimationFromData(config.data);
+ this._render();
}
}
- public setSegments(startFrame: number, endFrame: number): void {
- if (!this._isLoaded) return;
+ public setSpeed(speed: number): void {
+ if (this._dotLottieCore === null) return;
+
+ this._dotLottieCore.setConfig({
+ ...this._dotLottieCore.config(),
+ speed,
+ });
+ }
- // Validate the frame range
- if (startFrame < 0 || endFrame >= this._totalFrames || startFrame > endFrame) {
- console.error('Invalid frame range.');
+ public setBackgroundColor(color: string): void {
+ if (this._dotLottieCore === null) return;
- return;
+ if (this._canvas instanceof HTMLCanvasElement) {
+ this._canvas.style.backgroundColor = color;
}
- this._segments = [startFrame, endFrame];
+ this._backgroundColor = color;
+ }
+
+ public setLoop(loop: boolean): void {
+ if (this._dotLottieCore === null) return;
- if (this._currentFrame < startFrame || this._currentFrame > endFrame) {
- this._currentFrame = this._direction === 1 ? startFrame : endFrame;
+ this._dotLottieCore.setConfig({
+ ...this._dotLottieCore.config(),
+ loopAnimation: loop,
+ });
+ }
- // render the current frame
- if (this._renderer?.frame(this._currentFrame)) {
- this._render();
- this._eventManager.dispatch({
- type: 'frame',
- currentFrame: this._currentFrame,
- });
- }
- }
+ public setUseFrameInterpolation(useFrameInterpolation: boolean): void {
+ if (this._dotLottieCore === null) return;
- // If playing, adjust the animation timing
- if (this.isPlaying) {
- this._synchronizeAnimationTiming(this._currentFrame);
- }
+ this._dotLottieCore.setConfig({
+ ...this._dotLottieCore.config(),
+ useFrameInterpolation,
+ });
}
- /**
- * Registers an event listener for a specific event type.
- *
- * @param type - The type of the event to listen for.
- * @param listener - The callback function to be called when the event is dispatched.
- */
public addEventListener(type: T, listener: EventListener): void {
this._eventManager.addEventListener(type, listener);
}
- /**
- * Removes an event listener for a specific event type.
- *
- * @param type - The type of the event to listen for.
- * @param listener - The callback function to be called when the event is dispatched.
- */
public removeEventListener(type: T, listener?: EventListener): void {
this._eventManager.removeEventListener(type, listener);
}
- /**
- * Sets the source URL of the WASM file to load.
- * @param url - The URL of the WASM file to load.
- */
- public static setWasmUrl(url: string): void {
- RendererLoader.setWasmUrl(url);
- }
-
- /**
- * Destroys the DotLottie instance.
- *
- */
public destroy(): void {
- this._stopAnimationLoop();
- this._playbackState = 'stopped';
-
+ this._dotLottieCore?.delete();
+ this._dotLottieCore = null;
this._context = null;
- this._renderer = null;
this._eventManager.dispatch({
type: 'destroy',
@@ -905,98 +481,67 @@ export class DotLottie {
this._eventManager.removeAllEventListeners();
}
- /**
- * Freezes the animation by stopping the animation loop.
- *
- */
public freeze(): void {
- if (this._isFrozen) return;
+ if (this._animationFrameId === null) return;
- this._stopAnimationLoop();
+ this._frameManager.cancelAnimationFrame(this._animationFrameId);
+ this._animationFrameId = null;
this._isFrozen = true;
- this._eventManager.dispatch({
- type: 'freeze',
- });
+ this._eventManager.dispatch({ type: 'freeze' });
}
- /**
- * Unfreezes the animation by resuming the animation loop.
- *
- */
public unfreeze(): void {
- if (!this.isFrozen) return;
+ if (this._animationFrameId !== null) return;
- this._isFrozen = false;
- this._eventManager.dispatch({ type: 'unfreeze' });
+ this._animationFrameId = this._frameManager.requestAnimationFrame(this._draw.bind(this));
- // resume the animation loop only if the playback state is 'playing'
- if (this.isPlaying) {
- this._synchronizeAnimationTiming(this._currentFrame);
- this._startAnimationLoop();
- }
- }
-
- /**
- * Sets the background color of the canvas.
- *
- * @param color - The background color of the canvas.
- */
- public setBackgroundColor(color: string): void {
- this._backgroundColor = color;
-
- const rgbaInt = hexStringToRGBAInt(color);
+ this._isFrozen = false;
- if (IS_BROWSER && this._canvas instanceof HTMLCanvasElement) {
- this._canvas.style.backgroundColor = color;
- } else {
- this._renderer?.setBgColor(rgbaInt);
- }
+ this._eventManager.dispatch({ type: 'unfreeze' });
}
- /**
- * Adjusts the canvas size to match the size of its bounding box, considering the device's pixel ratio.
- * This method ensures that the canvas is correctly scaled for high-density displays, maintaining
- * the clarity and quality of the rendered animation.
- *
- * Call this method whenever the size of the canvas element changes (e.g., due to window resizing,
- * orientation changes, or dynamic layout updates) to ensure that the canvas is always properly scaled.
- *
- */
public resize(): void {
- if (!IS_BROWSER) {
- console.warn(
- `
- Resize operation failed: The canvas cannot be resized in a Node.js or Web Worker environment.
- In these environments, you must manually set the canvas size.
- `,
- );
-
- return;
- }
+ if (!IS_BROWSER) return;
- if (!(this._canvas instanceof HTMLCanvasElement)) {
- return;
- }
+ const dpr = this._renderConfig.devicePixelRatio || window.devicePixelRatio || 1;
const { height: clientHeight, width: clientWidth } = this._canvas.getBoundingClientRect();
- const dpr = this._renderConfig.devicePixelRatio || window.devicePixelRatio || 1;
this._canvas.width = clientWidth * dpr;
this._canvas.height = clientHeight * dpr;
- // resize the renderer and render the current frame
- this._render();
+ const ok = this._dotLottieCore?.resize(this._canvas.width, this._canvas.height);
+
+ if (ok) {
+ this._render();
+ }
}
- public setUseFrameInterpolation(useFrameInterpolation: boolean): void {
- this._useFrameInterpolation = useFrameInterpolation;
+ public setSegments(startFrame: number, endFrame: number): void {
+ if (this._dotLottieCore === null || this._wasmModule === null) return;
+
+ this._dotLottieCore.setConfig({
+ ...this._dotLottieCore.config(),
+ segments: createCoreSegments([startFrame, endFrame], this._wasmModule),
+ });
+ }
+
+ public setMode(mode: Mode): void {
+ if (this._dotLottieCore === null || this._wasmModule === null) return;
+
+ this._dotLottieCore.setConfig({
+ ...this._dotLottieCore.config(),
+ mode: createCoreMode(mode, this._wasmModule),
+ });
}
public setRenderConfig(config: RenderConfig): void {
this._renderConfig = config;
}
- // #endregion
+ public static setWasmUrl(url: string): void {
+ DotLottieWasmLoader.setWasmUrl(url);
+ }
}
diff --git a/packages/web/src/event-manager.ts b/packages/web/src/event-manager.ts
index 69517b26..3260aefa 100644
--- a/packages/web/src/event-manager.ts
+++ b/packages/web/src/event-manager.ts
@@ -16,7 +16,8 @@ export type EventType =
| 'stop'
| 'destroy'
| 'freeze'
- | 'unfreeze';
+ | 'unfreeze'
+ | 'render';
/**
* Maps an event type string to its respective event interface.
@@ -43,6 +44,8 @@ type EventByType = T extends 'complete'
? FreezeEvent
: T extends 'unfreeze'
? UnfreezeEvent
+ : T extends 'render'
+ ? RenderEvent
: never;
/**
@@ -52,6 +55,11 @@ export interface BaseEvent {
type: EventType;
}
+export interface RenderEvent extends BaseEvent {
+ currentFrame: number;
+ type: 'render';
+}
+
export interface FreezeEvent extends BaseEvent {
type: 'freeze';
}
diff --git a/packages/web/src/index.ts b/packages/web/src/index.ts
index 156a3730..f8578936 100644
--- a/packages/web/src/index.ts
+++ b/packages/web/src/index.ts
@@ -3,6 +3,4 @@
*/
export * from './dotlottie';
-export * from './event-manager';
-export * from './utils';
-export * from './renderer-loader';
+export type * from './event-manager';
diff --git a/packages/web/src/utils.ts b/packages/web/src/utils.ts
index a4aafd78..5a9fac97 100644
--- a/packages/web/src/utils.ts
+++ b/packages/web/src/utils.ts
@@ -2,48 +2,6 @@
* Copyright 2023 Design Barn Inc.
*/
-import { getAnimation, getManifest, loadFromArrayBuffer } from '@dotlottie/dotlottie-js';
-
-export async function getAnimationJSONFromDotLottie(dotLottieBuffer: ArrayBuffer): Promise {
- const loadedDotLottieFile = await loadFromArrayBuffer(dotLottieBuffer);
- const manifest = await getManifest(loadedDotLottieFile);
- const activeAnimationId = manifest?.activeAnimationId || manifest?.animations[0]?.id || '';
-
- if (!activeAnimationId) {
- throw new Error('Unable to determine the active animation ID from the .lottie manifest.');
- }
- const animationData = await getAnimation(loadedDotLottieFile, activeAnimationId, { inlineAssets: true });
-
- return JSON.stringify(animationData);
-}
-
-export async function loadAnimationJSONFromURL(animationURL: string): Promise {
- try {
- const response = await fetch(animationURL);
-
- if (!response.ok) {
- throw new Error(
- `Failed to fetch the animation data from URL: ${animationURL}. ${response.status}: ${response.statusText}`,
- );
- }
-
- const contentType = response.headers.get('content-type');
- let animationJSON: string;
-
- if (contentType?.includes('application/json')) {
- animationJSON = await response.text();
- } else {
- const arrayBuffer = await response.arrayBuffer();
-
- animationJSON = await getAnimationJSONFromDotLottie(arrayBuffer);
- }
-
- return animationJSON;
- } catch (error) {
- throw new Error(`Failed to load animation data from URL: ${animationURL}. ${error}`);
- }
-}
-
export function isHexColor(color: string): boolean {
return /^#([\da-f]{6}|[\da-f]{8})$/iu.test(color);
}
diff --git a/packages/web/src/wasm/index.ts b/packages/web/src/wasm/index.ts
deleted file mode 100644
index cf0f99ac..00000000
--- a/packages/web/src/wasm/index.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-/**
- * Copyright 2023 Design Barn Inc.
- */
-
-export { default as createRendererModule } from './renderer';
-
-// Interface describing the Renderer class
-export interface Renderer {
- duration(): number;
- error(): string;
- frame(no: number): boolean;
- load(data: string, width: number, height: number): boolean;
- render(): Uint8ClampedArray;
- resize(width: number, height: number): void;
- setBgColor(color: number): void;
- size(): Float32Array;
- totalFrames(): number;
- update(): boolean;
-}
-
-// Interface representing the module structure with Renderer class
-export interface Module {
- Renderer: new () => Renderer;
-}
diff --git a/packages/web/src/wasm/renderer.wasm b/packages/web/src/wasm/renderer.wasm
deleted file mode 100755
index 708ab60d..00000000
Binary files a/packages/web/src/wasm/renderer.wasm and /dev/null differ
diff --git a/packages/web/tests/dotlottie.test.ts b/packages/web/tests/dotlottie.test.ts
index dad39858..48726983 100644
--- a/packages/web/tests/dotlottie.test.ts
+++ b/packages/web/tests/dotlottie.test.ts
@@ -26,7 +26,7 @@ afterEach(() => {
});
describe('play', () => {
- test.skip('unfreeze the animation on play()', async () => {
+ test('unfreeze the animation on play()', async () => {
const onLoad = vi.fn();
const onPlay = vi.fn();
@@ -112,7 +112,7 @@ describe('play', () => {
mode: 'reverse',
},
{
- mode: 'bounce-reverse',
+ mode: 'reverse-bounce',
},
{
mode: 'bounce',
@@ -123,7 +123,7 @@ describe('play', () => {
speed: 2,
},
{
- mode: 'bounce-reverse',
+ mode: 'reverse-bounce',
segments: [5, 25],
speed: 2,
},
@@ -165,8 +165,7 @@ describe('play', () => {
expect(onLoad).toHaveBeenCalledTimes(1);
});
- const expectedDirection = config.mode === 'reverse' || config.mode === 'bounce-reverse' ? -1 : 1;
- const totalFrames = (config.segments?.[1] ?? dotLottie.totalFrames - 1) - (config.segments?.[0] ?? 0);
+ const totalFrames = (config.segments?.[1] ?? dotLottie.totalFrames) - (config.segments?.[0] ?? 0);
const expectedDuration =
((config.mode?.includes('bounce') ? 2 : 1) *
@@ -175,27 +174,26 @@ describe('play', () => {
dotLottie.speed;
const expectedEndFrame =
- config.mode === 'reverse' || config.mode === 'bounce-reverse'
+ config.mode === 'reverse' || config.mode === 'reverse-bounce'
? config.segments?.[0] ?? 0
- : config.segments?.[1] ?? dotLottie.totalFrames - 1;
+ : config.segments?.[1] ?? dotLottie.totalFrames;
const expectedStartFrame =
- config.mode === 'reverse' || config.mode === 'bounce-reverse'
- ? config.segments?.[1] ?? dotLottie.totalFrames - 1
+ config.mode === 'reverse' || config.mode === 'reverse-bounce'
+ ? config.segments?.[1] ?? dotLottie.totalFrames
: config.segments?.[0] ?? 0;
const startFrame =
- config.mode === 'reverse' || config.mode === 'bounce-reverse'
- ? dotLottie.segments?.[1]
- : dotLottie.segments?.[0];
+ config.mode === 'reverse' || config.mode === 'reverse-bounce'
+ ? dotLottie.segments?.[1] ?? dotLottie.totalFrames
+ : dotLottie.segments?.[0] ?? 0;
const endFrame =
- config.mode === 'reverse' || config.mode === 'bounce-reverse'
- ? dotLottie.segments?.[0]
- : dotLottie.segments?.[1];
+ config.mode === 'reverse' || config.mode === 'reverse-bounce'
+ ? dotLottie.segments?.[0] ?? 0
+ : dotLottie.segments?.[1] ?? dotLottie.totalFrames;
expect(startFrame).toBe(expectedStartFrame);
expect(endFrame).toBe(expectedEndFrame);
- expect(dotLottie.direction).toBe(expectedDirection);
expect(dotLottie.isLoaded).toBe(true);
await vi.waitFor(() => {
@@ -263,8 +261,7 @@ describe('play', () => {
expect(onLoad).toHaveBeenCalledTimes(1);
});
- const expectedDirection = config.mode === 'reverse' || config.mode === 'bounce-reverse' ? -1 : 1;
- const totalFrames = (config.segments?.[1] ?? dotLottie.totalFrames - 1) - (config.segments?.[0] ?? 0);
+ const totalFrames = (config.segments?.[1] ?? dotLottie.totalFrames) - (config.segments?.[0] ?? 0);
const expectedDuration =
((config.mode?.includes('bounce') ? 2 : 1) *
@@ -273,31 +270,29 @@ describe('play', () => {
dotLottie.speed;
const expectedEndFrame =
- config.mode === 'reverse' || config.mode === 'bounce-reverse'
+ config.mode === 'reverse' || config.mode === 'reverse-bounce'
? config.segments?.[0] ?? 0
- : config.segments?.[1] ?? dotLottie.totalFrames - 1;
+ : config.segments?.[1] ?? dotLottie.totalFrames;
const expectedStartFrame =
- config.mode === 'reverse' || config.mode === 'bounce-reverse'
- ? config.segments?.[1] ?? dotLottie.totalFrames - 1
+ config.mode === 'reverse' || config.mode === 'reverse-bounce'
+ ? config.segments?.[1] ?? dotLottie.totalFrames
: config.segments?.[0] ?? 0;
const startFrame =
- config.mode === 'reverse' || config.mode === 'bounce-reverse'
- ? dotLottie.segments?.[1]
- : dotLottie.segments?.[0];
+ config.mode === 'reverse' || config.mode === 'reverse-bounce'
+ ? dotLottie.segments?.[1] ?? dotLottie.totalFrames
+ : dotLottie.segments?.[0] ?? 0;
const endFrame =
- config.mode === 'reverse' || config.mode === 'bounce-reverse'
- ? dotLottie.segments?.[0]
- : dotLottie.segments?.[1];
+ config.mode === 'reverse' || config.mode === 'reverse-bounce'
+ ? dotLottie.segments?.[0] ?? 0
+ : dotLottie.segments?.[1] ?? dotLottie.totalFrames;
expect(startFrame).toBe(expectedStartFrame);
expect(endFrame).toBe(expectedEndFrame);
- expect(dotLottie.direction).toBe(expectedDirection);
expect(dotLottie.isLoaded).toBe(true);
await vi.waitFor(() => {
- expect(onLoad).toHaveBeenCalledTimes(1);
expect(onPlay).toHaveBeenCalledTimes(1);
});
@@ -366,7 +361,7 @@ describe('play', () => {
expect(onLoad).toHaveBeenCalledTimes(1);
});
- const totalFrames = (config.segments?.[1] ?? dotLottie.totalFrames - 1) - (config.segments?.[0] ?? 0);
+ const totalFrames = (config.segments?.[1] ?? dotLottie.totalFrames) - (config.segments?.[0] ?? 0);
const expectedDuration =
((config.mode?.includes('bounce') ? 2 : 1) *
@@ -439,9 +434,13 @@ describe('play', () => {
timeout: dotLottie.duration * 1000 * 2,
});
- const startFrame = dotLottie.mode.includes('reverse') ? dotLottie.segments?.[1] : dotLottie.segments?.[0];
- const endFrame = dotLottie.mode.includes('reverse') ? dotLottie.segments?.[0] : dotLottie.segments?.[1];
- const totalFrames = (config.segments?.[1] ?? dotLottie.totalFrames - 1) - (config.segments?.[0] ?? 0);
+ const startFrame = dotLottie.mode.includes('reverse')
+ ? dotLottie.segments?.[1] ?? dotLottie.totalFrames
+ : dotLottie.segments?.[0] ?? 0;
+ const endFrame = dotLottie.mode.includes('reverse')
+ ? dotLottie.segments?.[0] ?? 0
+ : dotLottie.segments?.[1] ?? dotLottie.totalFrames;
+ const totalFrames = (config.segments?.[1] ?? dotLottie.totalFrames) - (config.segments?.[0] ?? 0);
expect(onFrame).toHaveBeenNthCalledWith(1, {
type: 'frame',
@@ -650,7 +649,6 @@ describe('load', () => {
expect(dotLottie.autoplay).toBe(true);
expect(dotLottie.mode).toBe('reverse');
expect(dotLottie.backgroundColor).toBe('#ff00ff');
- expect(dotLottie.direction).toBe(-1);
});
test('loads a new animation data via load() method', async () => {
@@ -687,9 +685,7 @@ describe('load', () => {
expect(dotLottie.autoplay).toBe(true);
expect(dotLottie.mode).toBe('reverse');
expect(dotLottie.backgroundColor).toBe('#000000');
- expect(dotLottie.direction).toBe(-1);
expect(dotLottie.useFrameInterpolation).toBe(true);
- expect(dotLottie.canvas).toBe(canvas);
});
test('emit loadError event when loading invalid lottie animation data', async () => {
@@ -727,16 +723,21 @@ describe('load', () => {
});
test('log error when loading invalid animation data of invalid type', async () => {
- const error = vi.spyOn(console, 'error');
+ const onLoadError = vi.fn();
dotLottie = new DotLottie({
canvas,
data: 1 as unknown as string,
});
- await vi.waitFor(() => expect(error).toHaveBeenCalledTimes(1));
+ dotLottie.addEventListener('loadError', onLoadError);
- expect(error).toHaveBeenCalledWith('Unsupported data type for animation data. Expected a string or ArrayBuffer.');
+ await vi.waitFor(() => expect(onLoadError).toHaveBeenCalledTimes(1));
+
+ expect(onLoadError).toHaveBeenCalledWith({
+ type: 'loadError',
+ error: new Error('Unsupported data type for animation data. Expected a string or ArrayBuffer.'),
+ });
});
test('emit loadError when fail to load wasm', async () => {
@@ -838,7 +839,7 @@ describe('stop', () => {
mode: 'reverse',
},
{
- mode: 'bounce-reverse',
+ mode: 'reverse-bounce',
},
{
mode: 'bounce',
@@ -849,7 +850,7 @@ describe('stop', () => {
speed: 2,
},
{
- mode: 'bounce-reverse',
+ mode: 'reverse-bounce',
segments: [5, 25],
speed: 2,
},
@@ -884,11 +885,11 @@ describe('stop', () => {
expect(onPlay).toHaveBeenCalledTimes(1);
});
- const totalFrames = (config.segments?.[1] ?? dotLottie.totalFrames - 1) - (config.segments?.[0] ?? 0);
+ const totalFrames = (config.segments?.[1] ?? dotLottie.totalFrames) - (config.segments?.[0] ?? 0);
const startFrame =
- config.mode === 'reverse' || config.mode === 'bounce-reverse'
- ? config.segments?.[1] ?? dotLottie.totalFrames - 1
+ config.mode === 'reverse' || config.mode === 'reverse-bounce'
+ ? config.segments?.[1] ?? dotLottie.totalFrames
: config.segments?.[0] ?? 0;
expect(onFrame).toHaveBeenNthCalledWith(1, {
@@ -948,7 +949,7 @@ describe('setMode', () => {
expect(dotLottie.mode).toBe('forward');
});
- test.each(['reverse', 'bounce', 'bounce-reverse'])('setMode(%s)', async (mode) => {
+ test.each(['reverse', 'bounce', 'reverse-bounce'])('setMode(%s)', async (mode) => {
const onPlay = vi.fn();
const onFrame = vi.fn();
@@ -968,8 +969,6 @@ describe('setMode', () => {
dotLottie.setMode(mode);
expect(dotLottie.mode).toBe(mode);
-
- expect(dotLottie.direction).toBe(dotLottie.mode.includes('reverse') ? -1 : 1);
});
});
diff --git a/packages/web/tests/setup.ts b/packages/web/tests/setup.ts
index 32cbed79..9bd22a0b 100644
--- a/packages/web/tests/setup.ts
+++ b/packages/web/tests/setup.ts
@@ -4,4 +4,4 @@
import { DotLottie } from '../src';
-DotLottie.setWasmUrl('src/wasm/renderer.wasm');
+DotLottie.setWasmUrl('src/core/dotlottie-player.wasm');
diff --git a/packages/web/tsup.config.cjs b/packages/web/tsup.config.cjs
index 6b27b48e..0af25cfc 100644
--- a/packages/web/tsup.config.cjs
+++ b/packages/web/tsup.config.cjs
@@ -14,17 +14,17 @@ module.exports = defineConfig({
treeshake: true,
clean: true,
dts: true,
- minify: false,
- sourcemap: false,
- entry: ['./src/**/*.ts', './src/**/*.js'],
- format: ['esm'],
+ minify: true,
+ sourcemap: true,
+ entry: ['./src/index.ts'],
+ format: ['esm', 'cjs'],
platform: 'neutral',
target: ['es2020', 'node18'],
tsconfig: 'tsconfig.build.json',
onSuccess: () => {
fs.copyFileSync(
- path.resolve(__dirname, 'src/wasm/renderer.wasm'),
- path.resolve(__dirname, 'dist/wasm/renderer.wasm'),
+ path.resolve(__dirname, 'src/core/dotlottie-player.wasm'),
+ path.resolve(__dirname, 'dist/dotlottie-player.wasm'),
);
},
});
diff --git a/packages/web/vitest.config.ts b/packages/web/vitest.config.ts
index d620ea48..8693dda1 100644
--- a/packages/web/vitest.config.ts
+++ b/packages/web/vitest.config.ts
@@ -16,10 +16,10 @@ export default defineConfig({
include: ['src/**/*.ts'],
reporter: ['json', 'json-summary', 'text-summary', 'lcov'],
thresholds: {
- statements: 84,
- branches: 76,
- functions: 86,
- lines: 85,
+ statements: 83,
+ branches: 75,
+ functions: 84,
+ lines: 86,
},
},
testTimeout: 10000,
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 8dc0d3f0..d1407ed5 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -282,10 +282,6 @@ importers:
version: 5.0.4
packages/web:
- dependencies:
- '@dotlottie/dotlottie-js':
- specifier: ^0.6.2
- version: 0.6.2
devDependencies:
'@types/node':
specifier: ^20.10.5
@@ -958,25 +954,6 @@ packages:
'@jridgewell/trace-mapping': 0.3.9
dev: true
- /@dotlottie/dotlottie-js@0.6.2:
- resolution: {integrity: sha512-3UGG60r7Dz868KvPYIBhuO6HPX2M5CpcXulXilLbQZ91eWKkF+amoJSdkSfdLtWjjcwu/jSgeErAercxC2StBw==}
- engines: {node: '>=18.0.0'}
- dependencies:
- browser-image-hash: 0.0.5
- fflate: 0.8.1
- sharp: 0.33.2
- sharp-phash: 2.1.0(sharp@0.33.2)
- valibot: 0.13.1
- dev: false
-
- /@emnapi/runtime@0.45.0:
- resolution: {integrity: sha512-Txumi3td7J4A/xTTwlssKieHKTGl3j4A1tglBx72auZ49YK7ePY6XZricgIg9mnZT4xPfA+UPCUdnhRuEFDL+w==}
- requiresBuild: true
- dependencies:
- tslib: 2.6.2
- dev: false
- optional: true
-
/@endemolshinegroup/cosmiconfig-typescript-loader@3.0.2(cosmiconfig@7.0.1)(typescript@5.0.4):
resolution: {integrity: sha512-QRVtqJuS1mcT56oHpVegkKBlgtWjXw/gHNWO3eL9oyB5Sc7HBoc2OLG/nYpVfT/Jejvo3NUrD0Udk7XgoyDKkA==}
engines: {node: '>=10.0.0'}
@@ -1787,194 +1764,6 @@ packages:
resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==}
dev: true
- /@img/sharp-darwin-arm64@0.33.2:
- resolution: {integrity: sha512-itHBs1rPmsmGF9p4qRe++CzCgd+kFYktnsoR1sbIAfsRMrJZau0Tt1AH9KVnufc2/tU02Gf6Ibujx+15qRE03w==}
- engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [arm64]
- os: [darwin]
- requiresBuild: true
- optionalDependencies:
- '@img/sharp-libvips-darwin-arm64': 1.0.1
- dev: false
- optional: true
-
- /@img/sharp-darwin-x64@0.33.2:
- resolution: {integrity: sha512-/rK/69Rrp9x5kaWBjVN07KixZanRr+W1OiyKdXcbjQD6KbW+obaTeBBtLUAtbBsnlTTmWthw99xqoOS7SsySDg==}
- engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [x64]
- os: [darwin]
- requiresBuild: true
- optionalDependencies:
- '@img/sharp-libvips-darwin-x64': 1.0.1
- dev: false
- optional: true
-
- /@img/sharp-libvips-darwin-arm64@1.0.1:
- resolution: {integrity: sha512-kQyrSNd6lmBV7O0BUiyu/OEw9yeNGFbQhbxswS1i6rMDwBBSX+e+rPzu3S+MwAiGU3HdLze3PanQ4Xkfemgzcw==}
- engines: {macos: '>=11', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [arm64]
- os: [darwin]
- requiresBuild: true
- dev: false
- optional: true
-
- /@img/sharp-libvips-darwin-x64@1.0.1:
- resolution: {integrity: sha512-eVU/JYLPVjhhrd8Tk6gosl5pVlvsqiFlt50wotCvdkFGf+mDNBJxMh+bvav+Wt3EBnNZWq8Sp2I7XfSjm8siog==}
- engines: {macos: '>=10.13', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [x64]
- os: [darwin]
- requiresBuild: true
- dev: false
- optional: true
-
- /@img/sharp-libvips-linux-arm64@1.0.1:
- resolution: {integrity: sha512-bnGG+MJjdX70mAQcSLxgeJco11G+MxTz+ebxlz8Y3dxyeb3Nkl7LgLI0mXupoO+u1wRNx/iRj5yHtzA4sde1yA==}
- engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [arm64]
- os: [linux]
- requiresBuild: true
- dev: false
- optional: true
-
- /@img/sharp-libvips-linux-arm@1.0.1:
- resolution: {integrity: sha512-FtdMvR4R99FTsD53IA3LxYGghQ82t3yt0ZQ93WMZ2xV3dqrb0E8zq4VHaTOuLEAuA83oDawHV3fd+BsAPadHIQ==}
- engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [arm]
- os: [linux]
- requiresBuild: true
- dev: false
- optional: true
-
- /@img/sharp-libvips-linux-s390x@1.0.1:
- resolution: {integrity: sha512-3+rzfAR1YpMOeA2zZNp+aYEzGNWK4zF3+sdMxuCS3ey9HhDbJ66w6hDSHDMoap32DueFwhhs3vwooAB2MaK4XQ==}
- engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [s390x]
- os: [linux]
- requiresBuild: true
- dev: false
- optional: true
-
- /@img/sharp-libvips-linux-x64@1.0.1:
- resolution: {integrity: sha512-3NR1mxFsaSgMMzz1bAnnKbSAI+lHXVTqAHgc1bgzjHuXjo4hlscpUxc0vFSAPKI3yuzdzcZOkq7nDPrP2F8Jgw==}
- engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [x64]
- os: [linux]
- requiresBuild: true
- dev: false
- optional: true
-
- /@img/sharp-libvips-linuxmusl-arm64@1.0.1:
- resolution: {integrity: sha512-5aBRcjHDG/T6jwC3Edl3lP8nl9U2Yo8+oTl5drd1dh9Z1EBfzUKAJFUDTDisDjUwc7N4AjnPGfCA3jl3hY8uDg==}
- engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [arm64]
- os: [linux]
- requiresBuild: true
- dev: false
- optional: true
-
- /@img/sharp-libvips-linuxmusl-x64@1.0.1:
- resolution: {integrity: sha512-dcT7inI9DBFK6ovfeWRe3hG30h51cBAP5JXlZfx6pzc/Mnf9HFCQDLtYf4MCBjxaaTfjCCjkBxcy3XzOAo5txw==}
- engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [x64]
- os: [linux]
- requiresBuild: true
- dev: false
- optional: true
-
- /@img/sharp-linux-arm64@0.33.2:
- resolution: {integrity: sha512-pz0NNo882vVfqJ0yNInuG9YH71smP4gRSdeL09ukC2YLE6ZyZePAlWKEHgAzJGTiOh8Qkaov6mMIMlEhmLdKew==}
- engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [arm64]
- os: [linux]
- requiresBuild: true
- optionalDependencies:
- '@img/sharp-libvips-linux-arm64': 1.0.1
- dev: false
- optional: true
-
- /@img/sharp-linux-arm@0.33.2:
- resolution: {integrity: sha512-Fndk/4Zq3vAc4G/qyfXASbS3HBZbKrlnKZLEJzPLrXoJuipFNNwTes71+Ki1hwYW5lch26niRYoZFAtZVf3EGA==}
- engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [arm]
- os: [linux]
- requiresBuild: true
- optionalDependencies:
- '@img/sharp-libvips-linux-arm': 1.0.1
- dev: false
- optional: true
-
- /@img/sharp-linux-s390x@0.33.2:
- resolution: {integrity: sha512-MBoInDXDppMfhSzbMmOQtGfloVAflS2rP1qPcUIiITMi36Mm5YR7r0ASND99razjQUpHTzjrU1flO76hKvP5RA==}
- engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [s390x]
- os: [linux]
- requiresBuild: true
- optionalDependencies:
- '@img/sharp-libvips-linux-s390x': 1.0.1
- dev: false
- optional: true
-
- /@img/sharp-linux-x64@0.33.2:
- resolution: {integrity: sha512-xUT82H5IbXewKkeF5aiooajoO1tQV4PnKfS/OZtb5DDdxS/FCI/uXTVZ35GQ97RZXsycojz/AJ0asoz6p2/H/A==}
- engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [x64]
- os: [linux]
- requiresBuild: true
- optionalDependencies:
- '@img/sharp-libvips-linux-x64': 1.0.1
- dev: false
- optional: true
-
- /@img/sharp-linuxmusl-arm64@0.33.2:
- resolution: {integrity: sha512-F+0z8JCu/UnMzg8IYW1TMeiViIWBVg7IWP6nE0p5S5EPQxlLd76c8jYemG21X99UzFwgkRo5yz2DS+zbrnxZeA==}
- engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [arm64]
- os: [linux]
- requiresBuild: true
- optionalDependencies:
- '@img/sharp-libvips-linuxmusl-arm64': 1.0.1
- dev: false
- optional: true
-
- /@img/sharp-linuxmusl-x64@0.33.2:
- resolution: {integrity: sha512-+ZLE3SQmSL+Fn1gmSaM8uFusW5Y3J9VOf+wMGNnTtJUMUxFhv+P4UPaYEYT8tqnyYVaOVGgMN/zsOxn9pSsO2A==}
- engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [x64]
- os: [linux]
- requiresBuild: true
- optionalDependencies:
- '@img/sharp-libvips-linuxmusl-x64': 1.0.1
- dev: false
- optional: true
-
- /@img/sharp-wasm32@0.33.2:
- resolution: {integrity: sha512-fLbTaESVKuQcpm8ffgBD7jLb/CQLcATju/jxtTXR1XCLwbOQt+OL5zPHSDMmp2JZIeq82e18yE0Vv7zh6+6BfQ==}
- engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [wasm32]
- requiresBuild: true
- dependencies:
- '@emnapi/runtime': 0.45.0
- dev: false
- optional: true
-
- /@img/sharp-win32-ia32@0.33.2:
- resolution: {integrity: sha512-okBpql96hIGuZ4lN3+nsAjGeggxKm7hIRu9zyec0lnfB8E7Z6p95BuRZzDDXZOl2e8UmR4RhYt631i7mfmKU8g==}
- engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [ia32]
- os: [win32]
- requiresBuild: true
- dev: false
- optional: true
-
- /@img/sharp-win32-x64@0.33.2:
- resolution: {integrity: sha512-E4magOks77DK47FwHUIGH0RYWSgRBfGdK56kIHSVeB9uIS4pPFr4N2kIVsXdQQo4LzOsENKV5KAhRlRL7eMAdg==}
- engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
- cpu: [x64]
- os: [win32]
- requiresBuild: true
- dev: false
- optional: true
-
/@isaacs/cliui@8.0.2:
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
engines: {node: '>=12'}
@@ -2550,30 +2339,6 @@ packages:
resolution: {integrity: sha512-AW8PKd6iX3vAZ0vA43nOUOnbq/X5ihgU+mSXXqunMkeQADGiqw/PY0JNeYtD5sr0PAy51YPgAPbDoeapv9r8WA==}
dev: true
- /@rgba-image/common@0.1.13:
- resolution: {integrity: sha512-AnOBmBpjSgcymTuVhTGy+RB4FfmEQqR2GeJY3d3xfvR9fl3HfhzwgVqopuh3bKSAT6KRpJr7wNmug0qr3oI7bA==}
- dev: false
-
- /@rgba-image/copy@0.1.3:
- resolution: {integrity: sha512-fscJhpp8YtVELGIwQsv1Pj6BEN4PEWAlMJ6a/HWzYxzVr3y/dut4BUrqeWRKiKeRXAGqaV6QxkBxAgYMQYZEvw==}
- dependencies:
- '@rgba-image/common': 0.1.13
- dev: false
-
- /@rgba-image/create-image@0.1.1:
- resolution: {integrity: sha512-ndExUNyi9Ooa/OZqiJS53vYrQ48FX7MDmMrEslDxhsorDsXpeKI9w689r4AYhT9CF9KZlBe8SmI++3BwSvvwAQ==}
- dependencies:
- '@rgba-image/common': 0.1.13
- dev: false
-
- /@rgba-image/lanczos@0.1.1:
- resolution: {integrity: sha512-MSGGU7BZmEbg1xHtNp+StARoN7R38zJnFgSEvSzB710nXsHGEaJt//z2VnPfRQTtKSKUXEnp95JSuqDlXTBrYA==}
- dependencies:
- '@rgba-image/common': 0.1.13
- '@rgba-image/copy': 0.1.3
- '@rgba-image/create-image': 0.1.1
- dev: false
-
/@rollup/rollup-android-arm-eabi@4.6.1:
resolution: {integrity: sha512-0WQ0ouLejaUCRsL93GD4uft3rOmB8qoQMU05Kb8CmMtMBe7XUDLAltxVZI1q6byNqEtU7N1ZX1Vw5lIpgulLQA==}
cpu: [arm]
@@ -4540,14 +4305,6 @@ packages:
wcwidth: 1.0.1
dev: true
- /browser-image-hash@0.0.5:
- resolution: {integrity: sha512-j+rsA1L3vL8k8ji4pFPFAOU/wN/hegwk1eoMshFk3OtjzEzdDrT9Dz94OkLc43NhWGck2a9t5eQQok6zjJSPHQ==}
- dependencies:
- '@rgba-image/lanczos': 0.1.1
- decimal.js: 10.4.3
- wasm-imagemagick: 1.2.8
- dev: false
-
/browserslist@4.22.1:
resolution: {integrity: sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==}
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
@@ -4919,6 +4676,7 @@ packages:
engines: {node: '>=7.0.0'}
dependencies:
color-name: 1.1.4
+ dev: true
/color-name@1.1.3:
resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
@@ -4926,27 +4684,13 @@ packages:
/color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
-
- /color-string@1.9.1:
- resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
- dependencies:
- color-name: 1.1.4
- simple-swizzle: 0.2.2
- dev: false
+ dev: true
/color-support@1.1.3:
resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==}
hasBin: true
dev: true
- /color@4.2.3:
- resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
- engines: {node: '>=12.5.0'}
- dependencies:
- color-convert: 2.0.1
- color-string: 1.9.1
- dev: false
-
/colorette@2.0.20:
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
dev: true
@@ -5858,10 +5602,6 @@ packages:
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dev: true
- /decimal.js@10.4.3:
- resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==}
- dev: false
-
/decode-named-character-reference@1.0.2:
resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==}
dependencies:
@@ -5977,11 +5717,6 @@ packages:
engines: {node: '>=8'}
dev: true
- /detect-libc@2.0.2:
- resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==}
- engines: {node: '>=8'}
- dev: false
-
/devlop@1.1.0:
resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
dependencies:
@@ -6203,12 +5938,6 @@ packages:
is-arrayish: 0.2.1
dev: true
- /error-stack-parser@2.1.4:
- resolution: {integrity: sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==}
- dependencies:
- stackframe: 1.3.4
- dev: false
-
/es-abstract@1.22.3:
resolution: {integrity: sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==}
engines: {node: '>= 0.4'}
@@ -7304,10 +7033,6 @@ packages:
web-streams-polyfill: 3.2.1
dev: true
- /fflate@0.8.1:
- resolution: {integrity: sha512-/exOvEuc+/iaUm105QIiOt4LpBdMTWsXxqR0HDF35vx3fmaKzw7354gTilCh5rkzEt8WYyG//ku3h3nRmd7CHQ==}
- dev: false
-
/figgy-pudding@3.5.2:
resolution: {integrity: sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==}
dev: true
@@ -8253,10 +7978,6 @@ packages:
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
dev: true
- /is-arrayish@0.3.2:
- resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
- dev: false
-
/is-bigint@1.0.4:
resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==}
dependencies:
@@ -9090,6 +8811,7 @@ packages:
engines: {node: '>=10'}
dependencies:
yallist: 4.0.0
+ dev: true
/lru-cache@7.18.3:
resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==}
@@ -10763,6 +10485,7 @@ packages:
/p-map@2.1.0:
resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==}
engines: {node: '>=6'}
+ dev: true
/p-map@4.0.0:
resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==}
@@ -12407,6 +12130,7 @@ packages:
hasBin: true
dependencies:
lru-cache: 6.0.0
+ dev: true
/serialize-error@11.0.3:
resolution: {integrity: sha512-2G2y++21dhj2R7iHAdd0FIzjGwuKZld+7Pl/bTU6YIkrC2ZMbVUjm+luj6A6V34Rv9XfKJDKpTWu9W4Gse1D9g==}
@@ -12448,45 +12172,6 @@ packages:
resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==}
dev: true
- /sharp-phash@2.1.0(sharp@0.33.2):
- resolution: {integrity: sha512-9JYWr4tiKpjRA5Mi0qHn6LP2evS+GjdRVGjDFOSnO761m5Pavkpm83SyzauO2Ntt7znVqTn7J3XTUwHjRPAonw==}
- engines: {node: '>= 10'}
- peerDependencies:
- sharp: '>= 0.25.4'
- dependencies:
- sharp: 0.33.2
- dev: false
-
- /sharp@0.33.2:
- resolution: {integrity: sha512-WlYOPyyPDiiM07j/UO+E720ju6gtNtHjEGg5vovUk1Lgxyjm2LFO+37Nt/UI3MMh2l6hxTWQWi7qk3cXJTutcQ==}
- engines: {libvips: '>=8.15.1', node: ^18.17.0 || ^20.3.0 || >=21.0.0}
- requiresBuild: true
- dependencies:
- color: 4.2.3
- detect-libc: 2.0.2
- semver: 7.5.4
- optionalDependencies:
- '@img/sharp-darwin-arm64': 0.33.2
- '@img/sharp-darwin-x64': 0.33.2
- '@img/sharp-libvips-darwin-arm64': 1.0.1
- '@img/sharp-libvips-darwin-x64': 1.0.1
- '@img/sharp-libvips-linux-arm': 1.0.1
- '@img/sharp-libvips-linux-arm64': 1.0.1
- '@img/sharp-libvips-linux-s390x': 1.0.1
- '@img/sharp-libvips-linux-x64': 1.0.1
- '@img/sharp-libvips-linuxmusl-arm64': 1.0.1
- '@img/sharp-libvips-linuxmusl-x64': 1.0.1
- '@img/sharp-linux-arm': 0.33.2
- '@img/sharp-linux-arm64': 0.33.2
- '@img/sharp-linux-s390x': 0.33.2
- '@img/sharp-linux-x64': 0.33.2
- '@img/sharp-linuxmusl-arm64': 0.33.2
- '@img/sharp-linuxmusl-x64': 0.33.2
- '@img/sharp-wasm32': 0.33.2
- '@img/sharp-win32-ia32': 0.33.2
- '@img/sharp-win32-x64': 0.33.2
- dev: false
-
/shebang-command@1.2.0:
resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==}
engines: {node: '>=0.10.0'}
@@ -12546,12 +12231,6 @@ packages:
- supports-color
dev: true
- /simple-swizzle@0.2.2:
- resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
- dependencies:
- is-arrayish: 0.3.2
- dev: false
-
/sirv@2.0.3:
resolution: {integrity: sha512-O9jm9BsID1P+0HOi81VpXPoDxYP374pkOLzACAoyUQ/3OUVndNpsz6wMnY2z+yOxzbllCKZrM+9QrWsv4THnyA==}
engines: {node: '>= 10'}
@@ -12673,11 +12352,6 @@ packages:
source-map: 0.6.1
dev: true
- /source-map@0.5.6:
- resolution: {integrity: sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==}
- engines: {node: '>=0.10.0'}
- dev: false
-
/source-map@0.6.1:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
@@ -12768,35 +12442,10 @@ packages:
deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility'
dev: true
- /stack-generator@2.0.10:
- resolution: {integrity: sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==}
- dependencies:
- stackframe: 1.3.4
- dev: false
-
/stackback@0.0.2:
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
dev: true
- /stackframe@1.3.4:
- resolution: {integrity: sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==}
- dev: false
-
- /stacktrace-gps@3.1.2:
- resolution: {integrity: sha512-GcUgbO4Jsqqg6RxfyTHFiPxdPqF+3LFmQhm7MgCuYQOYuWyqxo5pwRPz5d/u6/WYJdEnWfK4r+jGbyD8TSggXQ==}
- dependencies:
- source-map: 0.5.6
- stackframe: 1.3.4
- dev: false
-
- /stacktrace-js@2.0.2:
- resolution: {integrity: sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==}
- dependencies:
- error-stack-parser: 2.1.4
- stack-generator: 2.0.10
- stacktrace-gps: 3.1.2
- dev: false
-
/std-env@3.6.0:
resolution: {integrity: sha512-aFZ19IgVmhdB2uX599ve2kE6BIE3YMnQ6Gp6BURhW/oIzpXGKr878TQfAQZn1+i0Flcc/UKUy1gOlcfaUBCryg==}
dev: true
@@ -13396,6 +13045,7 @@ packages:
/tslib@2.6.2:
resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
+ dev: true
/tsup@8.0.1(ts-node@10.9.1)(typescript@5.0.4):
resolution: {integrity: sha512-hvW7gUSG96j53ZTSlT4j/KL0q1Q2l6TqGBFc6/mu/L46IoNWqLLUzLRLP1R8Q7xrJTmkDxxDoojV5uCVs1sVOg==}
@@ -14095,10 +13745,6 @@ packages:
resolution: {integrity: sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==}
dev: true
- /valibot@0.13.1:
- resolution: {integrity: sha512-SG2W1RHqE2LShl3p6tyERt6I+G6PQa9ZFVfkyNKXz01HBzL+tBeH5kXw/5AQeAzPJSjI3djVGBl1CyozA1kyBQ==}
- dev: false
-
/validate-npm-package-license@3.0.4:
resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
dependencies:
@@ -14526,13 +14172,6 @@ packages:
resolution: {integrity: sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==}
dev: true
- /wasm-imagemagick@1.2.8:
- resolution: {integrity: sha512-V7u80n7g+iAoV7sYgQKGSdG59J6/aSMGO0DDK0zxKnwOGjmVXyjP0yU4tX4cMrfC0t/Wk3I8TX7cmdbFQOYHpg==}
- dependencies:
- p-map: 2.1.0
- stacktrace-js: 2.0.2
- dev: false
-
/watchpack@2.4.0:
resolution: {integrity: sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==}
engines: {node: '>=10.13.0'}
@@ -14904,6 +14543,7 @@ packages:
/yallist@4.0.0:
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
+ dev: true
/yaml@1.10.2:
resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}