From b6411f39dcc932dae77e03e2d3f0b011dcd0cca0 Mon Sep 17 00:00:00 2001
From: Johannes Loher <johannes.loher@fg4f.de>
Date: Mon, 28 Nov 2022 00:52:31 +0100
Subject: [PATCH] feat: update for v10

Unfortunately, ditching TypeScript is needed for that :(
---
 .eslintrc.cjs                                 |   25 +-
 .gitignore                                    |    2 +
 .gitlab-ci.yml                                |    9 -
 .vscode/settings.json                         |    2 -
 .yarn/sdks/eslint/package.json                |    2 +-
 .yarn/sdks/prettier/package.json              |    2 +-
 .yarn/sdks/typescript/bin/tsc                 |   20 -
 .yarn/sdks/typescript/bin/tsserver            |   20 -
 .yarn/sdks/typescript/lib/tsc.js              |   20 -
 .yarn/sdks/typescript/lib/tsserver.js         |  223 ----
 .yarn/sdks/typescript/lib/tsserverlibrary.js  |  223 ----
 .yarn/sdks/typescript/lib/typescript.js       |   20 -
 .yarn/sdks/typescript/package.json            |    6 -
 jsconfig.json                                 |    8 +
 jsconfig.json.license                         |    3 +
 module.json                                   |    8 +-
 package.json                                  |   26 +-
 rollup.config.js                              |    2 +-
 .../{combat-tracker.ts => combat-tracker.js}  |   24 +-
 src/{constants.ts => constants.js}            |    2 +-
 .../{active-effect.ts => active-effect.js}    |    8 +-
 src/data/documents/{combat.ts => combat.js}   |  113 +-
 .../documents/{combatant.ts => combatant.js}  |  111 +-
 src/{helpers.ts => helpers.js}                |    2 +-
 src/systems/{ds4.ts => ds4.js}                |   64 +-
 src/systems/{index.ts => index.js}            |    0
 src/{tickwerk.ts => tickwerk.js}              |    0
 template.json                                 |  225 ----
 template.json.license                         |    6 -
 templates/combat-tracker.hbs                  |   71 +-
 tsconfig.eslint.json                          |    4 -
 tsconfig.eslint.json.license                  |    3 -
 tsconfig.json                                 |   16 -
 yarn.lock                                     | 1148 +----------------
 34 files changed, 271 insertions(+), 2147 deletions(-)
 delete mode 100755 .yarn/sdks/typescript/bin/tsc
 delete mode 100755 .yarn/sdks/typescript/bin/tsserver
 delete mode 100644 .yarn/sdks/typescript/lib/tsc.js
 delete mode 100644 .yarn/sdks/typescript/lib/tsserver.js
 delete mode 100644 .yarn/sdks/typescript/lib/tsserverlibrary.js
 delete mode 100644 .yarn/sdks/typescript/lib/typescript.js
 delete mode 100644 .yarn/sdks/typescript/package.json
 create mode 100644 jsconfig.json
 create mode 100644 jsconfig.json.license
 rename src/apps/sidebar/{combat-tracker.ts => combat-tracker.js} (65%)
 rename src/{constants.ts => constants.js} (64%)
 rename src/data/documents/{active-effect.ts => active-effect.js} (67%)
 rename src/data/documents/{combat.ts => combat.js} (51%)
 rename src/data/documents/{combatant.ts => combatant.js} (62%)
 rename src/{helpers.ts => helpers.js} (83%)
 rename src/systems/{ds4.ts => ds4.js} (62%)
 rename src/systems/{index.ts => index.js} (100%)
 rename src/{tickwerk.ts => tickwerk.js} (100%)
 delete mode 100644 template.json
 delete mode 100644 template.json.license
 delete mode 100644 tsconfig.eslint.json
 delete mode 100644 tsconfig.eslint.json.license
 delete mode 100644 tsconfig.json

diff --git a/.eslintrc.cjs b/.eslintrc.cjs
index 30a53bc..929e5a6 100644
--- a/.eslintrc.cjs
+++ b/.eslintrc.cjs
@@ -3,29 +3,36 @@
 // SPDX-License-Identifier: MIT
 
 module.exports = {
-  parser: '@typescript-eslint/parser',
-
   parserOptions: {
-    ecmaVersion: 2020,
     sourceType: 'module',
   },
 
   env: {
     browser: true,
+    es2022: true,
+    jquery: true,
   },
 
-  extends: ['plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended'],
+  extends: ['eslint:recommended', 'plugin:prettier/recommended'],
 
-  plugins: ['@typescript-eslint'],
+  globals: {
+    Hooks: 'readonly',
+    Actor: 'readonly',
+    CONFIG: 'readonly',
+    ui: 'readonly',
+    Game: 'readonly',
+    game: 'readonly',
+    foundry: 'readonly',
+    Dialog: 'readonly',
+    twist: 'readonly',
+  },
 
   rules: {},
 
   overrides: [
     {
-      files: ['./*.cjs', './*.js'],
-      rules: {
-        '@typescript-eslint/no-var-requires': 'off',
-      },
+      files: ['./*.cjs', './*.js', './tools/**/*'],
+      env: { node: true, browser: false, jquery: false },
     },
   ],
 };
diff --git a/.gitignore b/.gitignore
index a45e3fd..88bb62e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,6 +14,8 @@ npm-debug.log
 
 # Local configuration
 foundryconfig.json
+/common
+/client
 
 # Distribution files
 dist
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index cef2e42..3561dfa 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -30,15 +30,6 @@ lint:
   cache:
     <<: *global_cache
 
-typecheck:
-  stage: check
-  before_script:
-    - yarn install --immutable
-  script:
-    - yarn typecheck
-  cache:
-    <<: *global_cache
-
 reuse:
   stage: check
   image:
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 62c4dfb..d2cf83e 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -5,8 +5,6 @@
   },
   "eslint.nodePath": ".yarn/sdks",
   "prettier.prettierPath": ".yarn/sdks/prettier/index.js",
-  "typescript.tsdk": ".yarn/sdks/typescript/lib",
-  "typescript.enablePromptUseWorkspaceTsdk": true,
   "importSorter.generalConfiguration.sortOnBeforeSave": true,
   "importSorter.importStringConfiguration.maximumNumberOfImportExpressionsPerLine.type": "newLineEachExpressionAfterCountLimitExceptIfOnlyOne",
   "importSorter.importStringConfiguration.maximumNumberOfImportExpressionsPerLine.count": 120,
diff --git a/.yarn/sdks/eslint/package.json b/.yarn/sdks/eslint/package.json
index 6e9210f..a025cef 100644
--- a/.yarn/sdks/eslint/package.json
+++ b/.yarn/sdks/eslint/package.json
@@ -1,6 +1,6 @@
 {
   "name": "eslint",
-  "version": "8.25.0-sdk",
+  "version": "8.28.0-sdk",
   "main": "./lib/api.js",
   "type": "commonjs"
 }
diff --git a/.yarn/sdks/prettier/package.json b/.yarn/sdks/prettier/package.json
index b61805c..97db755 100644
--- a/.yarn/sdks/prettier/package.json
+++ b/.yarn/sdks/prettier/package.json
@@ -1,6 +1,6 @@
 {
   "name": "prettier",
-  "version": "2.7.1-sdk",
+  "version": "2.8.0-sdk",
   "main": "./index.js",
   "type": "commonjs"
 }
diff --git a/.yarn/sdks/typescript/bin/tsc b/.yarn/sdks/typescript/bin/tsc
deleted file mode 100755
index 454b950..0000000
--- a/.yarn/sdks/typescript/bin/tsc
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env node
-
-const {existsSync} = require(`fs`);
-const {createRequire} = require(`module`);
-const {resolve} = require(`path`);
-
-const relPnpApiPath = "../../../../.pnp.cjs";
-
-const absPnpApiPath = resolve(__dirname, relPnpApiPath);
-const absRequire = createRequire(absPnpApiPath);
-
-if (existsSync(absPnpApiPath)) {
-  if (!process.versions.pnp) {
-    // Setup the environment to be able to require typescript/bin/tsc
-    require(absPnpApiPath).setup();
-  }
-}
-
-// Defer to the real typescript/bin/tsc your application uses
-module.exports = absRequire(`typescript/bin/tsc`);
diff --git a/.yarn/sdks/typescript/bin/tsserver b/.yarn/sdks/typescript/bin/tsserver
deleted file mode 100755
index d7a6056..0000000
--- a/.yarn/sdks/typescript/bin/tsserver
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env node
-
-const {existsSync} = require(`fs`);
-const {createRequire} = require(`module`);
-const {resolve} = require(`path`);
-
-const relPnpApiPath = "../../../../.pnp.cjs";
-
-const absPnpApiPath = resolve(__dirname, relPnpApiPath);
-const absRequire = createRequire(absPnpApiPath);
-
-if (existsSync(absPnpApiPath)) {
-  if (!process.versions.pnp) {
-    // Setup the environment to be able to require typescript/bin/tsserver
-    require(absPnpApiPath).setup();
-  }
-}
-
-// Defer to the real typescript/bin/tsserver your application uses
-module.exports = absRequire(`typescript/bin/tsserver`);
diff --git a/.yarn/sdks/typescript/lib/tsc.js b/.yarn/sdks/typescript/lib/tsc.js
deleted file mode 100644
index 2f62fc9..0000000
--- a/.yarn/sdks/typescript/lib/tsc.js
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env node
-
-const {existsSync} = require(`fs`);
-const {createRequire} = require(`module`);
-const {resolve} = require(`path`);
-
-const relPnpApiPath = "../../../../.pnp.cjs";
-
-const absPnpApiPath = resolve(__dirname, relPnpApiPath);
-const absRequire = createRequire(absPnpApiPath);
-
-if (existsSync(absPnpApiPath)) {
-  if (!process.versions.pnp) {
-    // Setup the environment to be able to require typescript/lib/tsc.js
-    require(absPnpApiPath).setup();
-  }
-}
-
-// Defer to the real typescript/lib/tsc.js your application uses
-module.exports = absRequire(`typescript/lib/tsc.js`);
diff --git a/.yarn/sdks/typescript/lib/tsserver.js b/.yarn/sdks/typescript/lib/tsserver.js
deleted file mode 100644
index 0fb2ac1..0000000
--- a/.yarn/sdks/typescript/lib/tsserver.js
+++ /dev/null
@@ -1,223 +0,0 @@
-#!/usr/bin/env node
-
-const {existsSync} = require(`fs`);
-const {createRequire} = require(`module`);
-const {resolve} = require(`path`);
-
-const relPnpApiPath = "../../../../.pnp.cjs";
-
-const absPnpApiPath = resolve(__dirname, relPnpApiPath);
-const absRequire = createRequire(absPnpApiPath);
-
-const moduleWrapper = tsserver => {
-  if (!process.versions.pnp) {
-    return tsserver;
-  }
-
-  const {isAbsolute} = require(`path`);
-  const pnpApi = require(`pnpapi`);
-
-  const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//);
-  const isPortal = str => str.startsWith("portal:/");
-  const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`);
-
-  const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => {
-    return `${locator.name}@${locator.reference}`;
-  }));
-
-  // VSCode sends the zip paths to TS using the "zip://" prefix, that TS
-  // doesn't understand. This layer makes sure to remove the protocol
-  // before forwarding it to TS, and to add it back on all returned paths.
-
-  function toEditorPath(str) {
-    // We add the `zip:` prefix to both `.zip/` paths and virtual paths
-    if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) {
-      // We also take the opportunity to turn virtual paths into physical ones;
-      // this makes it much easier to work with workspaces that list peer
-      // dependencies, since otherwise Ctrl+Click would bring us to the virtual
-      // file instances instead of the real ones.
-      //
-      // We only do this to modules owned by the the dependency tree roots.
-      // This avoids breaking the resolution when jumping inside a vendor
-      // with peer dep (otherwise jumping into react-dom would show resolution
-      // errors on react).
-      //
-      const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str;
-      if (resolved) {
-        const locator = pnpApi.findPackageLocator(resolved);
-        if (locator && (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))) {
-          str = resolved;
-        }
-      }
-
-      str = normalize(str);
-
-      if (str.match(/\.zip\//)) {
-        switch (hostInfo) {
-          // Absolute VSCode `Uri.fsPath`s need to start with a slash.
-          // VSCode only adds it automatically for supported schemes,
-          // so we have to do it manually for the `zip` scheme.
-          // The path needs to start with a caret otherwise VSCode doesn't handle the protocol
-          //
-          // Ref: https://github.com/microsoft/vscode/issues/105014#issuecomment-686760910
-          //
-          // 2021-10-08: VSCode changed the format in 1.61.
-          // Before | ^zip:/c:/foo/bar.zip/package.json
-          // After  | ^/zip//c:/foo/bar.zip/package.json
-          //
-          // 2022-04-06: VSCode changed the format in 1.66.
-          // Before | ^/zip//c:/foo/bar.zip/package.json
-          // After  | ^/zip/c:/foo/bar.zip/package.json
-          //
-          // 2022-05-06: VSCode changed the format in 1.68
-          // Before | ^/zip/c:/foo/bar.zip/package.json
-          // After  | ^/zip//c:/foo/bar.zip/package.json
-          //
-          case `vscode <1.61`: {
-            str = `^zip:${str}`;
-          } break;
-
-          case `vscode <1.66`: {
-            str = `^/zip/${str}`;
-          } break;
-
-          case `vscode <1.68`: {
-            str = `^/zip${str}`;
-          } break;
-
-          case `vscode`: {
-            str = `^/zip/${str}`;
-          } break;
-
-          // To make "go to definition" work,
-          // We have to resolve the actual file system path from virtual path
-          // and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip)
-          case `coc-nvim`: {
-            str = normalize(resolved).replace(/\.zip\//, `.zip::`);
-            str = resolve(`zipfile:${str}`);
-          } break;
-
-          // Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server)
-          // We have to resolve the actual file system path from virtual path,
-          // everything else is up to neovim
-          case `neovim`: {
-            str = normalize(resolved).replace(/\.zip\//, `.zip::`);
-            str = `zipfile://${str}`;
-          } break;
-
-          default: {
-            str = `zip:${str}`;
-          } break;
-        }
-      }
-    }
-
-    return str;
-  }
-
-  function fromEditorPath(str) {
-    switch (hostInfo) {
-      case `coc-nvim`: {
-        str = str.replace(/\.zip::/, `.zip/`);
-        // The path for coc-nvim is in format of /<pwd>/zipfile:/<pwd>/.yarn/...
-        // So in order to convert it back, we use .* to match all the thing
-        // before `zipfile:`
-        return process.platform === `win32`
-          ? str.replace(/^.*zipfile:\//, ``)
-          : str.replace(/^.*zipfile:/, ``);
-      } break;
-
-      case `neovim`: {
-        str = str.replace(/\.zip::/, `.zip/`);
-        // The path for neovim is in format of zipfile:///<pwd>/.yarn/...
-        return str.replace(/^zipfile:\/\//, ``);
-      } break;
-
-      case `vscode`:
-      default: {
-        return str.replace(/^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, process.platform === `win32` ? `` : `/`)
-      } break;
-    }
-  }
-
-  // Force enable 'allowLocalPluginLoads'
-  // TypeScript tries to resolve plugins using a path relative to itself
-  // which doesn't work when using the global cache
-  // https://github.com/microsoft/TypeScript/blob/1b57a0395e0bff191581c9606aab92832001de62/src/server/project.ts#L2238
-  // VSCode doesn't want to enable 'allowLocalPluginLoads' due to security concerns but
-  // TypeScript already does local loads and if this code is running the user trusts the workspace
-  // https://github.com/microsoft/vscode/issues/45856
-  const ConfiguredProject = tsserver.server.ConfiguredProject;
-  const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype;
-  ConfiguredProject.prototype.enablePluginsWithOptions = function() {
-    this.projectService.allowLocalPluginLoads = true;
-    return originalEnablePluginsWithOptions.apply(this, arguments);
-  };
-
-  // And here is the point where we hijack the VSCode <-> TS communications
-  // by adding ourselves in the middle. We locate everything that looks
-  // like an absolute path of ours and normalize it.
-
-  const Session = tsserver.server.Session;
-  const {onMessage: originalOnMessage, send: originalSend} = Session.prototype;
-  let hostInfo = `unknown`;
-
-  Object.assign(Session.prototype, {
-    onMessage(/** @type {string | object} */ message) {
-      const isStringMessage = typeof message === 'string';
-      const parsedMessage = isStringMessage ? JSON.parse(message) : message;
-
-      if (
-        parsedMessage != null &&
-        typeof parsedMessage === `object` &&
-        parsedMessage.arguments &&
-        typeof parsedMessage.arguments.hostInfo === `string`
-      ) {
-        hostInfo = parsedMessage.arguments.hostInfo;
-        if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK) {
-          const [, major, minor] = (process.env.VSCODE_IPC_HOOK.match(
-            // The RegExp from https://semver.org/ but without the caret at the start
-            /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/
-          ) ?? []).map(Number)
-
-          if (major === 1) {
-            if (minor < 61) {
-              hostInfo += ` <1.61`;
-            } else if (minor < 66) {
-              hostInfo += ` <1.66`;
-            } else if (minor < 68) {
-              hostInfo += ` <1.68`;
-            }
-          }
-        }
-      }
-
-      const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => {
-        return typeof value === 'string' ? fromEditorPath(value) : value;
-      });
-
-      return originalOnMessage.call(
-        this,
-        isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON)
-      );
-    },
-
-    send(/** @type {any} */ msg) {
-      return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => {
-        return typeof value === `string` ? toEditorPath(value) : value;
-      })));
-    }
-  });
-
-  return tsserver;
-};
-
-if (existsSync(absPnpApiPath)) {
-  if (!process.versions.pnp) {
-    // Setup the environment to be able to require typescript/lib/tsserver.js
-    require(absPnpApiPath).setup();
-  }
-}
-
-// Defer to the real typescript/lib/tsserver.js your application uses
-module.exports = moduleWrapper(absRequire(`typescript/lib/tsserver.js`));
diff --git a/.yarn/sdks/typescript/lib/tsserverlibrary.js b/.yarn/sdks/typescript/lib/tsserverlibrary.js
deleted file mode 100644
index e7033a8..0000000
--- a/.yarn/sdks/typescript/lib/tsserverlibrary.js
+++ /dev/null
@@ -1,223 +0,0 @@
-#!/usr/bin/env node
-
-const {existsSync} = require(`fs`);
-const {createRequire} = require(`module`);
-const {resolve} = require(`path`);
-
-const relPnpApiPath = "../../../../.pnp.cjs";
-
-const absPnpApiPath = resolve(__dirname, relPnpApiPath);
-const absRequire = createRequire(absPnpApiPath);
-
-const moduleWrapper = tsserver => {
-  if (!process.versions.pnp) {
-    return tsserver;
-  }
-
-  const {isAbsolute} = require(`path`);
-  const pnpApi = require(`pnpapi`);
-
-  const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//);
-  const isPortal = str => str.startsWith("portal:/");
-  const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`);
-
-  const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => {
-    return `${locator.name}@${locator.reference}`;
-  }));
-
-  // VSCode sends the zip paths to TS using the "zip://" prefix, that TS
-  // doesn't understand. This layer makes sure to remove the protocol
-  // before forwarding it to TS, and to add it back on all returned paths.
-
-  function toEditorPath(str) {
-    // We add the `zip:` prefix to both `.zip/` paths and virtual paths
-    if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) {
-      // We also take the opportunity to turn virtual paths into physical ones;
-      // this makes it much easier to work with workspaces that list peer
-      // dependencies, since otherwise Ctrl+Click would bring us to the virtual
-      // file instances instead of the real ones.
-      //
-      // We only do this to modules owned by the the dependency tree roots.
-      // This avoids breaking the resolution when jumping inside a vendor
-      // with peer dep (otherwise jumping into react-dom would show resolution
-      // errors on react).
-      //
-      const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str;
-      if (resolved) {
-        const locator = pnpApi.findPackageLocator(resolved);
-        if (locator && (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))) {
-          str = resolved;
-        }
-      }
-
-      str = normalize(str);
-
-      if (str.match(/\.zip\//)) {
-        switch (hostInfo) {
-          // Absolute VSCode `Uri.fsPath`s need to start with a slash.
-          // VSCode only adds it automatically for supported schemes,
-          // so we have to do it manually for the `zip` scheme.
-          // The path needs to start with a caret otherwise VSCode doesn't handle the protocol
-          //
-          // Ref: https://github.com/microsoft/vscode/issues/105014#issuecomment-686760910
-          //
-          // 2021-10-08: VSCode changed the format in 1.61.
-          // Before | ^zip:/c:/foo/bar.zip/package.json
-          // After  | ^/zip//c:/foo/bar.zip/package.json
-          //
-          // 2022-04-06: VSCode changed the format in 1.66.
-          // Before | ^/zip//c:/foo/bar.zip/package.json
-          // After  | ^/zip/c:/foo/bar.zip/package.json
-          //
-          // 2022-05-06: VSCode changed the format in 1.68
-          // Before | ^/zip/c:/foo/bar.zip/package.json
-          // After  | ^/zip//c:/foo/bar.zip/package.json
-          //
-          case `vscode <1.61`: {
-            str = `^zip:${str}`;
-          } break;
-
-          case `vscode <1.66`: {
-            str = `^/zip/${str}`;
-          } break;
-
-          case `vscode <1.68`: {
-            str = `^/zip${str}`;
-          } break;
-
-          case `vscode`: {
-            str = `^/zip/${str}`;
-          } break;
-
-          // To make "go to definition" work,
-          // We have to resolve the actual file system path from virtual path
-          // and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip)
-          case `coc-nvim`: {
-            str = normalize(resolved).replace(/\.zip\//, `.zip::`);
-            str = resolve(`zipfile:${str}`);
-          } break;
-
-          // Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server)
-          // We have to resolve the actual file system path from virtual path,
-          // everything else is up to neovim
-          case `neovim`: {
-            str = normalize(resolved).replace(/\.zip\//, `.zip::`);
-            str = `zipfile://${str}`;
-          } break;
-
-          default: {
-            str = `zip:${str}`;
-          } break;
-        }
-      }
-    }
-
-    return str;
-  }
-
-  function fromEditorPath(str) {
-    switch (hostInfo) {
-      case `coc-nvim`: {
-        str = str.replace(/\.zip::/, `.zip/`);
-        // The path for coc-nvim is in format of /<pwd>/zipfile:/<pwd>/.yarn/...
-        // So in order to convert it back, we use .* to match all the thing
-        // before `zipfile:`
-        return process.platform === `win32`
-          ? str.replace(/^.*zipfile:\//, ``)
-          : str.replace(/^.*zipfile:/, ``);
-      } break;
-
-      case `neovim`: {
-        str = str.replace(/\.zip::/, `.zip/`);
-        // The path for neovim is in format of zipfile:///<pwd>/.yarn/...
-        return str.replace(/^zipfile:\/\//, ``);
-      } break;
-
-      case `vscode`:
-      default: {
-        return str.replace(/^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, process.platform === `win32` ? `` : `/`)
-      } break;
-    }
-  }
-
-  // Force enable 'allowLocalPluginLoads'
-  // TypeScript tries to resolve plugins using a path relative to itself
-  // which doesn't work when using the global cache
-  // https://github.com/microsoft/TypeScript/blob/1b57a0395e0bff191581c9606aab92832001de62/src/server/project.ts#L2238
-  // VSCode doesn't want to enable 'allowLocalPluginLoads' due to security concerns but
-  // TypeScript already does local loads and if this code is running the user trusts the workspace
-  // https://github.com/microsoft/vscode/issues/45856
-  const ConfiguredProject = tsserver.server.ConfiguredProject;
-  const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype;
-  ConfiguredProject.prototype.enablePluginsWithOptions = function() {
-    this.projectService.allowLocalPluginLoads = true;
-    return originalEnablePluginsWithOptions.apply(this, arguments);
-  };
-
-  // And here is the point where we hijack the VSCode <-> TS communications
-  // by adding ourselves in the middle. We locate everything that looks
-  // like an absolute path of ours and normalize it.
-
-  const Session = tsserver.server.Session;
-  const {onMessage: originalOnMessage, send: originalSend} = Session.prototype;
-  let hostInfo = `unknown`;
-
-  Object.assign(Session.prototype, {
-    onMessage(/** @type {string | object} */ message) {
-      const isStringMessage = typeof message === 'string';
-      const parsedMessage = isStringMessage ? JSON.parse(message) : message;
-
-      if (
-        parsedMessage != null &&
-        typeof parsedMessage === `object` &&
-        parsedMessage.arguments &&
-        typeof parsedMessage.arguments.hostInfo === `string`
-      ) {
-        hostInfo = parsedMessage.arguments.hostInfo;
-        if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK) {
-          const [, major, minor] = (process.env.VSCODE_IPC_HOOK.match(
-            // The RegExp from https://semver.org/ but without the caret at the start
-            /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/
-          ) ?? []).map(Number)
-
-          if (major === 1) {
-            if (minor < 61) {
-              hostInfo += ` <1.61`;
-            } else if (minor < 66) {
-              hostInfo += ` <1.66`;
-            } else if (minor < 68) {
-              hostInfo += ` <1.68`;
-            }
-          }
-        }
-      }
-
-      const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => {
-        return typeof value === 'string' ? fromEditorPath(value) : value;
-      });
-
-      return originalOnMessage.call(
-        this,
-        isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON)
-      );
-    },
-
-    send(/** @type {any} */ msg) {
-      return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => {
-        return typeof value === `string` ? toEditorPath(value) : value;
-      })));
-    }
-  });
-
-  return tsserver;
-};
-
-if (existsSync(absPnpApiPath)) {
-  if (!process.versions.pnp) {
-    // Setup the environment to be able to require typescript/lib/tsserverlibrary.js
-    require(absPnpApiPath).setup();
-  }
-}
-
-// Defer to the real typescript/lib/tsserverlibrary.js your application uses
-module.exports = moduleWrapper(absRequire(`typescript/lib/tsserverlibrary.js`));
diff --git a/.yarn/sdks/typescript/lib/typescript.js b/.yarn/sdks/typescript/lib/typescript.js
deleted file mode 100644
index e14fa87..0000000
--- a/.yarn/sdks/typescript/lib/typescript.js
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env node
-
-const {existsSync} = require(`fs`);
-const {createRequire} = require(`module`);
-const {resolve} = require(`path`);
-
-const relPnpApiPath = "../../../../.pnp.cjs";
-
-const absPnpApiPath = resolve(__dirname, relPnpApiPath);
-const absRequire = createRequire(absPnpApiPath);
-
-if (existsSync(absPnpApiPath)) {
-  if (!process.versions.pnp) {
-    // Setup the environment to be able to require typescript/lib/typescript.js
-    require(absPnpApiPath).setup();
-  }
-}
-
-// Defer to the real typescript/lib/typescript.js your application uses
-module.exports = absRequire(`typescript/lib/typescript.js`);
diff --git a/.yarn/sdks/typescript/package.json b/.yarn/sdks/typescript/package.json
deleted file mode 100644
index b117d6a..0000000
--- a/.yarn/sdks/typescript/package.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "name": "typescript",
-  "version": "4.7.4-sdk",
-  "main": "./lib/typescript.js",
-  "type": "commonjs"
-}
diff --git a/jsconfig.json b/jsconfig.json
new file mode 100644
index 0000000..8b929d6
--- /dev/null
+++ b/jsconfig.json
@@ -0,0 +1,8 @@
+{
+  "compilerOptions": {
+    "module": "es2022",
+    "target": "ES2022"
+  },
+  "exclude": ["node_modules", "dist"],
+  "include": ["src", "client", "common"]
+}
diff --git a/jsconfig.json.license b/jsconfig.json.license
new file mode 100644
index 0000000..467ee14
--- /dev/null
+++ b/jsconfig.json.license
@@ -0,0 +1,3 @@
+SPDX-FileCopyrightText: 2022 Johannes Loher
+
+SPDX-License-Identifier: MIT
diff --git a/module.json b/module.json
index 1792189..52a0da3 100644
--- a/module.json
+++ b/module.json
@@ -1,5 +1,5 @@
 {
-  "name": "tickwerk",
+  "id": "tickwerk",
   "title": "Tickwerk",
   "description": "A tick based combat system for Foundry Virtual Tabletop",
   "authors": [
@@ -16,8 +16,10 @@
   "bugs": "https://git.f3l.de/dungeonslayers/tickwerk/-/issues",
   "changelog": "https://git.f3l.de/dungeonslayers/tickwerk/-/releases/1.2.1",
   "version": "1.2.1",
-  "minimumCoreVersion": "9",
-  "compatibleCoreVersion": "9",
+  "compatibility": {
+    "minimum": "10.290",
+    "verified": "10"
+  },
   "esmodules": ["tickwerk.js"],
   "styles": ["styles/tickwerk.css"],
   "languages": [
diff --git a/package.json b/package.json
index 612eb99..68ea59d 100644
--- a/package.json
+++ b/package.json
@@ -27,11 +27,9 @@
     "clean": "run-p clean:files clean:link",
     "clean:files": "rimraf dist",
     "clean:link": "node ./tools/link-package.js --clean",
-    "lint": "eslint --ext .ts,.js,.cjs,.mjs .",
-    "lint:fix": "eslint --ext .ts,.js,.cjs,.mjs --fix .",
-    "format": "prettier --write \"./**/*.(ts|js|cjs|mjs|json|scss|yml)\"",
-    "typecheck": "tsc --noEmit",
-    "typecheck:watch": "tsc --noEmit --watch",
+    "lint": "eslint --ext .js,.cjs,.mjs .",
+    "lint:fix": "eslint --ext .js,.cjs,.mjs --fix .",
+    "format": "prettier --write \"./**/*.(js|cjs|mjs|json|scss|yml)\"",
     "bump-version": "node ./tools/bump-version.js",
     "postinstall": "husky install",
     "changelog": "conventional-changelog -p conventionalcommits -o CHANGELOG.md -r 2"
@@ -40,20 +38,7 @@
     "@commitlint/cli": "17.3.0",
     "@commitlint/config-conventional": "17.3.0",
     "@guanghechen/rollup-plugin-copy": "2.1.4",
-    "@league-of-foundry-developers/foundry-vtt-types": "9.280.0",
-    "@pixi/constants": "6.2.1",
-    "@pixi/core": "6.2.1",
-    "@pixi/display": "6.2.1",
-    "@pixi/graphics": "6.2.1",
-    "@pixi/math": "6.2.1",
-    "@pixi/runner": "6.2.1",
-    "@pixi/settings": "6.2.1",
-    "@pixi/utils": "6.2.1",
-    "@seald-io/nedb": "3.1.0",
     "@swc/core": "1.3.20",
-    "@types/fs-extra": "9.0.13",
-    "@typescript-eslint/eslint-plugin": "5.44.0",
-    "@typescript-eslint/parser": "5.44.0",
     "conventional-changelog-cli": "2.2.2",
     "conventional-changelog-conventionalcommits": "5.0.0",
     "eslint": "8.28.0",
@@ -70,13 +55,10 @@
     "rollup-plugin-swc3": "0.7.0",
     "sass": "1.56.1",
     "semver": "7.3.8",
-    "ts-node": "10.9.1",
-    "tslib": "2.4.1",
-    "typescript": "4.7.4",
     "yargs": "17.6.2"
   },
   "lint-staged": {
-    "*.(ts|js|cjs|mjs)": "eslint --cache --fix",
+    "*.(js|cjs|mjs)": "eslint --cache --fix",
     "*.(json|scss|yml)": "prettier --write"
   },
   "packageManager": "yarn@3.2.4"
diff --git a/rollup.config.js b/rollup.config.js
index 4f325df..256579a 100644
--- a/rollup.config.js
+++ b/rollup.config.js
@@ -24,7 +24,7 @@ const isProduction = process.env.NODE_ENV === 'production';
  * @type {import('rollup').RollupOptions}
  */
 const config = {
-  input: { [name]: `${sourceDirectory}/${name}.ts` },
+  input: { [name]: `${sourceDirectory}/${name}.js` },
   output: {
     dir: distDirectory,
     format: 'es',
diff --git a/src/apps/sidebar/combat-tracker.ts b/src/apps/sidebar/combat-tracker.js
similarity index 65%
rename from src/apps/sidebar/combat-tracker.ts
rename to src/apps/sidebar/combat-tracker.js
index 3a8adbe..d7c02dc 100644
--- a/src/apps/sidebar/combat-tracker.ts
+++ b/src/apps/sidebar/combat-tracker.js
@@ -3,35 +3,43 @@
 // SPDX-License-Identifier: MIT
 
 export const registerCombatTrackerFunctionality = () => {
-  CONFIG.ui.combat = CombatTrackerMixin(CONFIG.ui.combat as typeof CombatTracker); // TODO: improve upstream types
+  CONFIG.ui.combat = CombatTrackerMixin(CONFIG.ui.combat);
 };
 
-const CombatTrackerMixin = (BaseCombatTracker: typeof CombatTracker) => {
+/**
+ * Enhance a combat tracker class with functionality for Tickwerk.
+ * @param {typeof CombatTracker} BaseCombatTracker The combat tracker class to enhance
+ * @returns The enhanced combat tracker class
+ */
+const CombatTrackerMixin = (BaseCombatTracker) => {
   return class TickwerkCombatTracker extends BaseCombatTracker {
-    static override get defaultOptions(): ApplicationOptions {
+    /** @override */
+    static get defaultOptions() {
       return foundry.utils.mergeObject(super.defaultOptions, {
         template: 'modules/tickwerk/templates/combat-tracker.hbs',
       });
     }
 
-    override async getData(options?: Partial<ApplicationOptions>): Promise<CombatTracker.Data> {
+    /** @override */
+    async getData(options) {
       const data = await super.getData(options);
       return {
         ...data,
         turns: data.turns.map((turn) => ({ ...turn, waiting: this.viewed?.combatants.get(turn.id)?.waiting })),
-      } as CombatTracker.Data; // TODO: Improve upstream types
+      };
     }
 
-    override activateListeners(html: JQuery): void {
+    /** @override */
+    activateListeners(html) {
       super.activateListeners(html);
       html.find('.combatant-control[data-control="toggleWaiting"]').on('click', this._onToggleWaiting.bind(this));
     }
 
     /**
      * Handle clicks on the Combatant waiting control button.
-     * @param event The originating click event
+     * @param {JQuery.ClickEvent} event The originating click event
      */
-    _onToggleWaiting(event: JQuery.ClickEvent) {
+    _onToggleWaiting(event) {
       event.preventDefault();
       event.stopPropagation();
       const button = event.currentTarget;
diff --git a/src/constants.ts b/src/constants.js
similarity index 64%
rename from src/constants.ts
rename to src/constants.js
index 0a54f83..28b3e82 100644
--- a/src/constants.ts
+++ b/src/constants.js
@@ -2,4 +2,4 @@
 //
 // SPDX-License-Identifier: MIT
 
-export const packageId = 'tickwerk' as const;
+export const packageId = 'tickwerk';
diff --git a/src/data/documents/active-effect.ts b/src/data/documents/active-effect.js
similarity index 67%
rename from src/data/documents/active-effect.ts
rename to src/data/documents/active-effect.js
index d11fe6d..b640a6b 100644
--- a/src/data/documents/active-effect.ts
+++ b/src/data/documents/active-effect.js
@@ -5,12 +5,12 @@
 import { getGame } from '../../helpers';
 
 export const registerActiveEffectFunctionality = () => {
-  Hooks.on<Hooks.CreateDocument<typeof ActiveEffect>>('createActiveEffect', onActiveEffectChanged);
-  Hooks.on<Hooks.UpdateDocument<typeof ActiveEffect>>('updateActiveEffect', onActiveEffectChanged);
-  Hooks.on<Hooks.DeleteDocument<typeof ActiveEffect>>('deleteActiveEffect', onActiveEffectChanged);
+  Hooks.on('createActiveEffect', onActiveEffectChanged);
+  Hooks.on('updateActiveEffect', onActiveEffectChanged);
+  Hooks.on('deleteActiveEffect', onActiveEffectChanged);
 };
 
-const onActiveEffectChanged = (activeEffect: ActiveEffect) => {
+const onActiveEffectChanged = (activeEffect) => {
   const game = getGame();
   const parent = activeEffect.parent;
   const actorId = parent?.id;
diff --git a/src/data/documents/combat.ts b/src/data/documents/combat.js
similarity index 51%
rename from src/data/documents/combat.ts
rename to src/data/documents/combat.js
index 1564249..dfcfc3c 100644
--- a/src/data/documents/combat.ts
+++ b/src/data/documents/combat.js
@@ -4,62 +4,76 @@
 
 import { packageId } from '../../constants';
 
-import type { TickwerkCombatant } from './combatant';
-
 export const registerCombatFunctionality = () => {
   CONFIG.Combat.documentClass = CombatMixin(CONFIG.Combat.documentClass);
 };
 
-const CombatMixin = (BaseCombat: typeof Combat) => {
+/**
+ * Enhance a combat class with functionality for the Tickwerk.
+ * @param {typeof Combat} BaseCombat  The combat class to enhance
+ * @returns A combat class, adapted for the Tickwerk
+ */
+const CombatMixin = (BaseCombat) => {
   return class TickwerkCombat extends BaseCombat {
-    override get combatant() {
-      return this.turns[0];
+    /** @override */
+    get combatant() {
+      return this.turns?.[0];
     }
 
-    override get round() {
-      return this.tickValue;
+    /** @override */
+    get nextCombatant() {
+      return this.turns?.[1];
     }
 
-    override get started() {
-      return this.turns.length > 0 && (this.getFlag(packageId, 'started') ?? false);
-    }
-
-    override get turn() {
-      return 0;
+    /** @override */
+    get started() {
+      return (this.turns?.length ?? 0) > 0 && (this.getFlag(packageId, 'started') ?? false);
     }
 
     /**
      * The current tick value of the Combat encounter.
+     * @type {number}
      */
-    get tickValue(): number {
+    get tickValue() {
       const tickValues = this.combatants
         .filter((combatant) => !combatant.isDefeated && !combatant.waiting)
         .map((combatant) => combatant.initiative)
-        .filter((tickValue): tickValue is number => tickValue !== null);
+        .filter((tickValue) => tickValue !== null);
       const tickValue = Math.min(...tickValues);
       return tickValue === Infinity ? 0 : tickValue;
     }
 
-    override async nextRound(): Promise<never> {
+    /** @override */
+    prepareDerivedData() {
+      super.prepareDerivedData();
+      this.turn = this.started ? 0 : null;
+    }
+
+    /** @override */
+    async nextRound() {
       throw new Error('Not implemented!');
     }
 
-    override async nextTurn() {
+    /** @override */
+    async nextTurn() {
       await this.combatant?.advanceTicksDialog();
       return this;
     }
 
-    override previousRound(): Promise<never> {
+    /** @override */
+    previousRound() {
       throw new Error('Not implemented!');
     }
 
-    override previousTurn(): Promise<never> {
+    /** @override */
+    previousTurn() {
       throw new Error('Not implemented!');
     }
 
-    override async resetAll() {
+    /** @override */
+    async resetAll() {
       for (const c of this.combatants) {
-        c.data.update({ initiative: null });
+        c.updateSource({ initiative: null });
       }
       return this.update(
         {
@@ -74,7 +88,8 @@ const CombatMixin = (BaseCombat: typeof Combat) => {
       );
     }
 
-    override setupTurns(): this['turns'] {
+    /** @override */
+    setupTurns() {
       const turns = this.combatants.contents.sort(this._sortCombatants);
 
       const c = turns[0];
@@ -82,12 +97,13 @@ const CombatMixin = (BaseCombat: typeof Combat) => {
         round: this.round,
         turn: 0,
         combatantId: c?.id ?? null,
-        tokenId: c?.data.tokenId ?? null,
+        tokenId: c?.tokenId ?? null,
       };
       return (this.turns = turns);
     }
 
-    override async startCombat(): Promise<this | undefined> {
+    /** @override */
+    async startCombat() {
       const hasCombatantWithTickValue = this.combatants.find(
         (combatant) => !combatant.isDefeated && combatant.initiative !== null,
       );
@@ -95,10 +111,14 @@ const CombatMixin = (BaseCombat: typeof Combat) => {
         ui.notifications?.warn('TICKWERK.WarningCannotStartCombat', { localize: true });
         return this;
       }
-      return this.setFlag(packageId, 'started', true);
+      this._playCombatSound('startEncounter');
+      const updateData = { flags: { [packageId]: { started: true } } };
+      Hooks.callAll('combatStart', this, updateData);
+      return this.update(updateData);
     }
 
-    protected override _sortCombatants(a: TickwerkCombatant, b: TickwerkCombatant): number {
+    /** @override */
+    _sortCombatants(a, b) {
       const da = a.isDefeated ? 1 : 0;
       const db = b.isDefeated ? 1 : 0;
       const cd = da - db;
@@ -121,15 +141,36 @@ const CombatMixin = (BaseCombat: typeof Combat) => {
 
       return (b.id ?? '') > (a.id ?? '') ? 1 : -1;
     }
+
+    /** @override */
+    async _preUpdate(changed, options, user) {
+      delete changed.round;
+      delete changed.turn;
+      options.tickwerk = {
+        combatantBeforeUpdate: this.combatant?.id,
+        nextCombatantBeforeUpdate: this.nextCombatant?.id,
+      };
+      return super._preUpdate(changed, options, user);
+    }
+
+    /** @override */
+    _onUpdate(data, options, userId) {
+      super._onUpdate(data, options, userId);
+      if (game.user.character) {
+        const { combatantBeforeUpdate, nextCombatantBeforeUpdate } = options.tickwerk ?? {};
+        if (
+          combatantBeforeUpdate !== undefined &&
+          combatantBeforeUpdate !== this.combatant &&
+          this.combatant?.actorId === game.user.character._id
+        ) {
+          this._playCombatSound('yourTurn');
+        } else if (
+          nextCombatantBeforeUpdate !== undefined &&
+          nextCombatantBeforeUpdate !== this.nextCombatant &&
+          this.nextCombatant?.actorId === game.user.character._id
+        )
+          this._playCombatSound('nextUp');
+      }
+    }
   };
 };
-
-declare global {
-  interface FlagConfig {
-    Combat: {
-      tickwerk?: {
-        started?: boolean;
-      };
-    };
-  }
-}
diff --git a/src/data/documents/combatant.ts b/src/data/documents/combatant.js
similarity index 62%
rename from src/data/documents/combatant.ts
rename to src/data/documents/combatant.js
index d7470a6..c996194 100644
--- a/src/data/documents/combatant.ts
+++ b/src/data/documents/combatant.js
@@ -2,7 +2,6 @@
 //
 // SPDX-License-Identifier: MIT
 
-import type { CombatantDataConstructorData } from '@league-of-foundry-developers/foundry-vtt-types/src/foundry/common/data/data.mjs/combatantData';
 import { packageId } from '../../constants';
 import { getGame } from '../../helpers';
 
@@ -10,39 +9,49 @@ export const registerCombatantFunctionality = () => {
   CONFIG.Combatant.documentClass = CombatantMixin(CONFIG.Combatant.documentClass);
 };
 
-const CombatantMixin = (BaseCombatant: typeof Combatant) => {
+/**
+ * Enhance a co,batant class with functionality for the Tickwerk.
+ * @param {typeof Combatant} BaseCombatant  The combat class to enhance
+ * @returns A combat class, adapted for the Tickwerk
+ */
+const CombatantMixin = (BaseCombatant) => {
   return class TickwerkCombatant extends BaseCombatant {
     /**
      * An temporary property to make changes to the initiative available to other instances in their `_pre…` methods.
+     * @type {number|null|undefined}
      */
-    _newInitiative: number | null | undefined;
+    _newInitiative;
 
     /**
      * An temporary property to make changes to the tiebreaker available to other instances in their `_pre…` methods.
+     * @type {number|undefined}
      */
-    _newTiebreaker: number | undefined;
+    _newTiebreaker;
 
     /***
      * Is this combatant currently waiting?
+     * @type {boolean}
      */
-    get waiting(): boolean {
+    get waiting() {
       return this.getFlag(packageId, 'waiting') ?? false;
     }
 
     /**
      * Toggle the waiting state of this combatant.
+     * @returns {Promise<this|undefined>} The updated combatant
      */
-    toggleWaiting(): Promise<this | undefined> {
-      const update: Record<string, unknown> = { [`flags.${packageId}.waiting`]: !this.waiting };
+    toggleWaiting() {
+      const update = { [`flags.${packageId}.waiting`]: !this.waiting };
       if (this.parent?.started && this.waiting) update.initiative = this.parent?.round;
       return this.update(update);
     }
 
     /**
      * Advance for the given number of ticks.
-     * @param ticks The number of ticks to advance for
+     * @param {number} ticks  The number of ticks to advance for
+     * @returns {Promise<void>} A promise that resolves once when the combatant has advanced
      */
-    async advanceTicks(ticks: number): Promise<void> {
+    async advanceTicks(ticks) {
       if (this.initiative === null) {
         ui.notifications?.warn('TICKWERK.WarningCannotAdvanceWithoutTickValue', { localize: true });
         return;
@@ -59,11 +68,15 @@ const CombatantMixin = (BaseCombatant: typeof Combatant) => {
       await this.update({ initiative: this.initiative + ticks });
       const advanceTime = ticks * CONFIG.time.roundTime;
       if (advanceTime !== 0) {
-        await this.combat?.update(undefined, { diff: false, advanceTime } as DocumentModificationContext);
+        await this.combat?.update(undefined, { diff: false, advanceTime });
       }
     }
 
-    async advanceTicksDialog(): Promise<void> {
+    /**
+     * Show a dialog for advancing the combatant a certain number of ticks.
+     * @returns {Promise<void>} A promise that resolves when the dialog has been confirmed and the combatant has advanced
+     */
+    async advanceTicksDialog() {
       const game = getGame();
       const id = foundry.utils.randomID();
 
@@ -76,14 +89,14 @@ const CombatantMixin = (BaseCombatant: typeof Combatant) => {
         title: game.i18n.localize('TICKWERK.AdvanceTicks'),
         content: form,
         yes: (html) => {
-          const ticks = html[0]?.querySelector<HTMLInputElement>('input[name="ticks"]')?.value;
+          const ticks = html[0]?.querySelector('input[name="ticks"]')?.value;
           const parsedTicks = ticks !== undefined ? parseInt(ticks) : undefined;
-          return Number.isSafeInteger(parsedTicks) ? parsedTicks : undefined;
+          return Number.isSafeInteger(parsedTicks) ? parsedTicks : NaN;
         },
         rejectClose: false,
       });
 
-      if (ticks === undefined) {
+      if (Number.isNaN(ticks)) {
         ui.notifications?.warn('TICKWERK.WarningInvalidNumberOfTicks', { localize: true });
         return;
       }
@@ -95,9 +108,9 @@ const CombatantMixin = (BaseCombatant: typeof Combatant) => {
 
     /**
      * Update tiebreaker data for a given creation or update.
-     * @param data The data of the creation / update
+     * @param {object} data The data of the creation / update
      */
-    async #updateTiebreakerData(data: DeepPartial<CombatantDataConstructorData>): Promise<void> {
+    async #updateTiebreakerData(data) {
       if ('initiative' in data) {
         const combatantsWithSameTickValue =
           this.parent?.combatants.filter((combatant) => {
@@ -106,7 +119,7 @@ const CombatantMixin = (BaseCombatant: typeof Combatant) => {
             return otherInitiative === data.initiative;
           }) ?? [];
         const tiebreaker = await this.#getTiebreaker(combatantsWithSameTickValue);
-        setProperty(data, `flags.${packageId}.tiebreaker`, tiebreaker);
+        foundry.utils.setProperty(data, `flags.${packageId}.tiebreaker`, tiebreaker);
         this._newInitiative = data.initiative;
         this._newTiebreaker = tiebreaker;
       }
@@ -114,46 +127,48 @@ const CombatantMixin = (BaseCombatant: typeof Combatant) => {
 
     /**
      * Get a tiebreaker between this combatant and the given other combatants.
-     * @param combatants The other combatants among which to find a tiebreaker
-     * @returns A promise that resolves to the tiebreaker
+     * @param {TickwerkCombatant[]} combatants  The other combatants among which to find a tiebreaker
+     * @returns {Promise<number>} A promise that resolves to the tiebreaker
      */
-    async #getTiebreaker(combatants: TickwerkCombatant[]): Promise<number> {
+    async #getTiebreaker(combatants) {
       const getTiebreaker = CONFIG.tickwerk?.getTiebreaker ?? defaultGetTiebreaker;
       return getTiebreaker(this, combatants);
     }
 
-    override testUserPermission(
-      user: foundry.documents.BaseUser,
-      permission: keyof typeof foundry.CONST.DOCUMENT_PERMISSION_LEVELS | foundry.CONST.DOCUMENT_PERMISSION_LEVELS,
-      { exact }: { exact?: boolean | undefined } = {},
-    ): boolean {
+    /** @override */
+    testUserPermission(user, permission, { exact } = {}) {
       if (user.isGM) return true;
       return super.testUserPermission(user, permission, { exact });
     }
 
-    protected override _getInitiativeFormula(): string {
+    /** @override */
+    _getInitiativeFormula() {
       const getInitiativeFormula = CONFIG.tickwerk?.getInitiativeFormula;
       if (getInitiativeFormula) return getInitiativeFormula(this);
       return super._getInitiativeFormula();
     }
 
-    protected override async _preCreate(...args: Parameters<Combatant['_preCreate']>): Promise<void> {
+    /** @override */
+    async _preCreate(...args) {
       await super._preCreate(...args);
       await this.#updateTiebreakerData(args[0]);
     }
 
-    protected override async _preUpdate(...args: Parameters<Combatant['_preUpdate']>): Promise<void> {
+    /** @override */
+    async _preUpdate(...args) {
       await super._preUpdate(...args);
       await this.#updateTiebreakerData(args[0]);
     }
 
-    protected override _onCreate(...args: Parameters<Combatant['_onCreate']>): void {
+    /** @override */
+    _onCreate(...args) {
       super._onCreate(...args);
       this._newInitiative = undefined;
       this._newTiebreaker = undefined;
     }
 
-    protected override _onUpdate(...args: Parameters<Combatant['_onUpdate']>): void {
+    /** @override */
+    _onUpdate(...args) {
       super._onUpdate(...args);
       this._newInitiative = undefined;
       this._newTiebreaker = undefined;
@@ -161,7 +176,16 @@ const CombatantMixin = (BaseCombatant: typeof Combatant) => {
   };
 };
 
-const defaultGetTiebreaker = async (combatant: TickwerkCombatant, combatants: TickwerkCombatant[]): Promise<number> => {
+/**
+ * A function to get a tiebreaker for a combatant
+ * @typedef {(combatant: TickwerkCombatant, combatants: TickwerkCombatant[]) => Promise<number>} GetTiebreaker
+ */
+
+/**
+ * Default implementation to get a tiebreaker for a combatant.
+ * @type {GetTiebreaker}
+ */
+const defaultGetTiebreaker = async (combatant, combatants) => {
   if (combatants.length === 0) return 0;
   const tiebreakers = combatants.map((combatant) => {
     return (
@@ -172,28 +196,3 @@ const defaultGetTiebreaker = async (combatant: TickwerkCombatant, combatants: Ti
   });
   return Math.max(...tiebreakers) + 1;
 };
-
-export type TickwerkCombatantConstructor = ReturnType<typeof CombatantMixin>;
-export type TickwerkCombatant = InstanceType<TickwerkCombatantConstructor>;
-
-declare global {
-  interface FlagConfig {
-    Combatant: {
-      tickwerk: {
-        tiebreaker?: number | undefined;
-        waiting?: boolean | undefined;
-      };
-    };
-  }
-
-  interface DocumentClassConfig {
-    Combatant: TickwerkCombatantConstructor;
-  }
-
-  interface CONFIG {
-    tickwerk?: {
-      getTiebreaker?: (combatant: TickwerkCombatant, combatants: TickwerkCombatant[]) => Promise<number>;
-      getInitiativeFormula?: (combatant: TickwerkCombatant) => string;
-    };
-  }
-}
diff --git a/src/helpers.ts b/src/helpers.js
similarity index 83%
rename from src/helpers.ts
rename to src/helpers.js
index 20c5adf..c1c1276 100644
--- a/src/helpers.ts
+++ b/src/helpers.js
@@ -2,7 +2,7 @@
 //
 // SPDX-License-Identifier: MIT
 
-export const getGame = (): Game => {
+export const getGame = () => {
   if (!(game instanceof Game)) {
     throw new Error('game is not initialized yet.');
   }
diff --git a/src/systems/ds4.ts b/src/systems/ds4.js
similarity index 62%
rename from src/systems/ds4.ts
rename to src/systems/ds4.js
index 0cffe69..c978e56 100644
--- a/src/systems/ds4.ts
+++ b/src/systems/ds4.js
@@ -5,7 +5,6 @@
 import { packageId } from '../constants';
 import { getGame } from '../helpers';
 
-import type { TickwerkCombatant } from '../data/documents/combatant';
 export const registerDS4SpecificFunctionality = () => {
   if (CONFIG.tickwerk === undefined) CONFIG.tickwerk = {};
   foundry.utils.mergeObject(CONFIG.tickwerk, { getTiebreaker, getInitiativeFormula });
@@ -14,20 +13,22 @@ export const registerDS4SpecificFunctionality = () => {
   Hooks.on('ds4.rollItem', onRollItem);
 };
 
-const getTiebreaker = async (combatant: TickwerkCombatant, combatants: TickwerkCombatant[]): Promise<number> => {
-  const ds4combatant = combatant as DS4TickwerkCombatant;
-  const ds4combatants = combatants as DS4TickwerkCombatant[];
+/** @type {import("../data/documents/combatant").GetTiebreaker} */
+const getTiebreaker = async (combatant, combatants) => {
   if (combatants.length === 0) return 0;
 
-  const lowerBounds: number[] = [];
-  const upperBounds: number[] = [];
-  const equals: number[] = [];
+  /** @type {number[]} */
+  const lowerBounds = [];
+  /** @type {number[]} */
+  const upperBounds = [];
+  /** @type {number[]} */
+  const equals = [];
 
-  for (const combatant of ds4combatants) {
-    const tiebreaker = combatant._newTiebreaker ?? combatant.getFlag(packageId, 'tiebreaker') ?? 0;
-    if (getInitiative(combatant) > getInitiative(ds4combatant)) {
+  for (const other of combatants) {
+    const tiebreaker = other._newTiebreaker ?? other.getFlag(packageId, 'tiebreaker') ?? 0;
+    if (getInitiative(other) > getInitiative(combatant)) {
       lowerBounds.push(tiebreaker);
-    } else if (getInitiative(combatant) < getInitiative(ds4combatant)) {
+    } else if (getInitiative(other) < getInitiative(combatant)) {
       upperBounds.push(tiebreaker);
     } else {
       equals.push(tiebreaker);
@@ -62,37 +63,32 @@ const getTiebreaker = async (combatant: TickwerkCombatant, combatants: TickwerkC
   }
 };
 
-const getInitiativeFormula = (combatant: TickwerkCombatant) => {
+/**
+ * Get the initiative formula for a combatant.
+ * @param {TickwerkCombatant} combatant The combatant for which to get the initiative formula
+ * @returns {string} The initiative formula
+ */
+const getInitiativeFormula = (combatant) => {
   const started = combatant.combat?.started ?? false;
   if (!started) return '-@combatValues.initiative.total';
   const tickValue = combatant.combat?.round ?? 0;
   return `max(${tickValue} + 10 - @combatValues.initiative.total, ${tickValue})`;
 };
 
-type DS4TickwerkCombatant = TickwerkCombatant & { actor: (Actor & { data: { data: ActorData } }) | null };
-
-const getInitiative = (combatant: DS4TickwerkCombatant): number => {
-  return combatant.actor?.data.data.combatValues.initiative.total ?? -Infinity;
+/**
+ * Get the initiative for a combatant.
+ * @param {TickwerkCombatant} combatant The combatant for which to get the initiative
+ * @returns {number}
+ */
+const getInitiative = (combatant) => {
+  return combatant.actor?.system.combatValues.initiative.total ?? -Infinity;
 };
 
-interface ActorData {
-  combatValues: {
-    initiative: {
-      total: number;
-    };
-  };
-}
-
-declare global {
-  // eslint-disable-next-line @typescript-eslint/no-namespace
-  namespace Hooks {
-    interface StaticCallbacks {
-      'ds4.rollItem': (item: Item) => void;
-    }
-  }
-}
-
-const onRollItem = (item: Item) => {
+/**
+ * React to an item roll by prompting the user to advance ticks.
+ * @param {Item} item The item that has been rolled
+ */
+const onRollItem = (item) => {
   const game = getGame();
   if (game.settings.get(packageId, 'ds4.reactToRollItemHook')) {
     if (['weapon', 'spell'].includes(item.type) && item.actor?.id) {
diff --git a/src/systems/index.ts b/src/systems/index.js
similarity index 100%
rename from src/systems/index.ts
rename to src/systems/index.js
diff --git a/src/tickwerk.ts b/src/tickwerk.js
similarity index 100%
rename from src/tickwerk.ts
rename to src/tickwerk.js
diff --git a/template.json b/template.json
deleted file mode 100644
index f37c11e..0000000
--- a/template.json
+++ /dev/null
@@ -1,225 +0,0 @@
-{
-  "Actor": {
-    "types": ["character", "creature"],
-    "templates": {
-      "base": {
-        "attributes": {
-          "body": {
-            "base": 0,
-            "mod": 0
-          },
-          "mobility": {
-            "base": 0,
-            "mod": 0
-          },
-          "mind": {
-            "base": 0,
-            "mod": 0
-          }
-        },
-        "traits": {
-          "strength": {
-            "base": 0,
-            "mod": 0
-          },
-          "constitution": {
-            "base": 0,
-            "mod": 0
-          },
-          "agility": {
-            "base": 0,
-            "mod": 0
-          },
-          "dexterity": {
-            "base": 0,
-            "mod": 0
-          },
-          "intellect": {
-            "base": 0,
-            "mod": 0
-          },
-          "aura": {
-            "base": 0,
-            "mod": 0
-          }
-        },
-        "combatValues": {
-          "hitPoints": {
-            "mod": 0,
-            "value": 0
-          },
-          "defense": {
-            "mod": 0
-          },
-          "initiative": {
-            "mod": 0
-          },
-          "movement": {
-            "mod": 0
-          },
-          "meleeAttack": {
-            "mod": 0
-          },
-          "rangedAttack": {
-            "mod": 0
-          },
-          "spellcasting": {
-            "mod": 0
-          },
-          "targetedSpellcasting": {
-            "mod": 0
-          }
-        }
-      }
-    },
-    "creature": {
-      "templates": ["base"],
-      "baseInfo": {
-        "loot": "",
-        "foeFactor": 1,
-        "creatureType": "humanoid",
-        "sizeCategory": "normal",
-        "experiencePoints": 0,
-        "description": ""
-      }
-    },
-    "character": {
-      "templates": ["base"],
-      "baseInfo": {
-        "race": "",
-        "class": "",
-        "heroClass": "",
-        "culture": ""
-      },
-      "progression": {
-        "level": 0,
-        "experiencePoints": 0,
-        "talentPoints": {
-          "total": 0,
-          "used": 0
-        },
-        "progressPoints": {
-          "total": 0,
-          "used": 0
-        }
-      },
-      "profile": {
-        "biography": "",
-        "gender": "",
-        "birthday": "",
-        "birthplace": "",
-        "age": 0,
-        "height": 0,
-        "hairColor": "",
-        "weight": 0,
-        "eyeColor": "",
-        "specialCharacteristics": ""
-      },
-      "currency": {
-        "gold": 0,
-        "silver": 0,
-        "copper": 0
-      },
-      "slayerPoints": {
-        "value": 0
-      }
-    }
-  },
-  "Item": {
-    "types": [
-      "weapon",
-      "armor",
-      "shield",
-      "spell",
-      "equipment",
-      "loot",
-      "talent",
-      "racialAbility",
-      "language",
-      "alphabet",
-      "specialCreatureAbility"
-    ],
-    "templates": {
-      "base": {
-        "description": ""
-      },
-      "physical": {
-        "quantity": 1,
-        "price": 0,
-        "availability": "unset",
-        "storageLocation": "-"
-      },
-      "equipable": {
-        "equipped": false
-      },
-      "protective": {
-        "armorValue": 0
-      }
-    },
-    "weapon": {
-      "templates": ["base", "physical", "equipable"],
-      "attackType": "melee",
-      "weaponBonus": 0,
-      "opponentDefense": 0
-    },
-    "armor": {
-      "templates": ["base", "physical", "equipable", "protective"],
-      "armorMaterialType": "cloth",
-      "armorType": "body"
-    },
-    "shield": {
-      "templates": ["base", "physical", "equipable", "protective"]
-    },
-    "spell": {
-      "templates": ["base", "equipable"],
-      "spellType": "spellcasting",
-      "bonus": "",
-      "spellCategory": "unset",
-      "maxDistance": {
-        "value": "",
-        "unit": "meter"
-      },
-      "effectRadius": {
-        "value": "",
-        "unit": "meter"
-      },
-      "duration": {
-        "value": "",
-        "unit": "custom"
-      },
-      "cooldownDuration": "0r",
-      "minimumLevels": {
-        "healer": null,
-        "wizard": null,
-        "sorcerer": null
-      }
-    },
-    "equipment": {
-      "templates": ["base", "physical", "equipable"]
-    },
-    "loot": {
-      "templates": ["base", "physical"]
-    },
-    "talent": {
-      "templates": ["base"],
-      "rank": {
-        "base": 0,
-        "max": 0,
-        "mod": 0
-      }
-    },
-    "racialAbility": {
-      "templates": ["base"]
-    },
-    "language": {
-      "templates": ["base"]
-    },
-    "alphabet": {
-      "templates": ["base"]
-    },
-    "specialCreatureAbility": {
-      "templates": ["base"],
-      "experiencePoints": 0
-    }
-  }
-}
diff --git a/template.json.license b/template.json.license
deleted file mode 100644
index ff79d3f..0000000
--- a/template.json.license
+++ /dev/null
@@ -1,6 +0,0 @@
-SPDX-FileCopyrightText: 2021 Johannes Loher
-SPDX-FileCopyrightText: 2021 Oliver Rümpelein
-SPDX-FileCopyrightText: 2021 Gesina Schwalbe
-SPDX-FileCopyrightText: 2021 Siegfried Krug
-
-SPDX-License-Identifier: MIT
diff --git a/templates/combat-tracker.hbs b/templates/combat-tracker.hbs
index 6c74ff3..9772de4 100644
--- a/templates/combat-tracker.hbs
+++ b/templates/combat-tracker.hbs
@@ -5,82 +5,89 @@ SPDX-FileCopyrightText: 2022 Johannes Loher
 SPDX-License-Identifier: MIT
 --}}
 
-<section class="tab sidebar-tab directory flexcol" id="combat" data-tab="combat">
-    <header id="combat-round">
+<section class="{{cssClass}} directory flexcol" id="{{cssId}}" data-tab="{{tabName}}">
+    <header class="combat-tracker-header">
         {{#if user.isGM}}
-        <nav class="encounters flexrow">
-            <a class="combat-create" title="{{localize 'COMBAT.Create'}}">
+        <nav class="encounters flexrow" aria-label="COMBAT.NavLabel">
+            <a class="combat-button combat-create" data-tooltip="COMBAT.Create">
                 <i class="fas fa-plus"></i>
             </a>
             {{#if combatCount}}
-            <a class="combat-cycle" title="{{localize 'COMBAT.EncounterPrevious'}}"
-               {{#if previousId}}data-combat-id="{{previousId}}"{{else}}disabled{{/if}}>
+            <a class="combat-button combat-cycle" data-tooltip="COMBAT.EncounterPrevious"
+               {{#if previousId}}data-document-id="{{previousId}}"{{else}}disabled{{/if}}>
                 <i class="fas fa-caret-left"></i>
             </a>
             <h4 class="encounter">{{localize "COMBAT.Encounter"}} {{currentIndex}} / {{combatCount}}</h4>
-            <a class="combat-cycle" title="{{localize 'COMBAT.EncounterNext'}}"
-               {{#if nextId}}data-combat-id="{{nextId}}"{{else}}disabled{{/if}}>
+            <a class="combat-button combat-cycle" data-tooltip="COMBAT.EncounterNext"
+               {{#if nextId}}data-document-id="{{nextId}}"{{else}}disabled{{/if}}>
                 <i class="fas fa-caret-right"></i>
             </a>
             {{/if}}
-            <a class="combat-control" title="{{localize 'COMBAT.Delete'}}" data-control="endCombat" {{#unless combatCount}}disabled{{/unless}}>
+            <a class="combat-button combat-control" data-tooltip="COMBAT.Delete" data-control="endCombat" {{#unless combatCount}}disabled{{/unless}}>
                 <i class="fas fa-trash"></i>
             </a>
         </nav>
         {{/if}}
 
-        <nav class="encounters flexrow {{#if hasCombat}}combat{{/if}}">
+        <div class="encounter-controls flexrow {{#if hasCombat}}combat{{/if}}">
             {{#if user.isGM}}
-            <a class="combat-control" title="{{localize 'COMBAT.RollAll'}}" data-control="rollAll" {{#unless turns}}disabled{{/unless}}>
+            <a class="combat-button combat-control" data-tooltip="COMBAT.RollAll" data-control="rollAll" {{#unless turns}}disabled{{/unless}}>
                 <i class="fas fa-users"></i>
             </a>
-            <a class="combat-control" title="{{localize 'COMBAT.RollNPC'}}" data-control="rollNPC" {{#unless turns}}disabled{{/unless}}>
+            <a class="combat-button combat-control" data-tooltip="COMBAT.RollNPC" data-control="rollNPC" {{#unless turns}}disabled{{/unless}}>
                 <i class="fas fa-users-cog"></i>
             </a>
             {{/if}}
 
             {{#if combatCount}}
             {{#if combat.started}}
-            <h3 class="encounter-title">{{localize 'TICKWERK.Tick'}} {{combat.tickValue}}</h3>
+            <h3 class="encounter-title noborder">{{localize 'TICKWERK.Tick'}} {{combat.tickValue}}</h3>
             {{else}}
-            <h3 class="encounter-title">{{localize 'COMBAT.NotStarted'}}</h3>
+            <h3 class="encounter-title noborder">{{localize 'COMBAT.NotStarted'}}</h3>
             {{/if}}
             {{else}}
-            <h3 class="encounter-title">{{localize "COMBAT.None"}}</h3>
+            <h3 class="encounter-title noborder">{{localize "COMBAT.None"}}</h3>
             {{/if}}
 
             {{#if user.isGM}}
-            <a class="combat-control" title="{{localize 'COMBAT.InitiativeReset'}}" data-control="resetAll"
+            <a class="combat-button combat-control" data-tooltip="COMBAT.InitiativeReset" data-control="resetAll"
                 {{#unless hasCombat}}disabled{{/unless}}>
                 <i class="fas fa-undo"></i>
             </a>
-            <a class="combat-control" title="{{labels.scope}}"
+            <a class="combat-button combat-control" data-tooltip="{{labels.scope}}"
                 data-control="toggleSceneLink" {{#unless hasCombat}}disabled{{/unless}}>
                 <i class="fas fa-{{#unless linked}}un{{/unless}}link"></i>
             </a>
-            <a class="combat-settings" title="{{localize 'COMBAT.Settings'}}" data-control="trackerSettings">
+            <a class="combat-button combat-settings" data-tooltip="COMBAT.Settings" data-control="trackerSettings">
                 <i class="fas fa-cog"></i>
             </a>
             {{/if}}
-        </nav>
+        </div>
     </header>
 
     <ol id="combat-tracker" class="directory-list">
         {{#each turns}}
         <li class="combatant actor directory-item flexrow {{this.css}}" data-combatant-id="{{this.id}}">
-            <img class="token-image" data-src="{{this.img}}" title="{{this.name}}"/>
+            <img class="token-image" data-src="{{this.img}}" alt="{{this.name}}"/>
             <div class="token-name flexcol">
                 <h4>{{this.name}}</h4>
                 <div class="combatant-controls flexrow">
                     {{#if (or ../user.isGM (and ../control this.owner))}}
-                    <a class="combatant-control" title="{{#if this.waiting}}{{localize 'TICKWERK.StopWaiting'}}{{else}}{{localize 'TICKWERK.Wait'}}{{/if}}" data-control="toggleWaiting">
+                    <a class="combatant-control" data-tooltip="{{#if this.waiting}}TICKWERK.StopWaiting{{else}}TICKWERK.Wait{{/if}}" data-control="toggleWaiting">
                         <i class="fas {{#if this.waiting}}fa-play-circle{{else}}fa-pause-circle{{/if}}"></i></a>
                     {{/if}}
                     {{#if ../user.isGM}}
-                    <a class="combatant-control {{#if this.hidden}}active{{/if}}" title="{{localize 'COMBAT.ToggleVis'}}" data-control="toggleHidden">
-                        <i class="fas fa-eye-slash"></i></a>
-                    <a class="combatant-control {{#if this.defeated}}active{{/if}}" title="{{localize 'COMBAT.ToggleDead'}}" data-control="toggleDefeated">
-                        <i class="fas fa-skull"></i></a>
+                    <a class="combatant-control {{#if this.hidden}}active{{/if}}" data-tooltip="COMBAT.ToggleVis" data-control="toggleHidden">
+                        <i class="fas fa-eye-slash"></i>
+                    </a>
+                    <a class="combatant-control {{#if this.defeated}}active{{/if}}" data-tooltip="COMBAT.ToggleDead" data-control="toggleDefeated">
+                        <i class="fas fa-skull"></i>
+                    </a>
+                    {{/if}}
+                    {{#if this.canPing}}
+                    <a class="combatant-control" data-tooltip="COMBAT.PingCombatant" data-control="pingCombatant">
+                        <i class="fa-solid fa-bullseye-arrow"></i>
+                    </a>
                     {{/if}}
                     <div class="token-effects">
                         {{#each this.effects}}
@@ -100,25 +107,25 @@ SPDX-License-Identifier: MIT
                 {{#if this.hasRolled}}
                 <span class="initiative">{{#if this.waiting}}{{localize "TICKWERK.Waiting"}}{{else}}{{this.initiative}}{{/if}}</span>
                 {{else if this.owner}}
-                <a class="combatant-control roll" title="{{localize 'COMBAT.InitiativeRoll'}}" data-control="rollInitiative"></a>
+                <a class="combatant-control roll" data-tooltip="COMBAT.InitiativeRoll" data-control="rollInitiative"></a>
                 {{/if}}
             </div>
         </li>
         {{/each}}
     </ol>
 
-    <nav id="combat-controls" class="directory-footer flexrow">
+    <nav id="combat-controls" class="directory-footer flexrow" data-tooltip-direction="UP">
     {{#if hasCombat}}
         {{#if user.isGM}}
             {{#if combat.started}}
-            <a class="combat-control center" title="{{localize 'COMBAT.End'}}" data-control="endCombat">{{localize 'COMBAT.End'}}</a>
-            <a class="combat-control" title="{{localize 'COMBAT.TurnNext'}}" data-control="nextTurn"><i class="fas fa-arrow-right"></i></a>
+            <a class="combat-control center" data-control="endCombat">{{localize 'COMBAT.End'}}</a>
+            <a class="combat-control" data-tooltip="COMBAT.TurnNext" data-control="nextTurn"><i class="fas fa-arrow-right"></i></a>
             {{else}}
-            <a class="combat-control center" title="{{localize 'COMBAT.Begin'}}" data-control="startCombat">{{localize 'COMBAT.Begin'}}</a>
+            <a class="combat-control center" data-control="startCombat">{{localize 'COMBAT.Begin'}}</a>
             {{/if}}
         {{else if (and control combat.started)}}
-        <a class="combat-control center" title="{{localize 'COMBAT.TurnEnd'}}" data-control="nextTurn">{{localize 'COMBAT.TurnEnd'}}</a>
-        <a class="combat-control" title="{{localize 'COMBAT.TurnNext'}}" data-control="nextTurn"><i class="fas fa-arrow-right"></i></a>
+        <a class="combat-control center" data-control="nextTurn">{{localize 'COMBAT.TurnEnd'}}</a>
+        <a class="combat-control" data-tooltip="COMBAT.TurnNext" data-control="nextTurn"><i class="fas fa-arrow-right"></i></a>
         {{/if}}
     {{/if}}
     </nav>
diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json
deleted file mode 100644
index 42fe594..0000000
--- a/tsconfig.eslint.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "extends": "./tsconfig.json",
-  "include": ["src", "*.js"]
-}
diff --git a/tsconfig.eslint.json.license b/tsconfig.eslint.json.license
deleted file mode 100644
index 31803f3..0000000
--- a/tsconfig.eslint.json.license
+++ /dev/null
@@ -1,3 +0,0 @@
-SPDX-FileCopyrightText: 2021 Johannes Loher
-
-SPDX-License-Identifier: MIT
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
deleted file mode 100644
index 6f173c9..0000000
--- a/tsconfig.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "compilerOptions": {
-    "target": "ES2021",
-    "lib": ["ES2021", "DOM"],
-    "types": ["@league-of-foundry-developers/foundry-vtt-types"],
-    "esModuleInterop": true,
-    "moduleResolution": "node",
-    "forceConsistentCasingInFileNames": true,
-    "strict": true,
-    "noUncheckedIndexedAccess": true,
-    "noImplicitOverride": true,
-    "resolveJsonModule": true,
-    "importsNotUsedAsValues": "error"
-  },
-  "include": ["src"]
-}
diff --git a/yarn.lock b/yarn.lock
index 540f9cb..1955895 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -342,22 +342,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@league-of-foundry-developers/foundry-vtt-types@npm:9.280.0":
-  version: 9.280.0
-  resolution: "@league-of-foundry-developers/foundry-vtt-types@npm:9.280.0"
-  dependencies:
-    "@pixi/graphics-smooth": 0.0.22
-    "@types/jquery": ~3.5.9
-    "@types/simple-peer": ~9.11.1
-    handlebars: 4.7.7
-    pixi-particles: 4.3.1
-    pixi.js: 5.3.11
-    socket.io-client: 4.3.2
-    tinymce: 5.10.1
-  checksum: 18fd05ff3fbdd849842f207e043e1924384bcd82ab65546067aa9b50d717e43dc4626822c8b96749cd687c2138cd7a7b39ac0b5fd453228876cbfa2f660f88f3
-  languageName: node
-  linkType: hard
-
 "@nodelib/fs.scandir@npm:2.1.5":
   version: 2.1.5
   resolution: "@nodelib/fs.scandir@npm:2.1.5"
@@ -405,484 +389,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@pixi/accessibility@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/accessibility@npm:5.3.11"
-  dependencies:
-    "@pixi/core": 5.3.11
-    "@pixi/display": 5.3.11
-    "@pixi/utils": 5.3.11
-  checksum: e64407bd08d472ccee9896aac21768cf5bad6fe52b75af4e7758168a153bd767c0e3e9959e646c86901acae77e9dfe4c05059075b5841000b7a2de50dd2d7083
-  languageName: node
-  linkType: hard
-
-"@pixi/app@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/app@npm:5.3.11"
-  dependencies:
-    "@pixi/core": 5.3.11
-    "@pixi/display": 5.3.11
-  checksum: c4fce95715380fe8fcea99c92e1f0a2e98a172b3e6ac691d658b31d5a950bafd23753e982106e8be08c5db4b7872df156ea779f47f15b7fb2afdbef40dc3fa56
-  languageName: node
-  linkType: hard
-
-"@pixi/constants@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/constants@npm:5.3.11"
-  checksum: ed23c735858a3a506ece0bea1afb3fac2ba261cb9722f17b15e9a4dcc8f70f3906a7cb90c94c255e7e7ece62d3447e68462975c3a30d2cb908f3632b4f97a891
-  languageName: node
-  linkType: hard
-
-"@pixi/constants@npm:6.2.1":
-  version: 6.2.1
-  resolution: "@pixi/constants@npm:6.2.1"
-  checksum: 16ce671884932afec41258891f301b9b725a4ae6285a39940b83ebd026a0dd077c78962b7f75eb6afba14a38de2420b0cfeaeae7986bbea4991506a4a83076b7
-  languageName: node
-  linkType: hard
-
-"@pixi/core@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/core@npm:5.3.11"
-  dependencies:
-    "@pixi/constants": 5.3.11
-    "@pixi/math": 5.3.11
-    "@pixi/runner": 5.3.11
-    "@pixi/settings": 5.3.11
-    "@pixi/ticker": 5.3.11
-    "@pixi/utils": 5.3.11
-  checksum: 865f26fa07397f67c0b418b7844576adff49aea47e4548b6122541c92da15744d128c681eb0c11c584906ba269485f816a8c0e0a4d6cb5521a2a488dfe4cfb40
-  languageName: node
-  linkType: hard
-
-"@pixi/core@npm:6.2.1":
-  version: 6.2.1
-  resolution: "@pixi/core@npm:6.2.1"
-  peerDependencies:
-    "@pixi/constants": 6.2.1
-    "@pixi/math": 6.2.1
-    "@pixi/runner": 6.2.1
-    "@pixi/settings": 6.2.1
-    "@pixi/ticker": 6.2.1
-    "@pixi/utils": 6.2.1
-  checksum: 946b39bd4a1e1414e2f6d60f9df1d56625312f482cf5a095ddb276554a351ebb0ebb8a0e98c7f98100eedecef89d1579b02e79b77626f1fe47e619aaffc3d469
-  languageName: node
-  linkType: hard
-
-"@pixi/display@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/display@npm:5.3.11"
-  dependencies:
-    "@pixi/math": 5.3.11
-    "@pixi/settings": 5.3.11
-    "@pixi/utils": 5.3.11
-  checksum: 83db7f10fe610104bca5b71031abe3dfdd8946fd4e1a3957f2f9c1ca61ebbd3b7ab04915e9ced78997b88817063da42ae7c5aea527ad70959eb320966f70f92b
-  languageName: node
-  linkType: hard
-
-"@pixi/display@npm:6.2.1":
-  version: 6.2.1
-  resolution: "@pixi/display@npm:6.2.1"
-  peerDependencies:
-    "@pixi/math": 6.2.1
-    "@pixi/settings": 6.2.1
-    "@pixi/utils": 6.2.1
-  checksum: b72d4f16fd4c27e03d34c5cd8490cbd2c5d507584cef3abbab329fc1575ed5bcc53e104fb063c35fb6e85a6f8e16e1c114f1ff599ad43b7d1e4797fd644639fe
-  languageName: node
-  linkType: hard
-
-"@pixi/extract@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/extract@npm:5.3.11"
-  dependencies:
-    "@pixi/core": 5.3.11
-    "@pixi/math": 5.3.11
-    "@pixi/utils": 5.3.11
-  checksum: 15d68bed15e29c4d49f39bc33c9097b05eeb7b374a6a1f54177eaf0079e9882e4d96e3cbf61951ab6474b458fcdc36010de776ef7eeaaf9505464bfff89498e4
-  languageName: node
-  linkType: hard
-
-"@pixi/filter-alpha@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/filter-alpha@npm:5.3.11"
-  dependencies:
-    "@pixi/core": 5.3.11
-  checksum: c5348cc46125f443effd41ed46ccd8312b8a797fad5898ca3460d1c2f2146287881f8b18d1953b444cca6969ad1cbf60792c9d84434cc396e147bcc57f7a9d01
-  languageName: node
-  linkType: hard
-
-"@pixi/filter-blur@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/filter-blur@npm:5.3.11"
-  dependencies:
-    "@pixi/core": 5.3.11
-    "@pixi/settings": 5.3.11
-  checksum: ff28b39f63c63cc9cb16d566ffb1543272830f3f566b677da22f47ad211ad594359fb07504280d80f9a7bfd1818409cf3cd9563c689057731d7e0fd105a3f988
-  languageName: node
-  linkType: hard
-
-"@pixi/filter-color-matrix@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/filter-color-matrix@npm:5.3.11"
-  dependencies:
-    "@pixi/core": 5.3.11
-  checksum: 5f76a7de0f9935fa16cbb66a18b430fa73a71d787f55334c2ba538bc58b11339ee0bfed0ccbe53c7693d6110fad5e88cb569af973849328b307e5314717130e7
-  languageName: node
-  linkType: hard
-
-"@pixi/filter-displacement@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/filter-displacement@npm:5.3.11"
-  dependencies:
-    "@pixi/core": 5.3.11
-    "@pixi/math": 5.3.11
-  checksum: 03436312e1dd860accd6c801feea8d0a868e5b90de8c49edc28d40cf71ba4da293b4c027d0a71897c9aec884db132cb4c7d22fd18a05da5248e4ab35fccd0df9
-  languageName: node
-  linkType: hard
-
-"@pixi/filter-fxaa@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/filter-fxaa@npm:5.3.11"
-  dependencies:
-    "@pixi/core": 5.3.11
-  checksum: 02a16119e4796e9d1bf01768358cc244c24d71d22e229b5eec9b31968771a07d0fdf11196de7b59d34b9c075245d16b3c794b0eb02fc7e5e27b22e703ea0ed27
-  languageName: node
-  linkType: hard
-
-"@pixi/filter-noise@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/filter-noise@npm:5.3.11"
-  dependencies:
-    "@pixi/core": 5.3.11
-  checksum: 7d27c5af18a096418ced42f9f668577db39e4b30c7fad540d7ba31fd8a59c16d8926680ff6c3523c3e4b2a9fc4a7b46694dc0d547863cdf2763b28dac4c06455
-  languageName: node
-  linkType: hard
-
-"@pixi/graphics-smooth@npm:0.0.22":
-  version: 0.0.22
-  resolution: "@pixi/graphics-smooth@npm:0.0.22"
-  peerDependencies:
-    "@pixi/constants": ^6.0.4
-    "@pixi/core": ^6.0.4
-    "@pixi/display": ^6.0.4
-    "@pixi/graphics": ^6.0.4
-    "@pixi/math": ^6.0.4
-    "@pixi/utils": ^6.0.4
-  checksum: 81dea3626180b4c7997b20ba6611d41e7a79d6278f71f65867e440d73577e13569c574a31623f5732d08d60beef867eb99f4ca79e34ca8ffb6755fe00a4d8508
-  languageName: node
-  linkType: hard
-
-"@pixi/graphics@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/graphics@npm:5.3.11"
-  dependencies:
-    "@pixi/constants": 5.3.11
-    "@pixi/core": 5.3.11
-    "@pixi/display": 5.3.11
-    "@pixi/math": 5.3.11
-    "@pixi/sprite": 5.3.11
-    "@pixi/utils": 5.3.11
-  checksum: 31014dd5b9b05dd6d048a6a74c261f5e368b0e558aceaf21a90df38b321495b75f5caf2fe7e148fbad25b5db2998a76c66f816a4247d4e8d6c222a8b740b14b4
-  languageName: node
-  linkType: hard
-
-"@pixi/graphics@npm:6.2.1":
-  version: 6.2.1
-  resolution: "@pixi/graphics@npm:6.2.1"
-  peerDependencies:
-    "@pixi/constants": 6.2.1
-    "@pixi/core": 6.2.1
-    "@pixi/display": 6.2.1
-    "@pixi/math": 6.2.1
-    "@pixi/sprite": 6.2.1
-    "@pixi/utils": 6.2.1
-  checksum: 08681899d3177784126bb91b4e0c7966ad92e28d90f626c7c9c4a1973f4dc70cf43a9843d49133431db60ea9fbea4cfa86afab8391a57612a3bdee164aedcc31
-  languageName: node
-  linkType: hard
-
-"@pixi/interaction@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/interaction@npm:5.3.11"
-  dependencies:
-    "@pixi/core": 5.3.11
-    "@pixi/display": 5.3.11
-    "@pixi/math": 5.3.11
-    "@pixi/ticker": 5.3.11
-    "@pixi/utils": 5.3.11
-  checksum: 2dc86690b85a614d062fe33dd1607ecb920e491bbb8822e28afef48ff745de1aa796b144225f887f6c391a96ab98c760e4b2081f621d9ccebdf59b4d63b9ded5
-  languageName: node
-  linkType: hard
-
-"@pixi/loaders@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/loaders@npm:5.3.11"
-  dependencies:
-    "@pixi/core": 5.3.11
-    "@pixi/utils": 5.3.11
-    resource-loader: ^3.0.1
-  checksum: 032e111c2dee5fdd26388ab95695f1800f9892ceb286248c4543d3b94b412390c6aa77d5f7b3118ae93a99b97b27db6b41e5459c67229cb5c22fcf3ef5f798c9
-  languageName: node
-  linkType: hard
-
-"@pixi/math@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/math@npm:5.3.11"
-  checksum: 594557c1620ccee3e643b780cd66c0e0a01f4e2513d01e1f97fc9297cc8cdd9f0371360d578a6e16d8c4ee3d852a7770bbfcd26cc12f8c38f7d8a82b81dd76ec
-  languageName: node
-  linkType: hard
-
-"@pixi/math@npm:6.2.1":
-  version: 6.2.1
-  resolution: "@pixi/math@npm:6.2.1"
-  checksum: 20ed1d294bb49c7a6f16dcd73e7befee97c15a5cc0127c120ec868bd5116039f9c5e13f05c19cdfedfffdf91625e10f27ccc51f96d54ad002d0a15102549f8ab
-  languageName: node
-  linkType: hard
-
-"@pixi/mesh-extras@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/mesh-extras@npm:5.3.11"
-  dependencies:
-    "@pixi/constants": 5.3.11
-    "@pixi/core": 5.3.11
-    "@pixi/math": 5.3.11
-    "@pixi/mesh": 5.3.11
-    "@pixi/utils": 5.3.11
-  checksum: 8c8188be1c978670f7c06b6de85d1d18b93eca321f17611830e88157958b40ac888490cf20a33e2fe3a85e57f0b654e7208dea3a4aa340330f1eb4a4c6029c7e
-  languageName: node
-  linkType: hard
-
-"@pixi/mesh@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/mesh@npm:5.3.11"
-  dependencies:
-    "@pixi/constants": 5.3.11
-    "@pixi/core": 5.3.11
-    "@pixi/display": 5.3.11
-    "@pixi/math": 5.3.11
-    "@pixi/settings": 5.3.11
-    "@pixi/utils": 5.3.11
-  checksum: 161748cd29cd8522254577f556d0dde09198f17ff0fd5abc78aeea173f281c73cd4816eed134cab69a6ec41b0909cbdeb7c513aae696815605cdb67b8cc2e367
-  languageName: node
-  linkType: hard
-
-"@pixi/mixin-cache-as-bitmap@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/mixin-cache-as-bitmap@npm:5.3.11"
-  dependencies:
-    "@pixi/core": 5.3.11
-    "@pixi/display": 5.3.11
-    "@pixi/math": 5.3.11
-    "@pixi/settings": 5.3.11
-    "@pixi/sprite": 5.3.11
-    "@pixi/utils": 5.3.11
-  checksum: ea0999df8da2373f1617ad0d1f72e6f95d3d7501aad2f4808adf781d9df4d2b31540ad43d599b709872c0e6af9489d8531274153eaca5fa105173b6666057580
-  languageName: node
-  linkType: hard
-
-"@pixi/mixin-get-child-by-name@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/mixin-get-child-by-name@npm:5.3.11"
-  dependencies:
-    "@pixi/display": 5.3.11
-  checksum: 3c8d852728d0fb311923ac641cabefb31dcb31d2184e3ff6d6a152b7b662fce477c4f209f1a1947a086e46f59f44089072ef5c6d9798de016bd116b7502640f9
-  languageName: node
-  linkType: hard
-
-"@pixi/mixin-get-global-position@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/mixin-get-global-position@npm:5.3.11"
-  dependencies:
-    "@pixi/display": 5.3.11
-    "@pixi/math": 5.3.11
-  checksum: 2be4698114f7061758efe3e2dad93a0216dfacf5cba4d20dc11105b55a4e69f26ef0d84c11d9670f157da11e235eb501d51018188176fd10c42955e7bf95bae0
-  languageName: node
-  linkType: hard
-
-"@pixi/particles@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/particles@npm:5.3.11"
-  dependencies:
-    "@pixi/constants": 5.3.11
-    "@pixi/core": 5.3.11
-    "@pixi/display": 5.3.11
-    "@pixi/math": 5.3.11
-    "@pixi/utils": 5.3.11
-  checksum: 2b866a2998f6295f88b21451a1088a9d32f75bd5c3cdae10bff5a47bc6846ff69ac7e07db87a3346b6dbfc1c49fb5e4ea0df69aebd815f2fa5a4f43e49c89a17
-  languageName: node
-  linkType: hard
-
-"@pixi/polyfill@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/polyfill@npm:5.3.11"
-  dependencies:
-    es6-promise-polyfill: ^1.2.0
-    object-assign: ^4.1.1
-  checksum: b9e69c974eab3ecba755c0b10c776aa6aac40eafec459fd205a786d1abbcf77c5ae05c6cde9381bc5d99830c284bfb746c56b09aedd4bed367063d3183b4722c
-  languageName: node
-  linkType: hard
-
-"@pixi/prepare@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/prepare@npm:5.3.11"
-  dependencies:
-    "@pixi/core": 5.3.11
-    "@pixi/display": 5.3.11
-    "@pixi/graphics": 5.3.11
-    "@pixi/settings": 5.3.11
-    "@pixi/text": 5.3.11
-    "@pixi/ticker": 5.3.11
-  checksum: eeb13f4c2eaff00f990e5f9d55593334a04a72ee1edf120b2b626e429e8e260514c371fc69dc87ee1c61355d9a6310d3daf56ec772ca1cd5976c2d94047e0552
-  languageName: node
-  linkType: hard
-
-"@pixi/runner@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/runner@npm:5.3.11"
-  checksum: decbf8853a5634b3de2260321b813e5165ac23ff1eb1431ad50e69a0531d04fadd4693f80c0c1e0673380b15376b7840407ebafe404b95247c8d9187978f1de2
-  languageName: node
-  linkType: hard
-
-"@pixi/runner@npm:6.2.1":
-  version: 6.2.1
-  resolution: "@pixi/runner@npm:6.2.1"
-  checksum: 786cc632c5cf0001a74eb0621225048b7bec2fd37c65cd783e0dcff87a418a271f5b83a349c1171d546f78c41b91f05f89db3300a6ce78bee18ce403cdbb9ee5
-  languageName: node
-  linkType: hard
-
-"@pixi/settings@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/settings@npm:5.3.11"
-  dependencies:
-    ismobilejs: ^1.1.0
-  checksum: b45a10c0a556b3737f9b0442364635d36c8dfd351337f55829e4049e6f120ad5c201b242eb49c17a817c3348b085b7506e00438c0169c2951a9b7dba94ddc497
-  languageName: node
-  linkType: hard
-
-"@pixi/settings@npm:6.2.1":
-  version: 6.2.1
-  resolution: "@pixi/settings@npm:6.2.1"
-  dependencies:
-    ismobilejs: ^1.1.0
-  checksum: f4db5bd74fca1f6c78153d4e86ae2a7961e929086543190cc8d923abfd35fb973eac61c3d722c2c753d30028a0d6c49a96fccd74f510636aa5a05afa3fda107d
-  languageName: node
-  linkType: hard
-
-"@pixi/sprite-animated@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/sprite-animated@npm:5.3.11"
-  dependencies:
-    "@pixi/core": 5.3.11
-    "@pixi/sprite": 5.3.11
-    "@pixi/ticker": 5.3.11
-  checksum: e821e5882961e5e65abe950f7d3600622a76b5f188b83280d1dbb2d9434847fe6a8f204cc63e1f87805ded804f3e9992f6b779d1561868df530f33c5d71da3ef
-  languageName: node
-  linkType: hard
-
-"@pixi/sprite-tiling@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/sprite-tiling@npm:5.3.11"
-  dependencies:
-    "@pixi/constants": 5.3.11
-    "@pixi/core": 5.3.11
-    "@pixi/display": 5.3.11
-    "@pixi/math": 5.3.11
-    "@pixi/sprite": 5.3.11
-    "@pixi/utils": 5.3.11
-  checksum: 2a3b82fb89a92be9413573ebe507a416485735de47d99ae4f9037cfec8619947b86fb53c4ba0d5c007d5b4e0148d8d83ffd9338a1ef2691b8c8d8dae05a77ebe
-  languageName: node
-  linkType: hard
-
-"@pixi/sprite@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/sprite@npm:5.3.11"
-  dependencies:
-    "@pixi/constants": 5.3.11
-    "@pixi/core": 5.3.11
-    "@pixi/display": 5.3.11
-    "@pixi/math": 5.3.11
-    "@pixi/settings": 5.3.11
-    "@pixi/utils": 5.3.11
-  checksum: 6e4c5f108db8d49f005e61801bf94bb12173bfefd2e0c803851530c27d31f8c0a78e60bd9f07a469e06154bf22f5f6a1da5aabf7119c9e1448534df0e42e4398
-  languageName: node
-  linkType: hard
-
-"@pixi/spritesheet@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/spritesheet@npm:5.3.11"
-  dependencies:
-    "@pixi/core": 5.3.11
-    "@pixi/loaders": 5.3.11
-    "@pixi/math": 5.3.11
-    "@pixi/utils": 5.3.11
-  checksum: a1782b7b25ed355eba78850f764189f5cc433a8cf737b9ca54bb896afb47fb66cb329dab91072e2914b3d0f981f65e4788657e5f5ac8995c3ecdfde870f29890
-  languageName: node
-  linkType: hard
-
-"@pixi/text-bitmap@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/text-bitmap@npm:5.3.11"
-  dependencies:
-    "@pixi/core": 5.3.11
-    "@pixi/display": 5.3.11
-    "@pixi/loaders": 5.3.11
-    "@pixi/math": 5.3.11
-    "@pixi/mesh": 5.3.11
-    "@pixi/settings": 5.3.11
-    "@pixi/text": 5.3.11
-    "@pixi/utils": 5.3.11
-  checksum: c901ebaf47720369e080c85065b879a1a80e725d782c43d7d4873569a73d7d5e9543cd5a8a71550c4a7dd13cf5497361f7ecd527edb5208aaf7cdc8d8d7310dd
-  languageName: node
-  linkType: hard
-
-"@pixi/text@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/text@npm:5.3.11"
-  dependencies:
-    "@pixi/core": 5.3.11
-    "@pixi/math": 5.3.11
-    "@pixi/settings": 5.3.11
-    "@pixi/sprite": 5.3.11
-    "@pixi/utils": 5.3.11
-  checksum: 583cd3534ac8682e96e55f511325ed01e817c812db92262afab03581ad82e8d7b3444ee858673236c8069af2c6c25efc166a67ef0bf3f2ef8ecedf7c1c910347
-  languageName: node
-  linkType: hard
-
-"@pixi/ticker@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/ticker@npm:5.3.11"
-  dependencies:
-    "@pixi/settings": 5.3.11
-  checksum: 45a4b6f1b43c70f09f9b050bf28afbeda155c30d33d9666a1698f6b884a376505c37b508408068f4fb74abaff61529a395d73dd64e437a376cada95f647832fe
-  languageName: node
-  linkType: hard
-
-"@pixi/utils@npm:5.3.11":
-  version: 5.3.11
-  resolution: "@pixi/utils@npm:5.3.11"
-  dependencies:
-    "@pixi/constants": 5.3.11
-    "@pixi/settings": 5.3.11
-    earcut: ^2.1.5
-    eventemitter3: ^3.1.0
-    url: ^0.11.0
-  checksum: b107c782b9c27a25a2e04e4ce12f78022a65ffb71133f4e9e7840f9cf653852d382d940635f27f284b0081692eaea39a310f1ce14d1d6ed1216e2738ac3b3f61
-  languageName: node
-  linkType: hard
-
-"@pixi/utils@npm:6.2.1":
-  version: 6.2.1
-  resolution: "@pixi/utils@npm:6.2.1"
-  dependencies:
-    "@types/earcut": ^2.1.0
-    earcut: ^2.2.2
-    eventemitter3: ^3.1.0
-    url: ^0.11.0
-  peerDependencies:
-    "@pixi/constants": 6.2.1
-    "@pixi/settings": 6.2.1
-  checksum: e324cafe80cd2ec3bcf0763cd1e6a7193b15384819af9031d7425a4d6ff8520acb143fc63f5bbc12fe0af17de458fc2eb89d3b2ddd4de5657155e35e164e0108
-  languageName: node
-  linkType: hard
-
 "@rollup/pluginutils@npm:^4.1.2, @rollup/pluginutils@npm:^4.2.1":
   version: 4.2.1
   resolution: "@rollup/pluginutils@npm:4.2.1"
@@ -893,31 +399,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@seald-io/binary-search-tree@npm:^1.0.2":
-  version: 1.0.2
-  resolution: "@seald-io/binary-search-tree@npm:1.0.2"
-  checksum: 957315cbe4c7af17a6830753e933d23fddae4620e55070a179b8c3e4582021e75a171da1094a5931be4deea41c059a5f233bd76e13689afb7c4447a8d5358be7
-  languageName: node
-  linkType: hard
-
-"@seald-io/nedb@npm:3.1.0":
-  version: 3.1.0
-  resolution: "@seald-io/nedb@npm:3.1.0"
-  dependencies:
-    "@seald-io/binary-search-tree": ^1.0.2
-    localforage: ^1.9.0
-    util: ^0.12.4
-  checksum: 081884b02756c8a623b9cc0907882e51a5c39f530ce02644af8b172fc0451c61e98d3582339d602f3102af8042303d1c3a912a625fc5e934a8b09998dfbf512c
-  languageName: node
-  linkType: hard
-
-"@socket.io/component-emitter@npm:~3.0.0":
-  version: 3.0.0
-  resolution: "@socket.io/component-emitter@npm:3.0.0"
-  checksum: b5e909dbb16bcf27958d1bfb8319f3255f3a50f62fde78ecf9a584f39f916b928fdc5661519892eea912da082c6413d671c1e67bde70725c75ee62956aa67c26
-  languageName: node
-  linkType: hard
-
 "@swc/core-darwin-arm64@npm:1.3.20":
   version: 1.3.20
   resolution: "@swc/core-darwin-arm64@npm:1.3.20"
@@ -1080,38 +561,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@types/earcut@npm:^2.1.0":
-  version: 2.1.1
-  resolution: "@types/earcut@npm:2.1.1"
-  checksum: 7845dab97ba2bf379caeb4fb91bb732e6710b0ce018a8e357f023cb96ac2fa5c64352461e93ecac2504966dcf6b0b882d117c2258cf15a679bd0063b3cee0e14
-  languageName: node
-  linkType: hard
-
-"@types/fs-extra@npm:9.0.13":
-  version: 9.0.13
-  resolution: "@types/fs-extra@npm:9.0.13"
-  dependencies:
-    "@types/node": "*"
-  checksum: add79e212acd5ac76b97b9045834e03a7996aef60a814185e0459088fd290519a3c1620865d588fa36c4498bf614210d2a703af5cf80aa1dbc125db78f6edac3
-  languageName: node
-  linkType: hard
-
-"@types/jquery@npm:~3.5.9":
-  version: 3.5.14
-  resolution: "@types/jquery@npm:3.5.14"
-  dependencies:
-    "@types/sizzle": "*"
-  checksum: 159d6f804ed1a204b3f79f2d591a271d82e866bd45bd49fb6ef40561a25dbe0f47ec7815681b44cc2db5598425f72811e7e80ab0e983d980470998ac56feb375
-  languageName: node
-  linkType: hard
-
-"@types/json-schema@npm:^7.0.9":
-  version: 7.0.11
-  resolution: "@types/json-schema@npm:7.0.11"
-  checksum: 527bddfe62db9012fccd7627794bd4c71beb77601861055d87e3ee464f2217c85fca7a4b56ae677478367bbd248dbde13553312b7d4dbc702a2f2bbf60c4018d
-  languageName: node
-  linkType: hard
-
 "@types/minimist@npm:^1.2.0":
   version: 1.2.2
   resolution: "@types/minimist@npm:1.2.2"
@@ -1119,13 +568,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@types/node@npm:*":
-  version: 18.11.9
-  resolution: "@types/node@npm:18.11.9"
-  checksum: cc0aae109e9b7adefc32eecb838d6fad931663bb06484b5e9cbbbf74865c721b03d16fd8d74ad90e31dbe093d956a7c2c306ba5429ba0c00f3f7505103d7a496
-  languageName: node
-  linkType: hard
-
 "@types/node@npm:^14.0.0":
   version: 14.18.33
   resolution: "@types/node@npm:14.18.33"
@@ -1147,149 +589,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@types/semver@npm:^7.3.12":
-  version: 7.3.13
-  resolution: "@types/semver@npm:7.3.13"
-  checksum: 00c0724d54757c2f4bc60b5032fe91cda6410e48689633d5f35ece8a0a66445e3e57fa1d6e07eb780f792e82ac542948ec4d0b76eb3484297b79bd18b8cf1cb0
-  languageName: node
-  linkType: hard
-
-"@types/simple-peer@npm:~9.11.1":
-  version: 9.11.5
-  resolution: "@types/simple-peer@npm:9.11.5"
-  dependencies:
-    "@types/node": "*"
-  checksum: f54d22cb1bfd188628078cdd9dd2884687a73e6f8eeb6851d08103be23dd178d3711d9530ed54e9930a55d9794ae7f23a7b1e2052b797f479260019a4bb48bcf
-  languageName: node
-  linkType: hard
-
-"@types/sizzle@npm:*":
-  version: 2.3.3
-  resolution: "@types/sizzle@npm:2.3.3"
-  checksum: 586a9fb1f6ff3e325e0f2cc1596a460615f0bc8a28f6e276ac9b509401039dd242fa8b34496d3a30c52f5b495873922d09a9e76c50c2ab2bcc70ba3fb9c4e160
-  languageName: node
-  linkType: hard
-
-"@typescript-eslint/eslint-plugin@npm:5.44.0":
-  version: 5.44.0
-  resolution: "@typescript-eslint/eslint-plugin@npm:5.44.0"
-  dependencies:
-    "@typescript-eslint/scope-manager": 5.44.0
-    "@typescript-eslint/type-utils": 5.44.0
-    "@typescript-eslint/utils": 5.44.0
-    debug: ^4.3.4
-    ignore: ^5.2.0
-    natural-compare-lite: ^1.4.0
-    regexpp: ^3.2.0
-    semver: ^7.3.7
-    tsutils: ^3.21.0
-  peerDependencies:
-    "@typescript-eslint/parser": ^5.0.0
-    eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
-  peerDependenciesMeta:
-    typescript:
-      optional: true
-  checksum: 88784e77e8e35ea50ca9c49d46df94cabc3447f4b332f3ca53974d3b5370cb5dcd85cc9ee0e317b91083812012369209574725dcfc3b2b4056b60371b68ca854
-  languageName: node
-  linkType: hard
-
-"@typescript-eslint/parser@npm:5.44.0":
-  version: 5.44.0
-  resolution: "@typescript-eslint/parser@npm:5.44.0"
-  dependencies:
-    "@typescript-eslint/scope-manager": 5.44.0
-    "@typescript-eslint/types": 5.44.0
-    "@typescript-eslint/typescript-estree": 5.44.0
-    debug: ^4.3.4
-  peerDependencies:
-    eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
-  peerDependenciesMeta:
-    typescript:
-      optional: true
-  checksum: 2d09a1a1547a7ae3f76c9a33a54e11d79a194fbb9dbae69988e7aed3370bdf12bafde669211152769d89db822e0cdee4173affc126664fa6f17abba56daa7261
-  languageName: node
-  linkType: hard
-
-"@typescript-eslint/scope-manager@npm:5.44.0":
-  version: 5.44.0
-  resolution: "@typescript-eslint/scope-manager@npm:5.44.0"
-  dependencies:
-    "@typescript-eslint/types": 5.44.0
-    "@typescript-eslint/visitor-keys": 5.44.0
-  checksum: 4cfe4b55eb428eda740e6b967e3a87f3e1f9c4bbd8e1d6b8d64a11666abe33ffe7a21e4e614444ccde2da6930fa85f3e0ffca43d6e339943ff7a4fbccb09c8fc
-  languageName: node
-  linkType: hard
-
-"@typescript-eslint/type-utils@npm:5.44.0":
-  version: 5.44.0
-  resolution: "@typescript-eslint/type-utils@npm:5.44.0"
-  dependencies:
-    "@typescript-eslint/typescript-estree": 5.44.0
-    "@typescript-eslint/utils": 5.44.0
-    debug: ^4.3.4
-    tsutils: ^3.21.0
-  peerDependencies:
-    eslint: "*"
-  peerDependenciesMeta:
-    typescript:
-      optional: true
-  checksum: 4c7b594f8afa52d57d0512951a874fa390eb791dcefcd0e1efff8817872293b2e4e04eff3c54d1595c1720a34d5fd315729af4e459882033d13cb6069ae9d28f
-  languageName: node
-  linkType: hard
-
-"@typescript-eslint/types@npm:5.44.0":
-  version: 5.44.0
-  resolution: "@typescript-eslint/types@npm:5.44.0"
-  checksum: ced7d32abecfc62ccb67cf27e30c0785b9c153ec7b1a05153ced58fa5a2031ab3845bc2e477b83e4cebdcc5881c5845d23053c6739c62549d41ae6208e547e85
-  languageName: node
-  linkType: hard
-
-"@typescript-eslint/typescript-estree@npm:5.44.0":
-  version: 5.44.0
-  resolution: "@typescript-eslint/typescript-estree@npm:5.44.0"
-  dependencies:
-    "@typescript-eslint/types": 5.44.0
-    "@typescript-eslint/visitor-keys": 5.44.0
-    debug: ^4.3.4
-    globby: ^11.1.0
-    is-glob: ^4.0.3
-    semver: ^7.3.7
-    tsutils: ^3.21.0
-  peerDependenciesMeta:
-    typescript:
-      optional: true
-  checksum: 758731108497cca7ff81cf0a78d086b5a85757a983979d6bb25ad8252b7acbc738c642ecb5f5df82f925a45926b9846e431d5cf9fee5ed2613300b4d0c5d6c3f
-  languageName: node
-  linkType: hard
-
-"@typescript-eslint/utils@npm:5.44.0":
-  version: 5.44.0
-  resolution: "@typescript-eslint/utils@npm:5.44.0"
-  dependencies:
-    "@types/json-schema": ^7.0.9
-    "@types/semver": ^7.3.12
-    "@typescript-eslint/scope-manager": 5.44.0
-    "@typescript-eslint/types": 5.44.0
-    "@typescript-eslint/typescript-estree": 5.44.0
-    eslint-scope: ^5.1.1
-    eslint-utils: ^3.0.0
-    semver: ^7.3.7
-  peerDependencies:
-    eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
-  checksum: bc5bb28e41898464d35b8eb47cc452103852541e3b6be56252c15a5a81c45e10aad3db4c749eb92d752b0c358df8074e23ec6f9e65f8089baadeda7f395c7e31
-  languageName: node
-  linkType: hard
-
-"@typescript-eslint/visitor-keys@npm:5.44.0":
-  version: 5.44.0
-  resolution: "@typescript-eslint/visitor-keys@npm:5.44.0"
-  dependencies:
-    "@typescript-eslint/types": 5.44.0
-    eslint-visitor-keys: ^3.3.0
-  checksum: a012c888209e1d6ae684b2a44fd460ae5a80f5faf07bca4bda6c9c0d8c063ad3297d4c53f7151ae86cf1a43dee09625dc3ee72183323c91089c7288fd573c6f4
-  languageName: node
-  linkType: hard
-
 "JSONStream@npm:^1.0.4":
   version: 1.3.5
   resolution: "JSONStream@npm:1.3.5"
@@ -1512,20 +811,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"available-typed-arrays@npm:^1.0.5":
-  version: 1.0.5
-  resolution: "available-typed-arrays@npm:1.0.5"
-  checksum: 20eb47b3cefd7db027b9bbb993c658abd36d4edd3fe1060e83699a03ee275b0c9b216cc076ff3f2db29073225fb70e7613987af14269ac1fe2a19803ccc97f1a
-  languageName: node
-  linkType: hard
-
-"backo2@npm:~1.0.2":
-  version: 1.0.2
-  resolution: "backo2@npm:1.0.2"
-  checksum: fda8d0a0f4810068d23715f2f45153146d6ee8f62dd827ce1e0b6cc3c8328e84ad61e11399a83931705cef702fe7cbb457856bf99b9bd10c4ed57b0786252385
-  languageName: node
-  linkType: hard
-
 "balanced-match@npm:^1.0.0":
   version: 1.0.2
   resolution: "balanced-match@npm:1.0.2"
@@ -2266,7 +1551,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4, debug@npm:~4.3.1, debug@npm:~4.3.2":
+"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4":
   version: 4.3.4
   resolution: "debug@npm:4.3.4"
   dependencies:
@@ -2405,13 +1690,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"earcut@npm:^2.1.5, earcut@npm:^2.2.2":
-  version: 2.2.4
-  resolution: "earcut@npm:2.2.4"
-  checksum: aea0466cb2f24e0c3c57148d8d28ac9846f53c4f43ee66780826474303ac851b305ef988152d0bdeb31e8f7ca939dc0df737e7505cfb1c1bdf2ff9d7f9ea2faa
-  languageName: node
-  linkType: hard
-
 "eastasianwidth@npm:^0.2.0":
   version: 0.2.0
   resolution: "eastasianwidth@npm:0.2.0"
@@ -2449,30 +1727,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"engine.io-client@npm:~6.0.1":
-  version: 6.0.3
-  resolution: "engine.io-client@npm:6.0.3"
-  dependencies:
-    "@socket.io/component-emitter": ~3.0.0
-    debug: ~4.3.1
-    engine.io-parser: ~5.0.0
-    has-cors: 1.1.0
-    parseqs: 0.0.6
-    parseuri: 0.0.6
-    ws: ~8.2.3
-    xmlhttprequest-ssl: ~2.0.0
-    yeast: 0.1.2
-  checksum: 11a70dba629e47981966f4b43e839327adc2444ce77d3476dcb93281712e92f972e3fdf97f2c298b3887f17d38ee609f022a470b6d2d255beccd471fa366603d
-  languageName: node
-  linkType: hard
-
-"engine.io-parser@npm:~5.0.0":
-  version: 5.0.4
-  resolution: "engine.io-parser@npm:5.0.4"
-  checksum: d4ad0cef6ff63c350e35696da9bb3dbd180f67b56e93e90375010cc40393e6c0639b780d5680807e1d93a7e2e3d7b4a1c3b27cf75db28eb8cbf605bc1497da03
-  languageName: node
-  linkType: hard
-
 "entities@npm:^2.0.0":
   version: 2.2.0
   resolution: "entities@npm:2.2.0"
@@ -2546,13 +1800,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"es6-promise-polyfill@npm:^1.2.0":
-  version: 1.2.0
-  resolution: "es6-promise-polyfill@npm:1.2.0"
-  checksum: b6022782ffdfa9c75d08e8b77580ea18908baa3c43a63f86a792d9c5cfa0c1e851de28743c44d6b5df11a8fc25f1be28bf3494bc1ff3bf9336204696897ee772
-  languageName: node
-  linkType: hard
-
 "escalade@npm:^3.1.1":
   version: 3.1.1
   resolution: "escalade@npm:3.1.1"
@@ -2600,16 +1847,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"eslint-scope@npm:^5.1.1":
-  version: 5.1.1
-  resolution: "eslint-scope@npm:5.1.1"
-  dependencies:
-    esrecurse: ^4.3.0
-    estraverse: ^4.1.1
-  checksum: 47e4b6a3f0cc29c7feedee6c67b225a2da7e155802c6ea13bbef4ac6b9e10c66cd2dcb987867ef176292bf4e64eccc680a49e35e9e9c669f4a02bac17e86abdb
-  languageName: node
-  linkType: hard
-
 "eslint-scope@npm:^7.1.1":
   version: 7.1.1
   resolution: "eslint-scope@npm:7.1.1"
@@ -2723,13 +1960,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"estraverse@npm:^4.1.1":
-  version: 4.3.0
-  resolution: "estraverse@npm:4.3.0"
-  checksum: a6299491f9940bb246124a8d44b7b7a413a8336f5436f9837aaa9330209bd9ee8af7e91a654a3545aee9c54b3308e78ee360cef1d777d37cfef77d2fa33b5827
-  languageName: node
-  linkType: hard
-
 "estraverse@npm:^5.1.0, estraverse@npm:^5.2.0":
   version: 5.3.0
   resolution: "estraverse@npm:5.3.0"
@@ -2751,13 +1981,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"eventemitter3@npm:^3.1.0":
-  version: 3.1.2
-  resolution: "eventemitter3@npm:3.1.2"
-  checksum: 81e4e82b8418f5cfd986d2b4a2fa5397ac4eb8134e09bcb47005545e22fdf8e9e61d5c053d34651112245aae411bdfe6d0ad5511da0400743fef5fc38bfcfbe3
-  languageName: node
-  linkType: hard
-
 "eventemitter3@npm:^4.0.4":
   version: 4.0.7
   resolution: "eventemitter3@npm:4.0.7"
@@ -2920,15 +2143,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"for-each@npm:^0.3.3":
-  version: 0.3.3
-  resolution: "for-each@npm:0.3.3"
-  dependencies:
-    is-callable: ^1.1.3
-  checksum: 6c48ff2bc63362319c65e2edca4a8e1e3483a2fabc72fbe7feaf8c73db94fc7861bd53bc02c8a66a0c1dd709da6b04eec42e0abdd6b40ce47305ae92a25e5d28
-  languageName: node
-  linkType: hard
-
 "fs-extra@npm:10.1.0, fs-extra@npm:^10.0.0, fs-extra@npm:^10.1.0":
   version: 10.1.0
   resolution: "fs-extra@npm:10.1.0"
@@ -3182,7 +2396,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"globby@npm:^11.0.4, globby@npm:^11.1.0":
+"globby@npm:^11.0.4":
   version: 11.1.0
   resolution: "globby@npm:11.1.0"
   dependencies:
@@ -3196,15 +2410,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"gopd@npm:^1.0.1":
-  version: 1.0.1
-  resolution: "gopd@npm:1.0.1"
-  dependencies:
-    get-intrinsic: ^1.1.3
-  checksum: a5ccfb8806e0917a94e0b3de2af2ea4979c1da920bc381667c260e00e7cafdbe844e2cb9c5bcfef4e5412e8bf73bab837285bc35c7ba73aaaf0134d4583393a6
-  languageName: node
-  linkType: hard
-
 "graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.6":
   version: 4.2.10
   resolution: "graceful-fs@npm:4.2.10"
@@ -3219,7 +2424,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"handlebars@npm:4.7.7, handlebars@npm:^4.7.7":
+"handlebars@npm:^4.7.7":
   version: 4.7.7
   resolution: "handlebars@npm:4.7.7"
   dependencies:
@@ -3251,13 +2456,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"has-cors@npm:1.1.0":
-  version: 1.1.0
-  resolution: "has-cors@npm:1.1.0"
-  checksum: 549ce94113fd23895b22d71ade9809918577b8558cd4d701fe79045d8b1d58d87eba870260b28f6a3229be933a691c55653afd496d0fc52e98fd2ff577f01197
-  languageName: node
-  linkType: hard
-
 "has-flag@npm:^3.0.0":
   version: 3.0.0
   resolution: "has-flag@npm:3.0.0"
@@ -3414,13 +2612,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"immediate@npm:~3.0.5":
-  version: 3.0.6
-  resolution: "immediate@npm:3.0.6"
-  checksum: f9b3486477555997657f70318cc8d3416159f208bec4cca3ff3442fd266bc23f50f0c9bd8547e1371a6b5e82b821ec9a7044a4f7b944798b25aa3cc6d5e63e62
-  languageName: node
-  linkType: hard
-
 "immutable@npm:^4.0.0":
   version: 4.1.0
   resolution: "immutable@npm:4.1.0"
@@ -3501,16 +2692,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"is-arguments@npm:^1.0.4":
-  version: 1.1.1
-  resolution: "is-arguments@npm:1.1.1"
-  dependencies:
-    call-bind: ^1.0.2
-    has-tostringtag: ^1.0.0
-  checksum: 7f02700ec2171b691ef3e4d0e3e6c0ba408e8434368504bb593d0d7c891c0dbfda6d19d30808b904a6cb1929bca648c061ba438c39f296c2a8ca083229c49f27
-  languageName: node
-  linkType: hard
-
 "is-arrayish@npm:^0.2.1":
   version: 0.2.1
   resolution: "is-arrayish@npm:0.2.1"
@@ -3546,7 +2727,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"is-callable@npm:^1.1.3, is-callable@npm:^1.1.4, is-callable@npm:^1.2.7":
+"is-callable@npm:^1.1.4, is-callable@npm:^1.2.7":
   version: 1.2.7
   resolution: "is-callable@npm:1.2.7"
   checksum: 61fd57d03b0d984e2ed3720fb1c7a897827ea174bd44402878e059542ea8c4aeedee0ea0985998aa5cc2736b2fa6e271c08587addb5b3959ac52cf665173d1ac
@@ -3592,15 +2773,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"is-generator-function@npm:^1.0.7":
-  version: 1.0.10
-  resolution: "is-generator-function@npm:1.0.10"
-  dependencies:
-    has-tostringtag: ^1.0.0
-  checksum: d54644e7dbaccef15ceb1e5d91d680eb5068c9ee9f9eb0a9e04173eb5542c9b51b5ab52c5537f5703e48d5fddfd376817c1ca07a84a407b7115b769d4bdde72b
-  languageName: node
-  linkType: hard
-
 "is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3, is-glob@npm:~4.0.1":
   version: 4.0.3
   resolution: "is-glob@npm:4.0.3"
@@ -3728,19 +2900,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"is-typed-array@npm:^1.1.10, is-typed-array@npm:^1.1.3":
-  version: 1.1.10
-  resolution: "is-typed-array@npm:1.1.10"
-  dependencies:
-    available-typed-arrays: ^1.0.5
-    call-bind: ^1.0.2
-    for-each: ^0.3.3
-    gopd: ^1.0.1
-    has-tostringtag: ^1.0.0
-  checksum: aac6ecb59d4c56a1cdeb69b1f129154ef462bbffe434cb8a8235ca89b42f258b7ae94073c41b3cb7bce37f6a1733ad4499f07882d5d5093a7ba84dfc4ebb8017
-  languageName: node
-  linkType: hard
-
 "is-weakref@npm:^1.0.2":
   version: 1.0.2
   resolution: "is-weakref@npm:1.0.2"
@@ -3764,13 +2923,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"ismobilejs@npm:^1.1.0":
-  version: 1.1.1
-  resolution: "ismobilejs@npm:1.1.1"
-  checksum: 937479c4ae13306f41391e0f57611b0835bc57325750b446cb12ed844d697407f66f050ebf7446538cc3aae9575df6382243224be3032c1574b61e2f955d8417
-  languageName: node
-  linkType: hard
-
 "js-sdsl@npm:^4.1.4":
   version: 4.1.5
   resolution: "js-sdsl@npm:4.1.5"
@@ -3875,15 +3027,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"lie@npm:3.1.1":
-  version: 3.1.1
-  resolution: "lie@npm:3.1.1"
-  dependencies:
-    immediate: ~3.0.5
-  checksum: 6da9f2121d2dbd15f1eca44c0c7e211e66a99c7b326ec8312645f3648935bc3a658cf0e9fa7b5f10144d9e2641500b4f55bd32754607c3de945b5f443e50ddd1
-  languageName: node
-  linkType: hard
-
 "lilconfig@npm:2.0.6, lilconfig@npm:^2.0.3":
   version: 2.0.6
   resolution: "lilconfig@npm:2.0.6"
@@ -3954,15 +3097,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"localforage@npm:^1.9.0":
-  version: 1.10.0
-  resolution: "localforage@npm:1.10.0"
-  dependencies:
-    lie: 3.1.1
-  checksum: f2978b434dafff9bcb0d9498de57d97eba165402419939c944412e179cab1854782830b5ec196212560b22712d1dd03918939f59cf1d4fc1d756fca7950086cf
-  languageName: node
-  linkType: hard
-
 "locate-path@npm:^2.0.0":
   version: 2.0.0
   resolution: "locate-path@npm:2.0.0"
@@ -4249,13 +3383,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"mini-signals@npm:^1.2.0":
-  version: 1.2.0
-  resolution: "mini-signals@npm:1.2.0"
-  checksum: fe28285d6ecc6c8035339fb909748e110ebf31cbaa4e8d849261017327d9a47ad43815f013ac1fc9b8b16c4d302dfd19b6dd952c9657293b70f8d1e95926545c
-  languageName: node
-  linkType: hard
-
 "minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2":
   version: 3.1.2
   resolution: "minimatch@npm:3.1.2"
@@ -4401,13 +3528,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"natural-compare-lite@npm:^1.4.0":
-  version: 1.4.0
-  resolution: "natural-compare-lite@npm:1.4.0"
-  checksum: 5222ac3986a2b78dd6069ac62cbb52a7bf8ffc90d972ab76dfe7b01892485d229530ed20d0c62e79a6b363a663b273db3bde195a1358ce9e5f779d4453887225
-  languageName: node
-  linkType: hard
-
 "natural-compare@npm:^1.4.0":
   version: 1.4.0
   resolution: "natural-compare@npm:1.4.0"
@@ -4572,13 +3692,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"object-assign@npm:^4.1.1":
-  version: 4.1.1
-  resolution: "object-assign@npm:4.1.1"
-  checksum: fcc6e4ea8c7fe48abfbb552578b1c53e0d194086e2e6bbbf59e0a536381a292f39943c6e9628af05b5528aa5e3318bb30d6b2e53cadaf5b8fe9e12c4b69af23f
-  languageName: node
-  linkType: hard
-
 "object-inspect@npm:^1.12.2, object-inspect@npm:^1.9.0":
   version: 1.12.2
   resolution: "object-inspect@npm:1.12.2"
@@ -4780,27 +3893,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"parse-uri@npm:^1.0.0":
-  version: 1.0.7
-  resolution: "parse-uri@npm:1.0.7"
-  checksum: 0d4386a586bda98bcdd041f9b1a7e9a6c16bc2ab198c90531f2d169eb2eb520477cc059a75c5cf0695eb3c9e69ff6b90793d07781ab83e2de1cbb255ec66e37f
-  languageName: node
-  linkType: hard
-
-"parseqs@npm:0.0.6":
-  version: 0.0.6
-  resolution: "parseqs@npm:0.0.6"
-  checksum: 7fc4ff4ba59764060bb8529875f6d4313056ea6939ff579b22dd7bd6f6033035e1fd2d6a559ab48ef0a7fa29a9d7731c982bfd1594e9115141fe1c328485ce9e
-  languageName: node
-  linkType: hard
-
-"parseuri@npm:0.0.6":
-  version: 0.0.6
-  resolution: "parseuri@npm:0.0.6"
-  checksum: fa430e40f0c75293a28e5f1023da5f51a5038d5e34c48c517b0d5187143f6bcc67d3091a062b68765db4a22757e488c7d15854f9d1921f2c2b9afa5ca0629a84
-  languageName: node
-  linkType: hard
-
 "path-exists@npm:^3.0.0":
   version: 3.0.0
   resolution: "path-exists@npm:3.0.0"
@@ -4912,57 +4004,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"pixi-particles@npm:4.3.1":
-  version: 4.3.1
-  resolution: "pixi-particles@npm:4.3.1"
-  peerDependencies:
-    pixi.js: ">=4.0.0"
-  checksum: c7e6314921e6a5a935fe9874d5e1389b8a234f1a9d4774aec181faecd211aa26c7442b58435517212a737c9db24ff83383b9cf83efb5143cc078fa211259ab9a
-  languageName: node
-  linkType: hard
-
-"pixi.js@npm:5.3.11":
-  version: 5.3.11
-  resolution: "pixi.js@npm:5.3.11"
-  dependencies:
-    "@pixi/accessibility": 5.3.11
-    "@pixi/app": 5.3.11
-    "@pixi/constants": 5.3.11
-    "@pixi/core": 5.3.11
-    "@pixi/display": 5.3.11
-    "@pixi/extract": 5.3.11
-    "@pixi/filter-alpha": 5.3.11
-    "@pixi/filter-blur": 5.3.11
-    "@pixi/filter-color-matrix": 5.3.11
-    "@pixi/filter-displacement": 5.3.11
-    "@pixi/filter-fxaa": 5.3.11
-    "@pixi/filter-noise": 5.3.11
-    "@pixi/graphics": 5.3.11
-    "@pixi/interaction": 5.3.11
-    "@pixi/loaders": 5.3.11
-    "@pixi/math": 5.3.11
-    "@pixi/mesh": 5.3.11
-    "@pixi/mesh-extras": 5.3.11
-    "@pixi/mixin-cache-as-bitmap": 5.3.11
-    "@pixi/mixin-get-child-by-name": 5.3.11
-    "@pixi/mixin-get-global-position": 5.3.11
-    "@pixi/particles": 5.3.11
-    "@pixi/polyfill": 5.3.11
-    "@pixi/prepare": 5.3.11
-    "@pixi/runner": 5.3.11
-    "@pixi/settings": 5.3.11
-    "@pixi/sprite": 5.3.11
-    "@pixi/sprite-animated": 5.3.11
-    "@pixi/sprite-tiling": 5.3.11
-    "@pixi/spritesheet": 5.3.11
-    "@pixi/text": 5.3.11
-    "@pixi/text-bitmap": 5.3.11
-    "@pixi/ticker": 5.3.11
-    "@pixi/utils": 5.3.11
-  checksum: ff33b02d78ef2266b8e3e1159142d2cc71605b846935760dcef36c8774dd87d8f804003f375ece259cbce1e9f64487ed5b2f1fca620677fc08a374a1203c60ce
-  languageName: node
-  linkType: hard
-
 "postcss-calc@npm:^8.2.3":
   version: 8.2.4
   resolution: "postcss-calc@npm:8.2.4"
@@ -5389,13 +4430,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"punycode@npm:1.3.2":
-  version: 1.3.2
-  resolution: "punycode@npm:1.3.2"
-  checksum: b8807fd594b1db33335692d1f03e8beeddde6fda7fbb4a2e32925d88d20a3aa4cd8dcc0c109ccaccbd2ba761c208dfaaada83007087ea8bfb0129c9ef1b99ed6
-  languageName: node
-  linkType: hard
-
 "punycode@npm:^2.1.0":
   version: 2.1.1
   resolution: "punycode@npm:2.1.1"
@@ -5422,13 +4456,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"querystring@npm:0.2.0":
-  version: 0.2.0
-  resolution: "querystring@npm:0.2.0"
-  checksum: 8258d6734f19be27e93f601758858c299bdebe71147909e367101ba459b95446fbe5b975bf9beb76390156a592b6f4ac3a68b6087cea165c259705b8b4e56a69
-  languageName: node
-  linkType: hard
-
 "queue-microtask@npm:^1.2.2":
   version: 1.2.3
   resolution: "queue-microtask@npm:1.2.3"
@@ -5613,16 +4640,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"resource-loader@npm:^3.0.1":
-  version: 3.0.1
-  resolution: "resource-loader@npm:3.0.1"
-  dependencies:
-    mini-signals: ^1.2.0
-    parse-uri: ^1.0.0
-  checksum: f7d35f589db48d0bde92a66a6dc8b884ddcadec3ae43df07c3e0cd99b215cf3002347633e7516baebef868f1edd5a433fe2260fbbc5f16f84d4e37d8923de451
-  languageName: node
-  linkType: hard
-
 "restore-cursor@npm:^3.1.0":
   version: 3.1.0
   resolution: "restore-cursor@npm:3.1.0"
@@ -5804,7 +4821,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"semver@npm:7.3.8, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7":
+"semver@npm:7.3.8, semver@npm:^7.3.4, semver@npm:^7.3.5":
   version: 7.3.8
   resolution: "semver@npm:7.3.8"
   dependencies:
@@ -5934,30 +4951,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"socket.io-client@npm:4.3.2":
-  version: 4.3.2
-  resolution: "socket.io-client@npm:4.3.2"
-  dependencies:
-    "@socket.io/component-emitter": ~3.0.0
-    backo2: ~1.0.2
-    debug: ~4.3.2
-    engine.io-client: ~6.0.1
-    parseuri: 0.0.6
-    socket.io-parser: ~4.1.1
-  checksum: e8c1c76848020f976958eed0a7630e1ed4a3108de75aa2cf7cb2c6babfcacff6d8fe1b70910b8b201a29e4965e238d520ac1868846c2872a948c9dd0e0761288
-  languageName: node
-  linkType: hard
-
-"socket.io-parser@npm:~4.1.1":
-  version: 4.1.2
-  resolution: "socket.io-parser@npm:4.1.2"
-  dependencies:
-    "@socket.io/component-emitter": ~3.0.0
-    debug: ~4.3.1
-  checksum: cd13cdbda929cce610b39fbf7f2c6aa59e55cfc58f13b38c592d7eb45b19d5110bcb81150607a88f8644959f5d0a384467a2083d29c12e224c010a406377649b
-  languageName: node
-  linkType: hard
-
 "socks-proxy-agent@npm:^7.0.0":
   version: 7.0.0
   resolution: "socks-proxy-agent@npm:7.0.0"
@@ -6342,20 +5335,7 @@ __metadata:
     "@commitlint/cli": 17.3.0
     "@commitlint/config-conventional": 17.3.0
     "@guanghechen/rollup-plugin-copy": 2.1.4
-    "@league-of-foundry-developers/foundry-vtt-types": 9.280.0
-    "@pixi/constants": 6.2.1
-    "@pixi/core": 6.2.1
-    "@pixi/display": 6.2.1
-    "@pixi/graphics": 6.2.1
-    "@pixi/math": 6.2.1
-    "@pixi/runner": 6.2.1
-    "@pixi/settings": 6.2.1
-    "@pixi/utils": 6.2.1
-    "@seald-io/nedb": 3.1.0
     "@swc/core": 1.3.20
-    "@types/fs-extra": 9.0.13
-    "@typescript-eslint/eslint-plugin": 5.44.0
-    "@typescript-eslint/parser": 5.44.0
     conventional-changelog-cli: 2.2.2
     conventional-changelog-conventionalcommits: 5.0.0
     eslint: 8.28.0
@@ -6372,20 +5352,10 @@ __metadata:
     rollup-plugin-swc3: 0.7.0
     sass: 1.56.1
     semver: 7.3.8
-    ts-node: 10.9.1
-    tslib: 2.4.1
-    typescript: 4.7.4
     yargs: 17.6.2
   languageName: unknown
   linkType: soft
 
-"tinymce@npm:5.10.1":
-  version: 5.10.1
-  resolution: "tinymce@npm:5.10.1"
-  checksum: 6a518c0e9c8f7d9ca22deb73d777dece4aeabe9361b409c5ca7dbb62607a284550c9d0bf77dffa5d4b21a831b56c2f08c365f8c35d958e374d5beacc1a717753
-  languageName: node
-  linkType: hard
-
 "to-regex-range@npm:^5.0.1":
   version: 5.0.1
   resolution: "to-regex-range@npm:5.0.1"
@@ -6402,7 +5372,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"ts-node@npm:10.9.1, ts-node@npm:^10.8.1":
+"ts-node@npm:^10.8.1":
   version: 10.9.1
   resolution: "ts-node@npm:10.9.1"
   dependencies:
@@ -6440,31 +5410,13 @@ __metadata:
   languageName: node
   linkType: hard
 
-"tslib@npm:2.4.1, tslib@npm:^2.1.0, tslib@npm:^2.3.1":
+"tslib@npm:^2.1.0, tslib@npm:^2.3.1":
   version: 2.4.1
   resolution: "tslib@npm:2.4.1"
   checksum: 19480d6e0313292bd6505d4efe096a6b31c70e21cf08b5febf4da62e95c265c8f571f7b36fcc3d1a17e068032f59c269fab3459d6cd3ed6949eafecf64315fca
   languageName: node
   linkType: hard
 
-"tslib@npm:^1.8.1":
-  version: 1.14.1
-  resolution: "tslib@npm:1.14.1"
-  checksum: dbe628ef87f66691d5d2959b3e41b9ca0045c3ee3c7c7b906cc1e328b39f199bb1ad9e671c39025bd56122ac57dfbf7385a94843b1cc07c60a4db74795829acd
-  languageName: node
-  linkType: hard
-
-"tsutils@npm:^3.21.0":
-  version: 3.21.0
-  resolution: "tsutils@npm:3.21.0"
-  dependencies:
-    tslib: ^1.8.1
-  peerDependencies:
-    typescript: ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta"
-  checksum: 1843f4c1b2e0f975e08c4c21caa4af4f7f65a12ac1b81b3b8489366826259323feb3fc7a243123453d2d1a02314205a7634e048d4a8009921da19f99755cdc48
-  languageName: node
-  linkType: hard
-
 "type-check@npm:^0.4.0, type-check@npm:~0.4.0":
   version: 0.4.0
   resolution: "type-check@npm:0.4.0"
@@ -6509,16 +5461,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"typescript@npm:4.7.4":
-  version: 4.7.4
-  resolution: "typescript@npm:4.7.4"
-  bin:
-    tsc: bin/tsc
-    tsserver: bin/tsserver
-  checksum: 5750181b1cd7e6482c4195825547e70f944114fb47e58e4aa7553e62f11b3f3173766aef9c281783edfd881f7b8299cf35e3ca8caebe73d8464528c907a164df
-  languageName: node
-  linkType: hard
-
 "typescript@npm:^4.6.4":
   version: 4.9.3
   resolution: "typescript@npm:4.9.3"
@@ -6529,16 +5471,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"typescript@patch:typescript@4.7.4#~builtin<compat/typescript>":
-  version: 4.7.4
-  resolution: "typescript@patch:typescript@npm%3A4.7.4#~builtin<compat/typescript>::version=4.7.4&hash=701156"
-  bin:
-    tsc: bin/tsc
-    tsserver: bin/tsserver
-  checksum: 9096d8f6c16cb80ef3bf96fcbbd055bf1c4a43bd14f3b7be45a9fbe7ada46ec977f604d5feed3263b4f2aa7d4c7477ce5f9cd87de0d6feedec69a983f3a4f93e
-  languageName: node
-  linkType: hard
-
 "typescript@patch:typescript@^4.6.4#~builtin<compat/typescript>":
   version: 4.9.3
   resolution: "typescript@patch:typescript@npm%3A4.9.3#~builtin<compat/typescript>::version=4.9.3&hash=701156"
@@ -6618,16 +5550,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"url@npm:^0.11.0":
-  version: 0.11.0
-  resolution: "url@npm:0.11.0"
-  dependencies:
-    punycode: 1.3.2
-    querystring: 0.2.0
-  checksum: 50d100d3dd2d98b9fe3ada48cadb0b08aa6be6d3ac64112b867b56b19be4bfcba03c2a9a0d7922bfd7ac17d4834e88537749fe182430dfd9b68e520175900d90
-  languageName: node
-  linkType: hard
-
 "util-deprecate@npm:^1.0.1, util-deprecate@npm:^1.0.2, util-deprecate@npm:~1.0.1":
   version: 1.0.2
   resolution: "util-deprecate@npm:1.0.2"
@@ -6635,19 +5557,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"util@npm:^0.12.4":
-  version: 0.12.5
-  resolution: "util@npm:0.12.5"
-  dependencies:
-    inherits: ^2.0.3
-    is-arguments: ^1.0.4
-    is-generator-function: ^1.0.7
-    is-typed-array: ^1.1.3
-    which-typed-array: ^1.1.2
-  checksum: 705e51f0de5b446f4edec10739752ac25856541e0254ea1e7e45e5b9f9b0cb105bc4bd415736a6210edc68245a7f903bf085ffb08dd7deb8a0e847f60538a38a
-  languageName: node
-  linkType: hard
-
 "uuid@npm:^3.3.2":
   version: 3.4.0
   resolution: "uuid@npm:3.4.0"
@@ -6687,20 +5596,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"which-typed-array@npm:^1.1.2":
-  version: 1.1.9
-  resolution: "which-typed-array@npm:1.1.9"
-  dependencies:
-    available-typed-arrays: ^1.0.5
-    call-bind: ^1.0.2
-    for-each: ^0.3.3
-    gopd: ^1.0.1
-    has-tostringtag: ^1.0.0
-    is-typed-array: ^1.1.10
-  checksum: fe0178ca44c57699ca2c0e657b64eaa8d2db2372a4e2851184f568f98c478ae3dc3fdb5f7e46c384487046b0cf9e23241423242b277e03e8ba3dabc7c84c98ef
-  languageName: node
-  linkType: hard
-
 "which@npm:^1.2.9":
   version: 1.3.1
   resolution: "which@npm:1.3.1"
@@ -6775,28 +5670,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"ws@npm:~8.2.3":
-  version: 8.2.3
-  resolution: "ws@npm:8.2.3"
-  peerDependencies:
-    bufferutil: ^4.0.1
-    utf-8-validate: ^5.0.2
-  peerDependenciesMeta:
-    bufferutil:
-      optional: true
-    utf-8-validate:
-      optional: true
-  checksum: c869296ccb45f218ac6d32f8f614cd85b50a21fd434caf11646008eef92173be53490810c5c23aea31bc527902261fbfd7b062197eea341b26128d4be56a85e4
-  languageName: node
-  linkType: hard
-
-"xmlhttprequest-ssl@npm:~2.0.0":
-  version: 2.0.0
-  resolution: "xmlhttprequest-ssl@npm:2.0.0"
-  checksum: 1e98df67f004fec15754392a131343ea92e6ab5ac4d77e842378c5c4e4fd5b6a9134b169d96842cc19422d77b1606b8df84a5685562b3b698cb68441636f827e
-  languageName: node
-  linkType: hard
-
 "xtend@npm:~4.0.1":
   version: 4.0.2
   resolution: "xtend@npm:4.0.2"
@@ -6876,13 +5749,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"yeast@npm:0.1.2":
-  version: 0.1.2
-  resolution: "yeast@npm:0.1.2"
-  checksum: 81a250b69f601fed541e9518eb2972e75631dd81231689503d7f288612d4eec793b29c208d6807fd6bfc4c2a43614d0c6db233739a4ae6223e244aaed6a885c0
-  languageName: node
-  linkType: hard
-
 "yn@npm:3.1.1":
   version: 3.1.1
   resolution: "yn@npm:3.1.1"