diff --git a/.cspell.json b/.cspell.json
new file mode 100644
index 000000000..66fca29b2
--- /dev/null
+++ b/.cspell.json
@@ -0,0 +1,17 @@
+{
+ "version": "0.2",
+ "language": "en,en-gb",
+ "words": [],
+ "dictionaries": [
+ "npm",
+ "softwareTerms",
+ "node",
+ "html",
+ "css",
+ "bash",
+ "en-gb",
+ "misc"
+ ],
+ "ignorePaths": ["package.json", "package-lock.json", "node_modules"]
+ }
+
\ No newline at end of file
diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml
index a068ffbb3..a77f4984b 100644
--- a/.github/workflows/releases.yml
+++ b/.github/workflows/releases.yml
@@ -25,6 +25,7 @@ jobs:
- name: Install
run: |
+ export DETECT_CHROMEDRIVER_VERSION=true
npm ci
npm run setheapsize
@@ -61,12 +62,22 @@ jobs:
tags: ${{ steps.image-metadata.outputs.tags }}
labels: ${{ steps.image-metadata.outputs.labels }}
containerfiles: ./Dockerfile
- platforms: linux/amd64
+ platforms: linux/amd64,linux/arm64
oci: true
+ # enable build layer caching between platforms
+ layers: true
# Webpack seems to use a lot of open files, increase the max open file limit to accomodate.
extra-args: |
--ulimit nofile=10000
+ - name: Publish to GHCR
+ uses: redhat-actions/push-to-registry@v2
+ with:
+ image: ${{ steps.build-image.outputs.image }}
+ tags: ${{ steps.build-image.outputs.tags }}
+ registry: ${{ env.REGISTRY }}
+ username: ${{ env.REGISTRY_USER }}
+ password: ${{ env.REGISTRY_PASSWORD }}
- name: Upload Release Assets
id: upload-release-assets
@@ -83,11 +94,3 @@ jobs:
uses: JS-DevTools/npm-publish@v1
with:
token: ${{ secrets.NPM_TOKEN }}
-
- - name: Publish to GHCR
- uses: redhat-actions/push-to-registry@v2
- with:
- tags: ${{ steps.build-image.outputs.tags }}
- registry: ${{ env.REGISTRY }}
- username: ${{ env.REGISTRY_USER }}
- password: ${{ env.REGISTRY_PASSWORD }}
diff --git a/Dockerfile b/Dockerfile
index be4c8bada..ba605fd71 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,9 +1,35 @@
-FROM node:18-alpine AS build
+#####################################
+# Build the app to a static website #
+#####################################
+# Modifier --platform=$BUILDPLATFORM limits the platform to "BUILDPLATFORM" during buildx multi-platform builds
+# This is because npm "chromedriver" package is not compatiable with all platforms
+# For more info see: https://docs.docker.com/build/building/multi-platform/#cross-compilation
+FROM --platform=$BUILDPLATFORM node:18-alpine AS builder
+WORKDIR /app
+
+COPY package.json .
+COPY package-lock.json .
+
+# Install dependencies
+# --ignore-scripts prevents postinstall script (which runs grunt) as it depends on files other than package.json
+RUN npm ci --ignore-scripts
+
+# Copy files needed for postinstall and build
COPY . .
-RUN npm ci
+
+# npm postinstall runs grunt, which depends on files other than package.json
+RUN npm run postinstall
+
+# Build the app
RUN npm run build
-FROM nginx:1.25-alpine3.18 AS cyberchef
+#########################################
+# Package static build files into nginx #
+#########################################
+# We are using Github Actions: redhat-actions/buildah-build@v2 which needs manual selection of arch in base image
+# Remove TARGETARCH if docker buildx is supported in the CI release as --platform=$TARGETPLATFORM will be automatically set
+ARG TARGETPLATFORM
+FROM --platform=${TARGETPLATFORM} nginx:stable-alpine AS cyberchef
-COPY --from=build ./build/prod /usr/share/nginx/html/
+COPY --from=builder /app/build/prod /usr/share/nginx/html/
diff --git a/README.md b/README.md
index 5549bda2a..89f0371d5 100755
--- a/README.md
+++ b/README.md
@@ -20,21 +20,36 @@ Cryptographic operations in CyberChef should not be relied upon to provide secur
[A live demo can be found here][1] - have fun!
-## Containers
+## Running Locally with Docker
-If you would like to try out CyberChef locally you can either build it yourself:
+**Prerequisites**
+- [Docker](hhttps://www.docker.com/products/docker-desktop/)
+ - Docker Desktop must be open and running on your machine
+
+
+#### Option 1: Build the Docker Image Yourself
+
+1. Build the docker image
```bash
docker build --tag cyberchef --ulimit nofile=10000 .
+```
+2. Run the docker container
+```bash
docker run -it -p 8080:80 cyberchef
```
+3. Navigate to `http://localhost:8080` in your browser
-Or you can use our image directly:
+#### Option 2: Use the pre-built Docker Image
+
+If you prefer to skip the build process, you can use the pre-built image
```bash
docker run -it -p 8080:80 ghcr.io/gchq/cyberchef:latest
```
+Just like before, navigate to `http://localhost:8080` in your browser.
+
This image is built and published through our [GitHub Workflows](.github/workflows/releases.yml)
## How it works
diff --git a/package-lock.json b/package-lock.json
index 8f9619945..b374df4bc 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -37,6 +37,7 @@
"d3": "7.9.0",
"d3-hexbin": "^0.2.2",
"diff": "^5.2.0",
+ "dompurify": "^3.2.5",
"es6-promisify": "^7.0.0",
"escodegen": "^2.1.0",
"esprima": "^4.0.1",
@@ -45,14 +46,17 @@
"file-saver": "^2.0.5",
"flat": "^6.0.1",
"geodesy": "1.1.3",
+ "handlebars": "^4.7.8",
+ "hash-wasm": "^4.12.0",
"highlight.js": "^11.9.0",
"ieee754": "^1.2.1",
"jimp": "^0.22.12",
+ "jq-web": "^0.5.1",
"jquery": "3.7.1",
- "js-crc": "^0.2.0",
"js-sha3": "^0.9.3",
"jsesc": "^3.0.2",
"json5": "^2.2.3",
+ "jsonata": "^2.0.3",
"jsonpath-plus": "^9.0.0",
"jsonwebtoken": "8.5.1",
"jsqr": "^1.4.0",
@@ -93,6 +97,7 @@
"ua-parser-js": "^1.0.38",
"unorm": "^1.6.0",
"utf8": "^3.0.0",
+ "uuid": "^11.1.0",
"vkbeautify": "^0.99.3",
"xpath": "0.0.34",
"xregexp": "^5.1.1",
@@ -121,6 +126,7 @@
"compression-webpack-plugin": "^11.1.0",
"copy-webpack-plugin": "^12.0.2",
"core-js": "^3.37.1",
+ "cspell": "^8.17.3",
"css-loader": "7.1.2",
"eslint": "^9.4.0",
"eslint-plugin-jsdoc": "^48.2.9",
@@ -1908,6 +1914,594 @@
"node": ">=0.1.90"
}
},
+ "node_modules/@cspell/cspell-bundled-dicts": {
+ "version": "8.17.3",
+ "resolved": "https://registry.npmjs.org/@cspell/cspell-bundled-dicts/-/cspell-bundled-dicts-8.17.3.tgz",
+ "integrity": "sha512-6uOF726o3JnExAUKM20OJJXZo+Qf9Jt64nkVwnVXx7Upqr5I9Pb1npYPEAIpUA03SnWYmKwUIqhAmkwrN+bLPA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@cspell/dict-ada": "^4.1.0",
+ "@cspell/dict-al": "^1.1.0",
+ "@cspell/dict-aws": "^4.0.9",
+ "@cspell/dict-bash": "^4.2.0",
+ "@cspell/dict-companies": "^3.1.13",
+ "@cspell/dict-cpp": "^6.0.3",
+ "@cspell/dict-cryptocurrencies": "^5.0.4",
+ "@cspell/dict-csharp": "^4.0.6",
+ "@cspell/dict-css": "^4.0.17",
+ "@cspell/dict-dart": "^2.3.0",
+ "@cspell/dict-data-science": "^2.0.7",
+ "@cspell/dict-django": "^4.1.4",
+ "@cspell/dict-docker": "^1.1.12",
+ "@cspell/dict-dotnet": "^5.0.9",
+ "@cspell/dict-elixir": "^4.0.7",
+ "@cspell/dict-en_us": "^4.3.30",
+ "@cspell/dict-en-common-misspellings": "^2.0.9",
+ "@cspell/dict-en-gb": "1.1.33",
+ "@cspell/dict-filetypes": "^3.0.10",
+ "@cspell/dict-flutter": "^1.1.0",
+ "@cspell/dict-fonts": "^4.0.4",
+ "@cspell/dict-fsharp": "^1.1.0",
+ "@cspell/dict-fullstack": "^3.2.3",
+ "@cspell/dict-gaming-terms": "^1.1.0",
+ "@cspell/dict-git": "^3.0.4",
+ "@cspell/dict-golang": "^6.0.18",
+ "@cspell/dict-google": "^1.0.8",
+ "@cspell/dict-haskell": "^4.0.5",
+ "@cspell/dict-html": "^4.0.11",
+ "@cspell/dict-html-symbol-entities": "^4.0.3",
+ "@cspell/dict-java": "^5.0.11",
+ "@cspell/dict-julia": "^1.1.0",
+ "@cspell/dict-k8s": "^1.0.10",
+ "@cspell/dict-kotlin": "^1.1.0",
+ "@cspell/dict-latex": "^4.0.3",
+ "@cspell/dict-lorem-ipsum": "^4.0.4",
+ "@cspell/dict-lua": "^4.0.7",
+ "@cspell/dict-makefile": "^1.0.4",
+ "@cspell/dict-markdown": "^2.0.9",
+ "@cspell/dict-monkeyc": "^1.0.10",
+ "@cspell/dict-node": "^5.0.6",
+ "@cspell/dict-npm": "^5.1.24",
+ "@cspell/dict-php": "^4.0.14",
+ "@cspell/dict-powershell": "^5.0.14",
+ "@cspell/dict-public-licenses": "^2.0.13",
+ "@cspell/dict-python": "^4.2.15",
+ "@cspell/dict-r": "^2.1.0",
+ "@cspell/dict-ruby": "^5.0.7",
+ "@cspell/dict-rust": "^4.0.11",
+ "@cspell/dict-scala": "^5.0.7",
+ "@cspell/dict-shell": "^1.1.0",
+ "@cspell/dict-software-terms": "^4.2.4",
+ "@cspell/dict-sql": "^2.2.0",
+ "@cspell/dict-svelte": "^1.0.6",
+ "@cspell/dict-swift": "^2.0.5",
+ "@cspell/dict-terraform": "^1.1.0",
+ "@cspell/dict-typescript": "^3.2.0",
+ "@cspell/dict-vue": "^3.0.4"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@cspell/cspell-json-reporter": {
+ "version": "8.17.3",
+ "resolved": "https://registry.npmjs.org/@cspell/cspell-json-reporter/-/cspell-json-reporter-8.17.3.tgz",
+ "integrity": "sha512-RWSfyHOin/d9CqLjz00JMvPkag3yUSsQZr6G9BnCT5cMEO/ws8wQZzA54CNj/LAOccbknTX65SSroPPAtxs56w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@cspell/cspell-types": "8.17.3"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@cspell/cspell-pipe": {
+ "version": "8.17.3",
+ "resolved": "https://registry.npmjs.org/@cspell/cspell-pipe/-/cspell-pipe-8.17.3.tgz",
+ "integrity": "sha512-DqqSWKt9NLWPGloYxZTpzUhgdW8ObMkZmOOF6TyqpJ4IbckEct8ULgskNorTNRlmmjLniaNgvg6JSHuYO3Urxw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@cspell/cspell-resolver": {
+ "version": "8.17.3",
+ "resolved": "https://registry.npmjs.org/@cspell/cspell-resolver/-/cspell-resolver-8.17.3.tgz",
+ "integrity": "sha512-yQlVaIsWiax6RRuuacZs++kl6Y9rwH9ZkVlsG9fhdeCJ5Xf3WCW+vmX1chzhhKDzRr8CF9fsvb1uagd/5/bBYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "global-directory": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@cspell/cspell-service-bus": {
+ "version": "8.17.3",
+ "resolved": "https://registry.npmjs.org/@cspell/cspell-service-bus/-/cspell-service-bus-8.17.3.tgz",
+ "integrity": "sha512-CC3nob/Kbuesz5WTW+LjAHnDFXJrA49pW5ckmbufJxNnoAk7EJez/qr7/ELMTf6Fl3A5xZ776Lhq7738Hy/fmQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@cspell/cspell-types": {
+ "version": "8.17.3",
+ "resolved": "https://registry.npmjs.org/@cspell/cspell-types/-/cspell-types-8.17.3.tgz",
+ "integrity": "sha512-ozgeuSioX9z2wtlargfgdw3LKwDFAfm8gxu+xwNREvXiLsevb+lb7ZlY5/ay+MahqR5Hfs7XzYzBLTKL/ldn9g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@cspell/dict-ada": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-ada/-/dict-ada-4.1.0.tgz",
+ "integrity": "sha512-7SvmhmX170gyPd+uHXrfmqJBY5qLcCX8kTGURPVeGxmt8XNXT75uu9rnZO+jwrfuU2EimNoArdVy5GZRGljGNg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-al": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-al/-/dict-al-1.1.0.tgz",
+ "integrity": "sha512-PtNI1KLmYkELYltbzuoztBxfi11jcE9HXBHCpID2lou/J4VMYKJPNqe4ZjVzSI9NYbMnMnyG3gkbhIdx66VSXg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-aws": {
+ "version": "4.0.9",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-aws/-/dict-aws-4.0.9.tgz",
+ "integrity": "sha512-bDYdnnJGwSkIZ4gzrauu7qzOs/ZAY/FnU4k11LgdMI8BhwMfsbsy2EI1iS+sD/BI5ZnNT9kU5YR3WADeNOmhRg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-bash": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-bash/-/dict-bash-4.2.0.tgz",
+ "integrity": "sha512-HOyOS+4AbCArZHs/wMxX/apRkjxg6NDWdt0jF9i9XkvJQUltMwEhyA2TWYjQ0kssBsnof+9amax2lhiZnh3kCg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@cspell/dict-shell": "1.1.0"
+ }
+ },
+ "node_modules/@cspell/dict-companies": {
+ "version": "3.1.14",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-companies/-/dict-companies-3.1.14.tgz",
+ "integrity": "sha512-iqo1Ce4L7h0l0GFSicm2wCLtfuymwkvgFGhmu9UHyuIcTbdFkDErH+m6lH3Ed+QuskJlpQ9dM7puMIGqUlVERw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-cpp": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-cpp/-/dict-cpp-6.0.3.tgz",
+ "integrity": "sha512-OFrVXdxCeGKnon36Pe3yFjBuY4kzzEwWFf3vDz+cJTodZDkjFkBifQeTtt5YfimgF8cfAJZXkBCsxjipAgmAiw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-cryptocurrencies": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-cryptocurrencies/-/dict-cryptocurrencies-5.0.4.tgz",
+ "integrity": "sha512-6iFu7Abu+4Mgqq08YhTKHfH59mpMpGTwdzDB2Y8bbgiwnGFCeoiSkVkgLn1Kel2++hYcZ8vsAW/MJS9oXxuMag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-csharp": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-csharp/-/dict-csharp-4.0.6.tgz",
+ "integrity": "sha512-w/+YsqOknjQXmIlWDRmkW+BHBPJZ/XDrfJhZRQnp0wzpPOGml7W0q1iae65P2AFRtTdPKYmvSz7AL5ZRkCnSIw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-css": {
+ "version": "4.0.17",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-css/-/dict-css-4.0.17.tgz",
+ "integrity": "sha512-2EisRLHk6X/PdicybwlajLGKF5aJf4xnX2uuG5lexuYKt05xV/J/OiBADmi8q9obhxf1nesrMQbqAt+6CsHo/w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-dart": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-dart/-/dict-dart-2.3.0.tgz",
+ "integrity": "sha512-1aY90lAicek8vYczGPDKr70pQSTQHwMFLbmWKTAI6iavmb1fisJBS1oTmMOKE4ximDf86MvVN6Ucwx3u/8HqLg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-data-science": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-data-science/-/dict-data-science-2.0.7.tgz",
+ "integrity": "sha512-XhAkK+nSW6zmrnWzusmZ1BpYLc62AWYHZc2p17u4nE2Z9XG5DleG55PCZxXQTKz90pmwlhFM9AfpkJsYaBWATA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-django": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-django/-/dict-django-4.1.4.tgz",
+ "integrity": "sha512-fX38eUoPvytZ/2GA+g4bbdUtCMGNFSLbdJJPKX2vbewIQGfgSFJKY56vvcHJKAvw7FopjvgyS/98Ta9WN1gckg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-docker": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-docker/-/dict-docker-1.1.12.tgz",
+ "integrity": "sha512-6d25ZPBnYZaT9D9An/x6g/4mk542R8bR3ipnby3QFCxnfdd6xaWiTcwDPsCgwN2aQZIQ1jX/fil9KmBEqIK/qA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-dotnet": {
+ "version": "5.0.9",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-dotnet/-/dict-dotnet-5.0.9.tgz",
+ "integrity": "sha512-JGD6RJW5sHtO5lfiJl11a5DpPN6eKSz5M1YBa1I76j4dDOIqgZB6rQexlDlK1DH9B06X4GdDQwdBfnpAB0r2uQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-elixir": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-elixir/-/dict-elixir-4.0.7.tgz",
+ "integrity": "sha512-MAUqlMw73mgtSdxvbAvyRlvc3bYnrDqXQrx5K9SwW8F7fRYf9V4vWYFULh+UWwwkqkhX9w03ZqFYRTdkFku6uA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-en_us": {
+ "version": "4.3.31",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-en_us/-/dict-en_us-4.3.31.tgz",
+ "integrity": "sha512-MDc+1B0aFwQONS0JZ6w7ks2KFGkUcaNTFJ8kI6GHvFRmEl3zP5NJDwFEXFsoEdLDb86j2myauSWMJXR3JFuwbA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-en-common-misspellings": {
+ "version": "2.0.9",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-en-common-misspellings/-/dict-en-common-misspellings-2.0.9.tgz",
+ "integrity": "sha512-O/jAr1VNtuyCFckbTmpeEf43ZFWVD9cJFvWaA6rO2IVmLirJViHWJUyBZOuQcesSplzEIw80MAYmnK06/MDWXQ==",
+ "dev": true,
+ "license": "CC BY-SA 4.0"
+ },
+ "node_modules/@cspell/dict-en-gb": {
+ "version": "1.1.33",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-en-gb/-/dict-en-gb-1.1.33.tgz",
+ "integrity": "sha512-tKSSUf9BJEV+GJQAYGw5e+ouhEe2ZXE620S7BLKe3ZmpnjlNG9JqlnaBhkIMxKnNFkLY2BP/EARzw31AZnOv4g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-filetypes": {
+ "version": "3.0.11",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-filetypes/-/dict-filetypes-3.0.11.tgz",
+ "integrity": "sha512-bBtCHZLo7MiSRUqx5KEiPdGOmXIlDGY+L7SJEtRWZENpAKE+96rT7hj+TUUYWBbCzheqHr0OXZJFEKDgsG/uZg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-flutter": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-flutter/-/dict-flutter-1.1.0.tgz",
+ "integrity": "sha512-3zDeS7zc2p8tr9YH9tfbOEYfopKY/srNsAa+kE3rfBTtQERAZeOhe5yxrnTPoufctXLyuUtcGMUTpxr3dO0iaA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-fonts": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-fonts/-/dict-fonts-4.0.4.tgz",
+ "integrity": "sha512-cHFho4hjojBcHl6qxidl9CvUb492IuSk7xIf2G2wJzcHwGaCFa2o3gRcxmIg1j62guetAeDDFELizDaJlVRIOg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-fsharp": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-fsharp/-/dict-fsharp-1.1.0.tgz",
+ "integrity": "sha512-oguWmHhGzgbgbEIBKtgKPrFSVAFtvGHaQS0oj+vacZqMObwkapcTGu7iwf4V3Bc2T3caf0QE6f6rQfIJFIAVsw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-fullstack": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-fullstack/-/dict-fullstack-3.2.4.tgz",
+ "integrity": "sha512-JRRvaOLBZ13BO9sP395W+06tyO1Jy/87aFlKe9xQiCWMiwpCo2kGq0xBGq0PDWe253lYLs+GKrNmLU0fSxrObg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-gaming-terms": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-gaming-terms/-/dict-gaming-terms-1.1.0.tgz",
+ "integrity": "sha512-46AnDs9XkgJ2f1Sqol1WgfJ8gOqp60fojpc9Wxch7x+BA63g4JfMV5/M5x0sI0TLlLY8EBSglcr8wQF/7C80AQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-git": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-git/-/dict-git-3.0.4.tgz",
+ "integrity": "sha512-C44M+m56rYn6QCsLbiKiedyPTMZxlDdEYAsPwwlL5bhMDDzXZ3Ic8OCQIhMbiunhCOJJT+er4URmOmM+sllnjg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-golang": {
+ "version": "6.0.18",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-golang/-/dict-golang-6.0.18.tgz",
+ "integrity": "sha512-Mt+7NwfodDwUk7423DdaQa0YaA+4UoV3XSxQwZioqjpFBCuxfvvv4l80MxCTAAbK6duGj0uHbGTwpv8fyKYPKg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-google": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-google/-/dict-google-1.0.8.tgz",
+ "integrity": "sha512-BnMHgcEeaLyloPmBs8phCqprI+4r2Jb8rni011A8hE+7FNk7FmLE3kiwxLFrcZnnb7eqM0agW4zUaNoB0P+z8A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-haskell": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-haskell/-/dict-haskell-4.0.5.tgz",
+ "integrity": "sha512-s4BG/4tlj2pPM9Ha7IZYMhUujXDnI0Eq1+38UTTCpatYLbQqDwRFf2KNPLRqkroU+a44yTUAe0rkkKbwy4yRtQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-html": {
+ "version": "4.0.11",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-html/-/dict-html-4.0.11.tgz",
+ "integrity": "sha512-QR3b/PB972SRQ2xICR1Nw/M44IJ6rjypwzA4jn+GH8ydjAX9acFNfc+hLZVyNe0FqsE90Gw3evLCOIF0vy1vQw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-html-symbol-entities": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-html-symbol-entities/-/dict-html-symbol-entities-4.0.3.tgz",
+ "integrity": "sha512-aABXX7dMLNFdSE8aY844X4+hvfK7977sOWgZXo4MTGAmOzR8524fjbJPswIBK7GaD3+SgFZ2yP2o0CFvXDGF+A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-java": {
+ "version": "5.0.11",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-java/-/dict-java-5.0.11.tgz",
+ "integrity": "sha512-T4t/1JqeH33Raa/QK/eQe26FE17eUCtWu+JsYcTLkQTci2dk1DfcIKo8YVHvZXBnuM43ATns9Xs0s+AlqDeH7w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-julia": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-julia/-/dict-julia-1.1.0.tgz",
+ "integrity": "sha512-CPUiesiXwy3HRoBR3joUseTZ9giFPCydSKu2rkh6I2nVjXnl5vFHzOMLXpbF4HQ1tH2CNfnDbUndxD+I+7eL9w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-k8s": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-k8s/-/dict-k8s-1.0.10.tgz",
+ "integrity": "sha512-313haTrX9prep1yWO7N6Xw4D6tvUJ0Xsx+YhCP+5YrrcIKoEw5Rtlg8R4PPzLqe6zibw6aJ+Eqq+y76Vx5BZkw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-kotlin": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-kotlin/-/dict-kotlin-1.1.0.tgz",
+ "integrity": "sha512-vySaVw6atY7LdwvstQowSbdxjXG6jDhjkWVWSjg1XsUckyzH1JRHXe9VahZz1i7dpoFEUOWQrhIe5B9482UyJQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-latex": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-latex/-/dict-latex-4.0.3.tgz",
+ "integrity": "sha512-2KXBt9fSpymYHxHfvhUpjUFyzrmN4c4P8mwIzweLyvqntBT3k0YGZJSriOdjfUjwSygrfEwiuPI1EMrvgrOMJw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-lorem-ipsum": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-lorem-ipsum/-/dict-lorem-ipsum-4.0.4.tgz",
+ "integrity": "sha512-+4f7vtY4dp2b9N5fn0za/UR0kwFq2zDtA62JCbWHbpjvO9wukkbl4rZg4YudHbBgkl73HRnXFgCiwNhdIA1JPw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-lua": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-lua/-/dict-lua-4.0.7.tgz",
+ "integrity": "sha512-Wbr7YSQw+cLHhTYTKV6cAljgMgcY+EUAxVIZW3ljKswEe4OLxnVJ7lPqZF5JKjlXdgCjbPSimsHqyAbC5pQN/Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-makefile": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-makefile/-/dict-makefile-1.0.4.tgz",
+ "integrity": "sha512-E4hG/c0ekPqUBvlkrVvzSoAA+SsDA9bLi4xSV3AXHTVru7Y2bVVGMPtpfF+fI3zTkww/jwinprcU1LSohI3ylw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-markdown": {
+ "version": "2.0.9",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-markdown/-/dict-markdown-2.0.9.tgz",
+ "integrity": "sha512-j2e6Eg18BlTb1mMP1DkyRFMM/FLS7qiZjltpURzDckB57zDZbUyskOFdl4VX7jItZZEeY0fe22bSPOycgS1Z5A==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "@cspell/dict-css": "^4.0.17",
+ "@cspell/dict-html": "^4.0.11",
+ "@cspell/dict-html-symbol-entities": "^4.0.3",
+ "@cspell/dict-typescript": "^3.2.0"
+ }
+ },
+ "node_modules/@cspell/dict-monkeyc": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-monkeyc/-/dict-monkeyc-1.0.10.tgz",
+ "integrity": "sha512-7RTGyKsTIIVqzbvOtAu6Z/lwwxjGRtY5RkKPlXKHEoEAgIXwfDxb5EkVwzGQwQr8hF/D3HrdYbRT8MFBfsueZw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-node": {
+ "version": "5.0.6",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-node/-/dict-node-5.0.6.tgz",
+ "integrity": "sha512-CEbhPCpxGvRNByGolSBTrXXW2rJA4bGqZuTx1KKO85mwR6aadeOmUE7xf/8jiCkXSy+qvr9aJeh+jlfXcsrziQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-npm": {
+ "version": "5.1.26",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-npm/-/dict-npm-5.1.26.tgz",
+ "integrity": "sha512-JU0/9P4nLPPC3Py+sF42tUKm9J4KAvwXaJubp2a4QwhCPzFVlOJTP2tTseFlLbdZn23d61pt0hZ+Jhyy7N76Mg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-php": {
+ "version": "4.0.14",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-php/-/dict-php-4.0.14.tgz",
+ "integrity": "sha512-7zur8pyncYZglxNmqsRycOZ6inpDoVd4yFfz1pQRe5xaRWMiK3Km4n0/X/1YMWhh3e3Sl/fQg5Axb2hlN68t1g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-powershell": {
+ "version": "5.0.14",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-powershell/-/dict-powershell-5.0.14.tgz",
+ "integrity": "sha512-ktjjvtkIUIYmj/SoGBYbr3/+CsRGNXGpvVANrY0wlm/IoGlGywhoTUDYN0IsGwI2b8Vktx3DZmQkfb3Wo38jBA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-public-licenses": {
+ "version": "2.0.13",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-public-licenses/-/dict-public-licenses-2.0.13.tgz",
+ "integrity": "sha512-1Wdp/XH1ieim7CadXYE7YLnUlW0pULEjVl9WEeziZw3EKCAw8ZI8Ih44m4bEa5VNBLnuP5TfqC4iDautAleQzQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-python": {
+ "version": "4.2.15",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-python/-/dict-python-4.2.15.tgz",
+ "integrity": "sha512-VNXhj0Eh+hdHN89MgyaoSAexBQKmYtJaMhucbMI7XmBs4pf8fuFFN3xugk51/A4TZJr8+RImdFFsGMOw+I4bDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@cspell/dict-data-science": "^2.0.7"
+ }
+ },
+ "node_modules/@cspell/dict-r": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-r/-/dict-r-2.1.0.tgz",
+ "integrity": "sha512-k2512wgGG0lTpTYH9w5Wwco+lAMf3Vz7mhqV8+OnalIE7muA0RSuD9tWBjiqLcX8zPvEJr4LdgxVju8Gk3OKyA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-ruby": {
+ "version": "5.0.7",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-ruby/-/dict-ruby-5.0.7.tgz",
+ "integrity": "sha512-4/d0hcoPzi5Alk0FmcyqlzFW9lQnZh9j07MJzPcyVO62nYJJAGKaPZL2o4qHeCS/od/ctJC5AHRdoUm0ktsw6Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-rust": {
+ "version": "4.0.11",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-rust/-/dict-rust-4.0.11.tgz",
+ "integrity": "sha512-OGWDEEzm8HlkSmtD8fV3pEcO2XBpzG2XYjgMCJCRwb2gRKvR+XIm6Dlhs04N/K2kU+iH8bvrqNpM8fS/BFl0uw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-scala": {
+ "version": "5.0.7",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-scala/-/dict-scala-5.0.7.tgz",
+ "integrity": "sha512-yatpSDW/GwulzO3t7hB5peoWwzo+Y3qTc0pO24Jf6f88jsEeKmDeKkfgPbYuCgbE4jisGR4vs4+jfQZDIYmXPA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-shell": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-shell/-/dict-shell-1.1.0.tgz",
+ "integrity": "sha512-D/xHXX7T37BJxNRf5JJHsvziFDvh23IF/KvkZXNSh8VqcRdod3BAz9VGHZf6VDqcZXr1VRqIYR3mQ8DSvs3AVQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-software-terms": {
+ "version": "4.2.5",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-software-terms/-/dict-software-terms-4.2.5.tgz",
+ "integrity": "sha512-CaRzkWti3AgcXoxuRcMijaNG7YUk/MH1rHjB8VX34v3UdCxXXeqvRyElRKnxhFeVLB/robb2UdShqh/CpskxRg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-sql": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-sql/-/dict-sql-2.2.0.tgz",
+ "integrity": "sha512-MUop+d1AHSzXpBvQgQkCiok8Ejzb+nrzyG16E8TvKL2MQeDwnIvMe3bv90eukP6E1HWb+V/MA/4pnq0pcJWKqQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-svelte": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-svelte/-/dict-svelte-1.0.6.tgz",
+ "integrity": "sha512-8LAJHSBdwHCoKCSy72PXXzz7ulGROD0rP1CQ0StOqXOOlTUeSFaJJlxNYjlONgd2c62XBQiN2wgLhtPN+1Zv7Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-swift": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-swift/-/dict-swift-2.0.5.tgz",
+ "integrity": "sha512-3lGzDCwUmnrfckv3Q4eVSW3sK3cHqqHlPprFJZD4nAqt23ot7fic5ALR7J4joHpvDz36nHX34TgcbZNNZOC/JA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-terraform": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-terraform/-/dict-terraform-1.1.0.tgz",
+ "integrity": "sha512-G55pcUUxeXAhejstmD35B47SkFd4uqCQimc+CMgq8Nx0dr03guL2iMsz8faRWQGkCnGimX8S91rbOhDv9p/heg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-typescript": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-typescript/-/dict-typescript-3.2.0.tgz",
+ "integrity": "sha512-Pk3zNePLT8qg51l0M4g1ISowYAEGxTuNfZlgkU5SvHa9Cu7x/BWoyYq9Fvc3kAyoisCjRPyvWF4uRYrPitPDFw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dict-vue": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@cspell/dict-vue/-/dict-vue-3.0.4.tgz",
+ "integrity": "sha512-0dPtI0lwHcAgSiQFx8CzvqjdoXROcH+1LyqgROCpBgppommWpVhbQ0eubnKotFEXgpUCONVkeZJ6Ql8NbTEu+w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@cspell/dynamic-import": {
+ "version": "8.17.3",
+ "resolved": "https://registry.npmjs.org/@cspell/dynamic-import/-/dynamic-import-8.17.3.tgz",
+ "integrity": "sha512-Kg6IJhGHPv+9OxpxaXUpcqgnHEOhMLRWHLyx7FADZ+CJyO4AVeWQfhpTRM6KXhzIl7dPlLG1g8JAQxaoy88KTw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@cspell/url": "8.17.3",
+ "import-meta-resolve": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=18.0"
+ }
+ },
+ "node_modules/@cspell/filetypes": {
+ "version": "8.17.3",
+ "resolved": "https://registry.npmjs.org/@cspell/filetypes/-/filetypes-8.17.3.tgz",
+ "integrity": "sha512-UFqRmJPccOSo+RYP/jZ4cr0s7ni37GrvnNAg1H/qIIxfmBYsexTAmsNzMqxp1M31NeI1Cx3LL7PspPMT0ms+7w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@cspell/strong-weak-map": {
+ "version": "8.17.3",
+ "resolved": "https://registry.npmjs.org/@cspell/strong-weak-map/-/strong-weak-map-8.17.3.tgz",
+ "integrity": "sha512-l/CaFc3CITI/dC+whEBZ05Om0KXR3V2whhVOWOBPIqA5lCjWAyvWWvmFD+CxWd0Hs6Qcb/YDnMyJW14aioXN4g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@cspell/url": {
+ "version": "8.17.3",
+ "resolved": "https://registry.npmjs.org/@cspell/url/-/url-8.17.3.tgz",
+ "integrity": "sha512-gcsCz8g0qY94C8RXiAlUH/89n84Q9RSptP91XrvnLOT+Xva9Aibd7ywd5k9ameuf8Nagyl0ezB1MInZ30S9SRw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.0"
+ }
+ },
"node_modules/@csstools/color-helpers": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.1.tgz",
@@ -3775,6 +4369,13 @@
"@types/node": "*"
}
},
+ "node_modules/@types/trusted-types": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
+ "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
+ "license": "MIT",
+ "optional": true
+ },
"node_modules/@types/ws": {
"version": "8.5.13",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz",
@@ -4400,6 +5001,13 @@
"node": ">=0.10.0"
}
},
+ "node_modules/array-timsort": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz",
+ "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/arrify": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
@@ -5687,6 +6295,35 @@
"node": ">=0.10.0"
}
},
+ "node_modules/chalk-template": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-1.1.0.tgz",
+ "integrity": "sha512-T2VJbcDuZQ0Tb2EWwSotMPJjgpy1/tGee1BTpUNsGZ/qgNjV2t7Mvu+d4600U564nbLesN1x2dPL+xii174Ekg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk-template?sponsor=1"
+ }
+ },
+ "node_modules/chalk-template/node_modules/chalk": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz",
+ "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
"node_modules/check-error": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
@@ -5813,6 +6450,46 @@
"node": ">= 10.0"
}
},
+ "node_modules/clear-module": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/clear-module/-/clear-module-4.1.2.tgz",
+ "integrity": "sha512-LWAxzHqdHsAZlPlEyJ2Poz6AIs384mPeqLVCru2p0BrP9G/kVGuhNyZYClLO6cXlnuJjzC8xtsJIuMjKqLXoAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parent-module": "^2.0.0",
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/clear-module/node_modules/parent-module": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-2.0.0.tgz",
+ "integrity": "sha512-uo0Z9JJeWzv8BG+tRcapBKNJ0dro9cLyczGzulS6EfeyAdeC9sbojtW6XwvYxJkEne9En+J2XEl4zyglVeIwFg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/clear-module/node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/cli-boxes": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz",
@@ -5994,6 +6671,23 @@
"node": ">= 10"
}
},
+ "node_modules/comment-json": {
+ "version": "4.2.5",
+ "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.2.5.tgz",
+ "integrity": "sha512-bKw/r35jR3HGt5PEPm1ljsQQGyCrR8sFGNiN5L+ykDHdpO8Smxkrkla9Yi6NkQyUrb8V54PGhfMs6NrIwtxtdw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-timsort": "^1.0.3",
+ "core-util-is": "^1.0.3",
+ "esprima": "^4.0.1",
+ "has-own-prop": "^2.0.0",
+ "repeat-string": "^1.6.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/comment-parser": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz",
@@ -6492,6 +7186,275 @@
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==",
"license": "MIT"
},
+ "node_modules/cspell": {
+ "version": "8.17.3",
+ "resolved": "https://registry.npmjs.org/cspell/-/cspell-8.17.3.tgz",
+ "integrity": "sha512-fBZg674Dir9y/FWMwm2JyixM/1eB2vnqHJjRxOgGS/ZiZ3QdQ3LkK02Aqvlni8ffWYDZnYnYY9rfWmql9bb42w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@cspell/cspell-json-reporter": "8.17.3",
+ "@cspell/cspell-pipe": "8.17.3",
+ "@cspell/cspell-types": "8.17.3",
+ "@cspell/dynamic-import": "8.17.3",
+ "@cspell/url": "8.17.3",
+ "chalk": "^5.4.1",
+ "chalk-template": "^1.1.0",
+ "commander": "^13.1.0",
+ "cspell-dictionary": "8.17.3",
+ "cspell-gitignore": "8.17.3",
+ "cspell-glob": "8.17.3",
+ "cspell-io": "8.17.3",
+ "cspell-lib": "8.17.3",
+ "fast-json-stable-stringify": "^2.1.0",
+ "file-entry-cache": "^9.1.0",
+ "get-stdin": "^9.0.0",
+ "semver": "^7.6.3",
+ "tinyglobby": "^0.2.10"
+ },
+ "bin": {
+ "cspell": "bin.mjs",
+ "cspell-esm": "bin.mjs"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/streetsidesoftware/cspell?sponsor=1"
+ }
+ },
+ "node_modules/cspell-config-lib": {
+ "version": "8.17.3",
+ "resolved": "https://registry.npmjs.org/cspell-config-lib/-/cspell-config-lib-8.17.3.tgz",
+ "integrity": "sha512-+N32Q6xck3D2RqZIFwq8s0TnzHYMpyh4bgNtYqW5DIP3TLDiA4/MJGjwmLKAg/s9dkre6n8/++vVli3MZAOhIg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@cspell/cspell-types": "8.17.3",
+ "comment-json": "^4.2.5",
+ "yaml": "^2.7.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/cspell-dictionary": {
+ "version": "8.17.3",
+ "resolved": "https://registry.npmjs.org/cspell-dictionary/-/cspell-dictionary-8.17.3.tgz",
+ "integrity": "sha512-89I/lpQKdkX17RCFrUIJnc70Rjfpup/o+ynHZen0hUxGTfLsEJPrK6H2oGvic3Yrv5q8IOtwM1p8vqPqBkBheA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@cspell/cspell-pipe": "8.17.3",
+ "@cspell/cspell-types": "8.17.3",
+ "cspell-trie-lib": "8.17.3",
+ "fast-equals": "^5.2.2"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/cspell-gitignore": {
+ "version": "8.17.3",
+ "resolved": "https://registry.npmjs.org/cspell-gitignore/-/cspell-gitignore-8.17.3.tgz",
+ "integrity": "sha512-rQamjb8R+Nwib/Bpcgf+xv5IdsOHgbP+fe4hCgv0jjgUPkeOR2c4dGwc0WS+2UkJbc+wQohpzBGDLRYGSB/hQw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@cspell/url": "8.17.3",
+ "cspell-glob": "8.17.3",
+ "cspell-io": "8.17.3",
+ "find-up-simple": "^1.0.0"
+ },
+ "bin": {
+ "cspell-gitignore": "bin.mjs"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/cspell-glob": {
+ "version": "8.17.3",
+ "resolved": "https://registry.npmjs.org/cspell-glob/-/cspell-glob-8.17.3.tgz",
+ "integrity": "sha512-0ov9A0E6OuOO7KOxlGCxJ09LR/ubZ6xcGwWc5bu+jp/8onUowQfe+9vZdznj/o8/vcf5JkDzyhRSBsdhWKqoAg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@cspell/url": "8.17.3",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/cspell-grammar": {
+ "version": "8.17.3",
+ "resolved": "https://registry.npmjs.org/cspell-grammar/-/cspell-grammar-8.17.3.tgz",
+ "integrity": "sha512-wfjkkvHthnKJtEaTgx3cPUPquGRXfgXSCwvMJaDyUi36KBlopXX38PejBTdmuqrvp7bINLSuHErml9wAfL5Fxw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@cspell/cspell-pipe": "8.17.3",
+ "@cspell/cspell-types": "8.17.3"
+ },
+ "bin": {
+ "cspell-grammar": "bin.mjs"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/cspell-io": {
+ "version": "8.17.3",
+ "resolved": "https://registry.npmjs.org/cspell-io/-/cspell-io-8.17.3.tgz",
+ "integrity": "sha512-NwEVb3Kr8loV1C8Stz9QSMgUrBkxqf2s7A9H2/RBnfvQBt9CWZS6NgoNxTPwHj3h1sUNl9reDkMQQzkKtgWGBQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@cspell/cspell-service-bus": "8.17.3",
+ "@cspell/url": "8.17.3"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/cspell-lib": {
+ "version": "8.17.3",
+ "resolved": "https://registry.npmjs.org/cspell-lib/-/cspell-lib-8.17.3.tgz",
+ "integrity": "sha512-KpwYIj8HwFyTzCCQcyezlmomvyNfPwZQmqTh4V126sFvf9HLoMdfyq8KYDZmZ//4HzwrF/ufJOF3CpuVUiJHfA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@cspell/cspell-bundled-dicts": "8.17.3",
+ "@cspell/cspell-pipe": "8.17.3",
+ "@cspell/cspell-resolver": "8.17.3",
+ "@cspell/cspell-types": "8.17.3",
+ "@cspell/dynamic-import": "8.17.3",
+ "@cspell/filetypes": "8.17.3",
+ "@cspell/strong-weak-map": "8.17.3",
+ "@cspell/url": "8.17.3",
+ "clear-module": "^4.1.2",
+ "comment-json": "^4.2.5",
+ "cspell-config-lib": "8.17.3",
+ "cspell-dictionary": "8.17.3",
+ "cspell-glob": "8.17.3",
+ "cspell-grammar": "8.17.3",
+ "cspell-io": "8.17.3",
+ "cspell-trie-lib": "8.17.3",
+ "env-paths": "^3.0.0",
+ "fast-equals": "^5.2.2",
+ "gensequence": "^7.0.0",
+ "import-fresh": "^3.3.0",
+ "resolve-from": "^5.0.0",
+ "vscode-languageserver-textdocument": "^1.0.12",
+ "vscode-uri": "^3.0.8",
+ "xdg-basedir": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/cspell-lib/node_modules/env-paths": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz",
+ "integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cspell-lib/node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cspell-trie-lib": {
+ "version": "8.17.3",
+ "resolved": "https://registry.npmjs.org/cspell-trie-lib/-/cspell-trie-lib-8.17.3.tgz",
+ "integrity": "sha512-6LE5BeT2Rwv0bkQckpxX0K1fnFCWfeJ8zVPFtYOaix0trtqj0VNuwWzYDnxyW+OwMioCH29yRAMODa+JDFfUrA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@cspell/cspell-pipe": "8.17.3",
+ "@cspell/cspell-types": "8.17.3",
+ "gensequence": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/cspell/node_modules/chalk": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz",
+ "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/cspell/node_modules/commander": {
+ "version": "13.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz",
+ "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/cspell/node_modules/file-entry-cache": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-9.1.0.tgz",
+ "integrity": "sha512-/pqPFG+FdxWQj+/WSuzXSDaNzxgTLr/OrR1QuqfEZzDakpdYE70PwUxL7BPUa8hpjbvY1+qvCl8k+8Tq34xJgg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/cspell/node_modules/flat-cache": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-5.0.0.tgz",
+ "integrity": "sha512-JrqFmyUl2PnPi1OvLyTVHnQvwQ0S+e6lGSwu8OkAZlSaNIZciTY2H/cOOROxsBA1m/LZNHDsqAgDZt6akWcjsQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.3.1",
+ "keyv": "^4.5.4"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/cspell/node_modules/semver": {
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
+ "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/css-loader": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz",
@@ -7459,6 +8422,15 @@
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
+ "node_modules/dompurify": {
+ "version": "3.2.5",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.5.tgz",
+ "integrity": "sha512-mLPd29uoRe9HpvwP2TxClGQBzGXeEC/we/q+bFlmPPmj2p2Ugl3r6ATu/UU1v77DXNcehiBg9zsr1dREyA/dJQ==",
+ "license": "(MPL-2.0 OR Apache-2.0)",
+ "optionalDependencies": {
+ "@types/trusted-types": "^2.0.7"
+ }
+ },
"node_modules/domutils": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
@@ -8480,6 +9452,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/fast-equals": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.2.2.tgz",
+ "integrity": "sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
"node_modules/fast-glob": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
@@ -8749,6 +9731,19 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/find-up-simple": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.0.tgz",
+ "integrity": "sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/findup-sync": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-5.0.0.tgz",
@@ -9023,6 +10018,16 @@
"node": ">= 4.0.0"
}
},
+ "node_modules/gensequence": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/gensequence/-/gensequence-7.0.0.tgz",
+ "integrity": "sha512-47Frx13aZh01afHJTB3zTtKIlFI6vWY+MYCN9Qpew6i52rfKjnhCF/l1YlC8UmEMvvntZZ6z4PiCcmyuedR2aQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/gensync": {
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -9096,6 +10101,19 @@
"node": ">= 0.4"
}
},
+ "node_modules/get-stdin": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz",
+ "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/get-stream": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
@@ -9198,6 +10216,32 @@
"process": "^0.11.10"
}
},
+ "node_modules/global-directory": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz",
+ "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ini": "4.1.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/global-directory/node_modules/ini": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz",
+ "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
"node_modules/global-modules": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
@@ -9802,6 +10846,27 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/handlebars": {
+ "version": "4.7.8",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz",
+ "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==",
+ "license": "MIT",
+ "dependencies": {
+ "minimist": "^1.2.5",
+ "neo-async": "^2.6.2",
+ "source-map": "^0.6.1",
+ "wordwrap": "^1.0.0"
+ },
+ "bin": {
+ "handlebars": "bin/handlebars"
+ },
+ "engines": {
+ "node": ">=0.4.7"
+ },
+ "optionalDependencies": {
+ "uglify-js": "^3.1.4"
+ }
+ },
"node_modules/has-ansi": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
@@ -9838,6 +10903,16 @@
"node": ">=8"
}
},
+ "node_modules/has-own-prop": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz",
+ "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/has-property-descriptors": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
@@ -9890,6 +10965,11 @@
"node": ">= 0.10"
}
},
+ "node_modules/hash-wasm": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/hash-wasm/-/hash-wasm-4.12.0.tgz",
+ "integrity": "sha512-+/2B2rYLb48I/evdOIhP+K/DD2ca2fgBjp6O+GBEnCDk2e4rpeXIK8GvIyRPjTezgmWn9gmKwkQjjx6BtqDHVQ=="
+ },
"node_modules/hash.js": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
@@ -10369,6 +11449,17 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/import-meta-resolve": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz",
+ "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/imports-loader": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/imports-loader/-/imports-loader-5.0.0.tgz",
@@ -11246,18 +12337,18 @@
"integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==",
"license": "BSD-3-Clause"
},
+ "node_modules/jq-web": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/jq-web/-/jq-web-0.5.1.tgz",
+ "integrity": "sha512-3Fa3E6g3U1O1j46ljy0EM10yRr4txzILga8J7bqOG8F89gZ6Lilz82WG9z6TItWpYEO0YGa4W8yFGj+NMM1xqQ==",
+ "license": "ISC"
+ },
"node_modules/jquery": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz",
"integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==",
"license": "MIT"
},
- "node_modules/js-crc": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/js-crc/-/js-crc-0.2.0.tgz",
- "integrity": "sha512-8DdCSAOACpF8WDAjyDFBC2rj8OS4HUP9mNZBDfl8jCiPCnJG+2bkuycalxwZh6heFy6PrMvoWTp47lp6gzT65A==",
- "license": "MIT"
- },
"node_modules/js-sha3": {
"version": "0.9.3",
"resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.9.3.tgz",
@@ -11403,6 +12494,14 @@
"node": ">=6"
}
},
+ "node_modules/jsonata": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/jsonata/-/jsonata-2.0.6.tgz",
+ "integrity": "sha512-WhQB5tXQ32qjkx2GYHFw2XbL90u+LLzjofAYwi+86g6SyZeXHz9F1Q0amy3dWRYczshOC3Haok9J4pOCgHtwyQ==",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
"node_modules/jsonpath-plus": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-9.0.0.tgz",
@@ -12593,7 +13692,6 @@
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
- "dev": true,
"license": "MIT"
},
"node_modules/netmask": {
@@ -12815,6 +13913,15 @@
"node": ">=8"
}
},
+ "node_modules/nightwatch/node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "dev": true,
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
"node_modules/nightwatch/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
@@ -14900,6 +16007,16 @@
"node": ">=8"
}
},
+ "node_modules/repeat-string": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
"node_modules/require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
@@ -15748,6 +16865,15 @@
"node": ">=0.8.0"
}
},
+ "node_modules/sockjs/node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "dev": true,
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
"node_modules/socks": {
"version": "2.8.3",
"resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz",
@@ -15788,7 +16914,6 @@
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "devOptional": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
@@ -16486,6 +17611,48 @@
"integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==",
"license": "MIT"
},
+ "node_modules/tinyglobby": {
+ "version": "0.2.10",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.10.tgz",
+ "integrity": "sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.4.2",
+ "picomatch": "^4.0.2"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/tinyglobby/node_modules/fdir": {
+ "version": "6.4.3",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz",
+ "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/tinyglobby/node_modules/picomatch": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
+ "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
"node_modules/tmp": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz",
@@ -16993,13 +18160,15 @@
}
},
"node_modules/uuid": {
- "version": "8.3.2",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
- "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
- "dev": true,
- "license": "MIT",
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz",
+ "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==",
+ "funding": [
+ "https://github.com/sponsors/broofa",
+ "https://github.com/sponsors/ctavan"
+ ],
"bin": {
- "uuid": "dist/bin/uuid"
+ "uuid": "dist/esm/bin/uuid"
}
},
"node_modules/v8flags": {
@@ -17031,6 +18200,20 @@
"integrity": "sha512-2ozZEFfmVvQcHWoHLNuiKlUfDKlhh4KGsy54U0UrlLMR1SO+XKAIDqBxtBwHgNrekurlJwE8A9K6L49T78ZQ9Q==",
"license": "MIT"
},
+ "node_modules/vscode-languageserver-textdocument": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz",
+ "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/vscode-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz",
+ "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/w3c-keyname": {
"version": "2.2.8",
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
@@ -17750,6 +18933,12 @@
"node": ">=0.10.0"
}
},
+ "node_modules/wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==",
+ "license": "MIT"
+ },
"node_modules/worker-loader": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-3.0.8.tgz",
@@ -17941,6 +19130,19 @@
}
}
},
+ "node_modules/xdg-basedir": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz",
+ "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/xhr": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/xhr/-/xhr-2.6.0.tgz",
@@ -18042,6 +19244,19 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/yaml": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz",
+ "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "yaml": "bin.mjs"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
"node_modules/yargs": {
"version": "16.2.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
diff --git a/package.json b/package.json
index 7c8a97de0..9191ab6f0 100644
--- a/package.json
+++ b/package.json
@@ -61,6 +61,7 @@
"compression-webpack-plugin": "^11.1.0",
"copy-webpack-plugin": "^12.0.2",
"core-js": "^3.37.1",
+ "cspell": "^8.17.3",
"css-loader": "7.1.2",
"eslint": "^9.4.0",
"eslint-plugin-jsdoc": "^48.2.9",
@@ -122,6 +123,7 @@
"d3": "7.9.0",
"d3-hexbin": "^0.2.2",
"diff": "^5.2.0",
+ "dompurify": "^3.2.5",
"es6-promisify": "^7.0.0",
"escodegen": "^2.1.0",
"esprima": "^4.0.1",
@@ -130,14 +132,17 @@
"file-saver": "^2.0.5",
"flat": "^6.0.1",
"geodesy": "1.1.3",
+ "handlebars": "^4.7.8",
+ "hash-wasm": "^4.12.0",
"highlight.js": "^11.9.0",
"ieee754": "^1.2.1",
"jimp": "^0.22.12",
+ "jq-web": "^0.5.1",
"jquery": "3.7.1",
- "js-crc": "^0.2.0",
"js-sha3": "^0.9.3",
"jsesc": "^3.0.2",
"json5": "^2.2.3",
+ "jsonata": "^2.0.3",
"jsonpath-plus": "^9.0.0",
"jsonwebtoken": "8.5.1",
"jsqr": "^1.4.0",
@@ -178,6 +183,7 @@
"ua-parser-js": "^1.0.38",
"unorm": "^1.6.0",
"utf8": "^3.0.0",
+ "uuid": "^11.1.0",
"vkbeautify": "^0.99.3",
"xpath": "0.0.34",
"xregexp": "^5.1.1",
@@ -193,6 +199,7 @@
"testui": "npx grunt testui",
"testuidev": "npx nightwatch --env=dev",
"lint": "npx grunt lint",
+ "lint:grammar": "cspell ./src",
"postinstall": "npx grunt exec:fixCryptoApiImports && npx grunt exec:fixSnackbarMarkup && npx grunt exec:fixJimpModule",
"newop": "node --experimental-modules --experimental-json-modules src/core/config/scripts/newOperation.mjs",
"minor": "node --experimental-modules --experimental-json-modules src/core/config/scripts/newMinorVersion.mjs",
diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json
index de3ea8826..434c8bb61 100644
--- a/src/core/config/Categories.json
+++ b/src/core/config/Categories.json
@@ -72,6 +72,8 @@
"Avro to JSON",
"CBOR Encode",
"CBOR Decode",
+ "YAML to JSON",
+ "JSON to YAML",
"Caret/M-decode",
"Rison Encode",
"Rison Decode",
@@ -193,7 +195,9 @@
"Parse SSH Host Key",
"Parse CSR",
"Public Key from Certificate",
- "Public Key from Private Key"
+ "Public Key from Private Key",
+ "SM2 Encrypt",
+ "SM2 Decrypt"
]
},
{
@@ -290,6 +294,7 @@
"To Upper case",
"To Lower case",
"Swap case",
+ "Alternating Caps",
"To Case Insensitive Regex",
"From Case Insensitive Regex",
"Add line numbers",
@@ -365,11 +370,13 @@
"Regular expression",
"XPath expression",
"JPath expression",
+ "Jsonata Query",
"CSS selector",
"Extract EXIF",
"Extract ID3",
"Extract Files",
- "RAKE"
+ "RAKE",
+ "Template"
]
},
{
@@ -400,6 +407,7 @@
"name": "Hashing",
"ops": [
"Analyse hash",
+ "Generate all checksums",
"Generate all hashes",
"MD2",
"MD4",
@@ -418,6 +426,7 @@
"Snefru",
"BLAKE2b",
"BLAKE2s",
+ "BLAKE3",
"GOST Hash",
"Streebog",
"SSDEEP",
@@ -441,10 +450,9 @@
"Fletcher-64 Checksum",
"Adler-32 Checksum",
"Luhn Checksum",
- "CRC-8 Checksum",
- "CRC-16 Checksum",
- "CRC-32 Checksum",
- "TCP/IP Checksum"
+ "CRC Checksum",
+ "TCP/IP Checksum",
+ "XOR Checksum"
]
},
{
@@ -465,8 +473,10 @@
"CSS Minify",
"XPath expression",
"JPath expression",
+ "Jq",
"CSS selector",
"PHP Deserialize",
+ "PHP Serialize",
"Microsoft Script Decoder",
"Strip HTML tags",
"Diff",
@@ -541,6 +551,7 @@
"Pseudo-Random Number Generator",
"Generate De Bruijn Sequence",
"Generate UUID",
+ "Analyse UUID",
"Generate TOTP",
"Generate HOTP",
"Generate QR Code",
diff --git a/src/core/lib/Base32.mjs b/src/core/lib/Base32.mjs
new file mode 100644
index 000000000..92b76eca7
--- /dev/null
+++ b/src/core/lib/Base32.mjs
@@ -0,0 +1,23 @@
+// import Utils from "../Utils.mjs";
+
+/**
+ * Base32 resources.
+ *
+ * @author Peter C-S [petercs@purelymail.com]
+ * @license Apache-2.0
+ */
+
+/**
+ * Base32 alphabets.
+ */
+export const ALPHABET_OPTIONS = [
+ {
+ name: "Standard", // https://www.rfc-editor.org/rfc/rfc4648#section-6
+ value: "A-Z2-7=",
+ },
+ {
+ name: "Hex Extended", // https://www.rfc-editor.org/rfc/rfc4648#section-7
+ value: "0-9A-V=",
+ },
+];
+
diff --git a/src/core/lib/Extract.mjs b/src/core/lib/Extract.mjs
index 18fec28cf..3de2dd6d2 100644
--- a/src/core/lib/Extract.mjs
+++ b/src/core/lib/Extract.mjs
@@ -62,3 +62,9 @@ export const URL_REGEX = new RegExp(protocol + hostname + "(?:" + port + ")?(?:"
* Domain name regular expression
*/
export const DOMAIN_REGEX = /\b((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}\b/ig;
+
+
+/**
+ * DMARC Domain name regular expression
+ */
+export const DMARC_DOMAIN_REGEX = /\b((?=[a-z0-9_-]{1,63}\.)(xn--)?[a-z0-9_]+(-[a-z0-9_]+)*\.)+[a-z]{2,63}\b/ig;
diff --git a/src/core/lib/SM2.mjs b/src/core/lib/SM2.mjs
new file mode 100644
index 000000000..e81564106
--- /dev/null
+++ b/src/core/lib/SM2.mjs
@@ -0,0 +1,258 @@
+/**
+ * Utilities and operations utilized for SM2 encryption and decryption
+ * @author flakjacket95 [dflack95@gmail.com]
+ * @copyright Crown Copyright 2024
+ * @license Apache-2.0
+ */
+
+import OperationError from "../errors/OperationError.mjs";
+import { fromHex } from "../lib/Hex.mjs";
+import Utils from "../Utils.mjs";
+import Sm3 from "crypto-api/src/hasher/sm3.mjs";
+import {toHex} from "crypto-api/src/encoder/hex.mjs";
+import r from "jsrsasign";
+
+/**
+ * SM2 Class for encryption and decryption operations
+ */
+export class SM2 {
+ /**
+ * Constructor for SM2 class; sets up with the curve and the output format as specified in user args
+ *
+ * @param {*} curve
+ * @param {*} format
+ */
+ constructor(curve, format) {
+ this.ecParams = null;
+ this.rng = new r.SecureRandom();
+ /*
+ For any additional curve definitions utilized by SM2, add another block like the below for that curve, then add the curve name to the Curve selection dropdown
+ */
+ r.crypto.ECParameterDB.regist(
+ "sm2p256v1", // name / p = 2**256 - 2**224 - 2**96 + 2**64 - 1
+ 256,
+ "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", // p
+ "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", // a
+ "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", // b
+ "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", // n
+ "1", // h
+ "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", // gx
+ "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0", // gy
+ []
+ ); // alias
+ this.ecParams = r.crypto.ECParameterDB.getByName(curve);
+
+ this.format = format;
+ }
+
+ /**
+ * Set the public key coordinates for the SM2 class
+ *
+ * @param {string} publicKeyX
+ * @param {string} publicKeyY
+ */
+ setPublicKey(publicKeyX, publicKeyY) {
+ /*
+ * TODO: This needs some additional length validation; and checking for errors in the decoding process
+ * TODO: Can probably support other public key encoding methods here as well in the future
+ */
+ this.publicKey = this.ecParams.curve.decodePointHex("04" + publicKeyX + publicKeyY);
+
+ if (this.publicKey.isInfinity()) {
+ throw new OperationError("Invalid Public Key");
+ }
+ }
+
+ /**
+ * Set the private key value for the SM2 class
+ *
+ * @param {string} privateKey
+ */
+ setPrivateKey(privateKeyHex) {
+ this.privateKey = new r.BigInteger(privateKeyHex, 16);
+ }
+
+ /**
+ * Main encryption function; takes user input, processes encryption and returns the result in hex (with the components arranged as configured by the user args)
+ *
+ * @param {*} input
+ * @returns {string}
+ */
+ encrypt(input) {
+ const G = this.ecParams.G;
+
+ /*
+ * Compute a new, random public key along the same elliptic curve to form the starting point for our encryption process (record the resulting X and Y as hex to provide as part of the operation output)
+ * k: Randomly generated BigInteger
+ * c1: Result of dotting our curve generator point `G` with the value of `k`
+ */
+ const k = this.generatePublicKey();
+ const c1 = G.multiply(k);
+ const [hexC1X, hexC1Y] = this.getPointAsHex(c1);
+
+ /*
+ * Compute p2 (secret) using the public key, and the chosen k value above
+ */
+ const p2 = this.publicKey.multiply(k);
+
+ /*
+ * Compute the C3 SM3 hash before we transform the array
+ */
+ const c3 = this.c3(p2, input);
+
+ /*
+ * Genreate a proper length encryption key, XOR iteratively, and convert newly encrypted data to hex
+ */
+ const key = this.kdf(p2, input.byteLength);
+ for (let i = 0; i < input.byteLength; i++) {
+ input[i] ^= Utils.ord(key[i]);
+ }
+ const c2 = Buffer.from(input).toString("hex");
+
+ /*
+ * Check user input specs; order the output components as selected
+ */
+ if (this.format === "C1C3C2") {
+ return hexC1X + hexC1Y + c3 + c2;
+ } else {
+ return hexC1X + hexC1Y + c2 + c3;
+ }
+ }
+ /**
+ * Function to decrypt an SM2 encrypted message
+ *
+ * @param {*} input
+ */
+ decrypt(input) {
+ const c1X = input.slice(0, 64);
+ const c1Y = input.slice(64, 128);
+
+ let c3 = "";
+ let c2 = "";
+
+ if (this.format === "C1C3C2") {
+ c3 = input.slice(128, 192);
+ c2 = input.slice(192);
+ } else {
+ c2 = input.slice(128, -64);
+ c3 = input.slice(-64);
+ }
+ c2 = Uint8Array.from(fromHex(c2));
+ const c1 = this.ecParams.curve.decodePointHex("04" + c1X + c1Y);
+
+ /*
+ * Compute the p2 (secret) value by taking the C1 point provided in the encrypted package, and multiplying by the private k value
+ */
+ const p2 = c1.multiply(this.privateKey);
+
+ /*
+ * Similar to encryption; compute sufficient length key material and XOR the input data to recover the original message
+ */
+ const key = this.kdf(p2, c2.byteLength);
+
+ for (let i = 0; i < c2.byteLength; i++) {
+ c2[i] ^= Utils.ord(key[i]);
+ }
+
+ const check = this.c3(p2, c2);
+ if (check === c3) {
+ return c2.buffer;
+ } else {
+ throw new OperationError("Decryption Error -- Computed Hashes Do Not Match");
+ }
+ }
+
+
+ /**
+ * Generates a large random number
+ *
+ * @param {*} limit
+ * @returns
+ */
+ getBigRandom(limit) {
+ return new r.BigInteger(limit.bitLength(), this.rng)
+ .mod(limit.subtract(r.BigInteger.ONE))
+ .add(r.BigInteger.ONE);
+ }
+
+ /**
+ * Helper function for generating a large random K number; utilized for generating our initial C1 point
+ * TODO: Do we need to do any sort of validation on the resulting k values?
+ *
+ * @returns {BigInteger}
+ */
+ generatePublicKey() {
+ const n = this.ecParams.n;
+ const k = this.getBigRandom(n);
+ return k;
+ }
+
+ /**
+ * SM2 Key Derivation Function (KDF); Takes P2 point, and generates a key material stream large enough to encrypt all of the input data
+ *
+ * @param {*} p2
+ * @param {*} len
+ * @returns {string}
+ */
+ kdf(p2, len) {
+ const [hX, hY] = this.getPointAsHex(p2);
+
+ const total = Math.ceil(len / 32) + 1;
+ let cnt = 1;
+
+ let keyMaterial = "";
+
+ while (cnt < total) {
+ const num = Utils.intToByteArray(cnt, 4, "big");
+ const overall = fromHex(hX).concat(fromHex(hY)).concat(num);
+ keyMaterial += this.sm3(overall);
+ cnt++;
+ }
+ return keyMaterial;
+ }
+
+ /**
+ * Calculates the C3 component of our final encrypted payload; which is the SM3 hash of the P2 point and the original, unencrypted input data
+ *
+ * @param {*} p2
+ * @param {*} input
+ * @returns {string}
+ */
+ c3(p2, input) {
+ const [hX, hY] = this.getPointAsHex(p2);
+
+ const overall = fromHex(hX).concat(Array.from(input)).concat(fromHex(hY));
+
+ return toHex(this.sm3(overall));
+
+ }
+
+ /**
+ * SM3 setup helper function; takes input data as an array, processes the hash and returns the result
+ *
+ * @param {*} data
+ * @returns {string}
+ */
+ sm3(data) {
+ const hashData = Utils.arrayBufferToStr(Uint8Array.from(data).buffer, false);
+ const hasher = new Sm3();
+ hasher.update(hashData);
+ return hasher.finalize();
+ }
+
+ /**
+ * Utility function, returns an elliptic curve points X and Y values as hex;
+ *
+ * @param {EcPointFp} point
+ * @returns {[]}
+ */
+ getPointAsHex(point) {
+ const biX = point.getX().toBigInteger();
+ const biY = point.getY().toBigInteger();
+
+ const charlen = this.ecParams.keycharlen;
+ const hX = ("0000000000" + biX.toString(16)).slice(- charlen);
+ const hY = ("0000000000" + biY.toString(16)).slice(- charlen);
+ return [hX, hY];
+ }
+}
diff --git a/src/core/operations/AESDecrypt.mjs b/src/core/operations/AESDecrypt.mjs
index e24a5119b..5e6cec264 100644
--- a/src/core/operations/AESDecrypt.mjs
+++ b/src/core/operations/AESDecrypt.mjs
@@ -112,7 +112,7 @@ class AESDecrypt extends Operation {
run(input, args) {
const key = Utils.convertToByteString(args[0].string, args[0].option),
iv = Utils.convertToByteString(args[1].string, args[1].option),
- mode = args[2].substring(0, 3),
+ mode = args[2].split("/")[0],
noPadding = args[2].endsWith("NoPadding"),
inputType = args[3],
outputType = args[4],
diff --git a/src/core/operations/AESEncrypt.mjs b/src/core/operations/AESEncrypt.mjs
index 7b52ff039..84e1c5405 100644
--- a/src/core/operations/AESEncrypt.mjs
+++ b/src/core/operations/AESEncrypt.mjs
@@ -66,6 +66,14 @@ class AESEncrypt extends Operation {
{
name: "ECB",
off: [5]
+ },
+ {
+ name: "CBC/NoPadding",
+ off: [5]
+ },
+ {
+ name: "ECB/NoPadding",
+ off: [5]
}
]
},
@@ -98,7 +106,8 @@ class AESEncrypt extends Operation {
run(input, args) {
const key = Utils.convertToByteString(args[0].string, args[0].option),
iv = Utils.convertToByteString(args[1].string, args[1].option),
- mode = args[2],
+ mode = args[2].split("/")[0],
+ noPadding = args[2].endsWith("NoPadding"),
inputType = args[3],
outputType = args[4],
aad = Utils.convertToByteString(args[5].string, args[5].option);
@@ -114,11 +123,20 @@ The following algorithms will be used based on the size of the key:
input = Utils.convertToByteString(input, inputType);
+ // Handle NoPadding modes
+ if (noPadding && input.length % 16 !== 0) {
+ throw new OperationError("Input length must be a multiple of 16 bytes for NoPadding modes.");
+ }
const cipher = forge.cipher.createCipher("AES-" + mode, key);
cipher.start({
iv: iv,
additionalData: mode === "GCM" ? aad : undefined
});
+ if (noPadding) {
+ cipher.mode.pad = function(output, options) {
+ return true;
+ };
+ }
cipher.update(forge.util.createBuffer(input));
cipher.finish();
diff --git a/src/core/operations/AlternatingCaps.mjs b/src/core/operations/AlternatingCaps.mjs
new file mode 100644
index 000000000..2d54867c4
--- /dev/null
+++ b/src/core/operations/AlternatingCaps.mjs
@@ -0,0 +1,53 @@
+/**
+ * @author sw5678
+ * @copyright Crown Copyright 2023
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation.mjs";
+
+/**
+ * Alternating caps operation
+ */
+class AlternatingCaps extends Operation {
+
+ /**
+ * AlternatingCaps constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "Alternating Caps";
+ this.module = "Default";
+ this.description = "Alternating caps, also known as studly caps, sticky caps, or spongecase is a form of text notation in which the capitalization of letters varies by some pattern, or arbitrarily. An example of this would be spelling 'alternative caps' as 'aLtErNaTiNg CaPs'.";
+ this.infoURL = "https://en.wikipedia.org/wiki/Alternating_caps";
+ this.inputType = "string";
+ this.outputType = "string";
+ this.args= [];
+ }
+
+ /**
+ * @param {string} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ let output = "";
+ let previousCaps = true;
+ for (let i = 0; i < input.length; i++) {
+ // Check if the element is a letter
+ if (!RegExp(/^\p{L}/, "u").test(input[i])) {
+ output += input[i];
+ } else if (previousCaps) {
+ output += input[i].toLowerCase();
+ previousCaps = false;
+ } else {
+ output += input[i].toUpperCase();
+ previousCaps = true;
+ }
+ }
+ return output;
+ }
+}
+
+export default AlternatingCaps;
diff --git a/src/core/operations/AnalyseUUID.mjs b/src/core/operations/AnalyseUUID.mjs
new file mode 100644
index 000000000..b35060179
--- /dev/null
+++ b/src/core/operations/AnalyseUUID.mjs
@@ -0,0 +1,48 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2023
+ * @license Apache-2.0
+ */
+
+import * as uuid from "uuid";
+
+import Operation from "../Operation.mjs";
+import OperationError from "../errors/OperationError.mjs";
+
+/**
+ * Analyse UUID operation
+ */
+class AnalyseUUID extends Operation {
+
+ /**
+ * AnalyseUUID constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "Analyse UUID";
+ this.module = "Crypto";
+ this.description = "Tries to determine information about a given UUID and suggests which version may have been used to generate it";
+ this.infoURL = "https://wikipedia.org/wiki/Universally_unique_identifier";
+ this.inputType = "string";
+ this.outputType = "string";
+ this.args = [];
+ }
+
+ /**
+ * @param {string} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ try {
+ const uuidVersion = uuid.version(input);
+ return "UUID version: " + uuidVersion;
+ } catch (error) {
+ throw new OperationError("Invalid UUID");
+ }
+ }
+
+}
+
+export default AnalyseUUID;
diff --git a/src/core/operations/BLAKE3.mjs b/src/core/operations/BLAKE3.mjs
new file mode 100644
index 000000000..0f686120a
--- /dev/null
+++ b/src/core/operations/BLAKE3.mjs
@@ -0,0 +1,58 @@
+/**
+ * @author xumptex [xumptex@outlook.fr]
+ * @copyright Crown Copyright 2025
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation.mjs";
+import OperationError from "../errors/OperationError.mjs";
+import { blake3 } from "hash-wasm";
+/**
+ * BLAKE3 operation
+ */
+class BLAKE3 extends Operation {
+
+ /**
+ * BLAKE3 constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "BLAKE3";
+ this.module = "Hashing";
+ this.description = "Hashes the input using BLAKE3 (UTF-8 encoded), with an optional key (also UTF-8), and outputs the result in hexadecimal format.";
+ this.infoURL = "https://en.wikipedia.org/wiki/BLAKE_(hash_function)#BLAKE3";
+ this.inputType = "string";
+ this.outputType = "string";
+ this.args = [
+ {
+ "name": "Size (bytes)",
+ "type": "number"
+ }, {
+ "name": "Key",
+ "type": "string",
+ "value": ""
+ }
+ ];
+ }
+
+ /**
+ * @param {string} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ const key = args[1];
+ const size = args[0];
+ // Check if the user want a key hash or not
+ if (key === "") {
+ return blake3(input, size*8);
+ } if (key.length !== 32) {
+ throw new OperationError("The key must be exactly 32 bytes long");
+ }
+ return blake3(input, size*8, key);
+ }
+
+}
+
+export default BLAKE3;
diff --git a/src/core/operations/CRC16Checksum.mjs b/src/core/operations/CRC16Checksum.mjs
deleted file mode 100644
index 035ee04b3..000000000
--- a/src/core/operations/CRC16Checksum.mjs
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * @author n1474335 [n1474335@gmail.com]
- * @copyright Crown Copyright 2016
- * @license Apache-2.0
- */
-
-import Operation from "../Operation.mjs";
-import JSCRC from "js-crc";
-
-/**
- * CRC-16 Checksum operation
- */
-class CRC16Checksum extends Operation {
-
- /**
- * CRC16Checksum constructor
- */
- constructor() {
- super();
-
- this.name = "CRC-16 Checksum";
- this.module = "Crypto";
- this.description = "A cyclic redundancy check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to raw data.
The CRC was invented by W. Wesley Peterson in 1961.";
- this.infoURL = "https://wikipedia.org/wiki/Cyclic_redundancy_check";
- this.inputType = "ArrayBuffer";
- this.outputType = "string";
- this.args = [];
- }
-
- /**
- * @param {ArrayBuffer} input
- * @param {Object[]} args
- * @returns {string}
- */
- run(input, args) {
- return JSCRC.crc16(input);
- }
-
-}
-
-export default CRC16Checksum;
diff --git a/src/core/operations/CRC32Checksum.mjs b/src/core/operations/CRC32Checksum.mjs
deleted file mode 100644
index cfe846438..000000000
--- a/src/core/operations/CRC32Checksum.mjs
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * @author n1474335 [n1474335@gmail.com]
- * @copyright Crown Copyright 2016
- * @license Apache-2.0
- */
-
-import Operation from "../Operation.mjs";
-import JSCRC from "js-crc";
-
-/**
- * CRC-32 Checksum operation
- */
-class CRC32Checksum extends Operation {
-
- /**
- * CRC32Checksum constructor
- */
- constructor() {
- super();
-
- this.name = "CRC-32 Checksum";
- this.module = "Crypto";
- this.description = "A cyclic redundancy check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to raw data.
The CRC was invented by W. Wesley Peterson in 1961; the 32-bit CRC function of Ethernet and many other standards is the work of several researchers and was published in 1975.";
- this.infoURL = "https://wikipedia.org/wiki/Cyclic_redundancy_check";
- this.inputType = "ArrayBuffer";
- this.outputType = "string";
- this.args = [];
- }
-
- /**
- * @param {ArrayBuffer} input
- * @param {Object[]} args
- * @returns {string}
- */
- run(input, args) {
- return JSCRC.crc32(input);
- }
-
-}
-
-export default CRC32Checksum;
diff --git a/src/core/operations/CRC8Checksum.mjs b/src/core/operations/CRC8Checksum.mjs
deleted file mode 100644
index 193cadf98..000000000
--- a/src/core/operations/CRC8Checksum.mjs
+++ /dev/null
@@ -1,157 +0,0 @@
-/**
- * @author mshwed [m@ttshwed.com]
- * @copyright Crown Copyright 2019
- * @license Apache-2.0
- */
-
-import Operation from "../Operation.mjs";
-import OperationError from "../errors/OperationError.mjs";
-
-import { toHexFast } from "../lib/Hex.mjs";
-
-/**
- * CRC-8 Checksum operation
- */
-class CRC8Checksum extends Operation {
-
- /**
- * CRC8Checksum constructor
- */
- constructor() {
- super();
-
- this.name = "CRC-8 Checksum";
- this.module = "Crypto";
- this.description = "A cyclic redundancy check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to raw data.
The CRC was invented by W. Wesley Peterson in 1961.";
- this.infoURL = "https://wikipedia.org/wiki/Cyclic_redundancy_check";
- this.inputType = "ArrayBuffer";
- this.outputType = "string";
- this.args = [
- {
- "name": "Algorithm",
- "type": "option",
- "value": [
- "CRC-8",
- "CRC-8/CDMA2000",
- "CRC-8/DARC",
- "CRC-8/DVB-S2",
- "CRC-8/EBU",
- "CRC-8/I-CODE",
- "CRC-8/ITU",
- "CRC-8/MAXIM",
- "CRC-8/ROHC",
- "CRC-8/WCDMA"
- ]
- }
- ];
- }
-
- /**
- * Generates the pre-computed lookup table for byte division
- *
- * @param polynomial
- */
- calculateCRC8LookupTable(polynomial) {
- const crc8Table = new Uint8Array(256);
-
- let currentByte;
- for (let i = 0; i < 256; i++) {
- currentByte = i;
- for (let bit = 0; bit < 8; bit++) {
- if ((currentByte & 0x80) !== 0) {
- currentByte <<= 1;
- currentByte ^= polynomial;
- } else {
- currentByte <<= 1;
- }
- }
-
- crc8Table[i] = currentByte;
- }
-
- return crc8Table;
- }
-
- /**
- * Calculates the CRC-8 Checksum from an input
- *
- * @param {ArrayBuffer} input
- * @param {number} polynomial
- * @param {number} initializationValue
- * @param {boolean} inputReflection
- * @param {boolean} outputReflection
- * @param {number} xorOut
- */
- calculateCRC8(input, polynomial, initializationValue, inputReflection, outputReflection, xorOut) {
- const crcSize = 8;
- const crcTable = this.calculateCRC8LookupTable(polynomial);
-
- let crc = initializationValue !== 0 ? initializationValue : 0;
- let currentByte, position;
-
- input = new Uint8Array(input);
- for (const inputByte of input) {
- currentByte = inputReflection ? this.reverseBits(inputByte, crcSize) : inputByte;
-
- position = (currentByte ^ crc) & 255;
- crc = crcTable[position];
- }
-
- crc = outputReflection ? this.reverseBits(crc, crcSize) : crc;
-
- if (xorOut !== 0) crc = crc ^ xorOut;
-
- return toHexFast(new Uint8Array([crc]));
- }
-
- /**
- * Reverse the bits for a given input byte.
- *
- * @param {number} input
- */
- reverseBits(input, hashSize) {
- let reversedByte = 0;
- for (let i = hashSize - 1; i >= 0; i--) {
- reversedByte |= ((input & 1) << i);
- input >>= 1;
- }
-
- return reversedByte;
- }
-
- /**
- * @param {ArrayBuffer} input
- * @param {Object[]} args
- * @returns {string}
- */
- run(input, args) {
- const algorithm = args[0];
-
- switch (algorithm) {
- case "CRC-8":
- return this.calculateCRC8(input, 0x7, 0x0, false, false, 0x0);
- case "CRC-8/CDMA2000":
- return this.calculateCRC8(input, 0x9B, 0xFF, false, false, 0x0);
- case "CRC-8/DARC":
- return this.calculateCRC8(input, 0x39, 0x0, true, true, 0x0);
- case "CRC-8/DVB-S2":
- return this.calculateCRC8(input, 0xD5, 0x0, false, false, 0x0);
- case "CRC-8/EBU":
- return this.calculateCRC8(input, 0x1D, 0xFF, true, true, 0x0);
- case "CRC-8/I-CODE":
- return this.calculateCRC8(input, 0x1D, 0xFD, false, false, 0x0);
- case "CRC-8/ITU":
- return this.calculateCRC8(input, 0x7, 0x0, false, false, 0x55);
- case "CRC-8/MAXIM":
- return this.calculateCRC8(input, 0x31, 0x0, true, true, 0x0);
- case "CRC-8/ROHC":
- return this.calculateCRC8(input, 0x7, 0xFF, true, true, 0x0);
- case "CRC-8/WCDMA":
- return this.calculateCRC8(input, 0x9B, 0x0, true, true, 0x0);
- default:
- throw new OperationError("Unknown checksum algorithm");
- }
- }
-}
-
-export default CRC8Checksum;
diff --git a/src/core/operations/CRCChecksum.mjs b/src/core/operations/CRCChecksum.mjs
new file mode 100644
index 000000000..88da2fa5a
--- /dev/null
+++ b/src/core/operations/CRCChecksum.mjs
@@ -0,0 +1,1110 @@
+/**
+ * @author r4mos [2k95ljkhg@mozmail.com]
+ * @copyright Crown Copyright 2025
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation.mjs";
+import OperationError from "../errors/OperationError.mjs";
+
+/**
+ * CRC Checksum operation
+ */
+class CRCChecksum extends Operation {
+
+ /**
+ * CRCChecksum constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "CRC Checksum";
+ this.module = "Default";
+ this.description = "A Cyclic Redundancy Check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to raw data.";
+ this.infoURL = "https://wikipedia.org/wiki/Cyclic_redundancy_check";
+ this.inputType = "ArrayBuffer";
+ this.outputType = "string";
+ this.args = [
+ {
+ name: "Algorithm",
+ type: "argSelector",
+ value: [
+ {
+ name: "Custom",
+ on: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-3/GSM",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-3/ROHC",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-4/G-704",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-4/INTERLAKEN",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-4/ITU",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-5/EPC",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-5/EPC-C1G2",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-5/G-704",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-5/ITU",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-5/USB",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-6/CDMA2000-A",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-6/CDMA2000-B",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-6/DARC",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-6/G-704",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-6/GSM",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-6/ITU",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-7/MMC",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-7/ROHC",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-7/UMTS",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-8",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-8/8H2F",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-8/AES",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-8/AUTOSAR",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-8/BLUETOOTH",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-8/CDMA2000",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-8/DARC",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-8/DVB-S2",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-8/EBU",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-8/GSM-A",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-8/GSM-B",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-8/HITAG",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-8/I-432-1",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-8/I-CODE",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-8/ITU",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-8/LTE",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-8/MAXIM",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-8/MAXIM-DOW",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-8/MIFARE-MAD",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-8/NRSC-5",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-8/OPENSAFETY",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-8/ROHC",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-8/SAE-J1850",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-8/SAE-J1850-ZERO",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-8/SMBUS",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-8/TECH-3250",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-8/WCDMA",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-10/ATM",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-10/CDMA2000",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-10/GSM",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-10/I-610",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-11/FLEXRAY",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-11/UMTS",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-12/3GPP",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-12/CDMA2000",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-12/DECT",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-12/GSM",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-12/UMTS",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-13/BBC",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-14/DARC",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-14/GSM",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-15/CAN",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-15/MPT1327",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/A",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/ACORN",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/ARC",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/AUG-CCITT",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/AUTOSAR",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/B",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/BLUETOOTH",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/BUYPASS",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/CCITT",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/CCITT-FALSE",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/CCITT-TRUE",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/CCITT-ZERO",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/CDMA2000",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/CMS",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/DARC",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/DDS-110",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/DECT-R",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/DECT-X",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/DNP",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/EN-13757",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/EPC",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/EPC-C1G2",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/GENIBUS",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/GSM",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/I-CODE",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/IBM",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/IBM-3740",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/IBM-SDLC",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/IEC-61158-2",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/ISO-HDLC",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/ISO-IEC-14443-3-A",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/ISO-IEC-14443-3-B",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/KERMIT",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/LHA",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/LJ1200",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/LTE",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/M17",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/MAXIM",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/MAXIM-DOW",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/MCRF4XX",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/MODBUS",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/NRSC-5",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/OPENSAFETY-A",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/OPENSAFETY-B",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/PROFIBUS",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/RIELLO",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/SPI-FUJITSU",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/T10-DIF",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/TELEDISK",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/TMS37157",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/UMTS",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/USB",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/V-41-LSB",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/V-41-MSB",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/VERIFONE",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/X-25",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/XMODEM",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-16/ZMODEM",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-17/CAN-FD",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-21/CAN-FD",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-24/BLE",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-24/FLEXRAY-A",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-24/FLEXRAY-B",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-24/INTERLAKEN",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-24/LTE-A",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-24/LTE-B",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-24/OPENPGP",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-24/OS-9",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-30/CDMA",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-31/PHILIPS",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32/AAL5",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32/ADCCP",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32/AIXM",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32/AUTOSAR",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32/BASE91-C",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32/BASE91-D",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32/BZIP2",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32/C",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32/CASTAGNOLI",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32/CD-ROM-EDC",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32/CKSUM",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32/D",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32/DECT-B",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32/INTERLAKEN",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32/ISCSI",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32/ISO-HDLC",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32/JAMCRC",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32/MEF",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32/MPEG-2",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32/NVME",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32/PKZIP",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32/POSIX",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32/Q",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32/SATA",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32/V-42",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32/XFER",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-32/XZ",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-40/GSM",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-64/ECMA-182",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-64/GO-ECMA",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-64/GO-ISO",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-64/MS",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-64/NVME",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-64/REDIS",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-64/WE",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-64/XZ",
+ off: [1, 2, 3, 4, 5, 6]
+ },
+ {
+ name: "CRC-82/DARC",
+ off: [1, 2, 3, 4, 5, 6]
+ }
+ ]
+ },
+ {
+ name: "Width (bits)",
+ type: "toggleString",
+ value: "0",
+ toggleValues: ["Decimal"]
+ },
+ {
+ name: "Polynomial",
+ type: "toggleString",
+ value: "0",
+ toggleValues: ["Hex"]
+ },
+ {
+ name: "Initialization",
+ type: "toggleString",
+ value: "0",
+ toggleValues: ["Hex"]
+ },
+ {
+ name: "Reflect input",
+ type: "option",
+ value: ["True", "False"]
+ },
+ {
+ name: "Reflect output",
+ type: "option",
+ value: ["True", "False"]
+ },
+ {
+ name: "Xor Output",
+ type: "toggleString",
+ value: "0",
+ toggleValues: ["Hex"]
+ }
+ ];
+ }
+
+ /**
+ * Reverse the order of bits in a number
+ *
+ * @param {BigInt} data
+ * @param {BigInt} reflect
+ */
+ reflectData(data, reflect) {
+ let value = 0n;
+ for (let bit = 0n; bit < reflect; bit++) {
+ if ((data & 1n) === 1n) {
+ value |= (1n << ((reflect - 1n) - bit));
+ }
+ data >>= 1n;
+ }
+ return value;
+ }
+
+ /**
+ * Performs the CRC Checksum calculation bit per bit without acceleration
+ *
+ * @param {BigInt} width
+ * @param {ArrayBuffer} input
+ * @param {BigInt} poly
+ * @param {BigInt} remainder
+ * @param {boolean} reflectIn
+ * @param {boolean} reflectOut
+ * @param {BigInt} xorOut
+ */
+ calculateCrcBitPerBit(width, input, poly, remainder, reflectIn, reflectOut, xorOut) {
+ const TOP_BIT = 1n << (width - 1n);
+ const MASK = (1n << width) - 1n;
+
+ for (let byte of input) {
+ byte = BigInt(byte);
+ if (reflectIn) {
+ byte = this.reflectData(byte, 8n);
+ }
+
+ for (let i = 0x80n; i !== 0n; i >>= 1n) {
+ let bit = remainder & TOP_BIT;
+
+ remainder = (remainder << 1n) & MASK;
+
+ if ((byte & i) !== 0n) {
+ bit ^= TOP_BIT;
+ }
+
+ if (bit !== 0n) {
+ remainder ^= poly;
+ }
+ }
+ }
+
+ if (reflectOut) {
+ remainder = this.reflectData(remainder, width);
+ }
+
+ return remainder ^ xorOut;
+ }
+
+ /**
+ * Generates the necessary table to speed up the calculation
+ *
+ * @param {BigInt} width
+ * @param {BigInt} poly
+ * @param {BigInt} MASK
+ * @param {BigInt} TOP_BIT
+ */
+ generateTable(width, poly, MASK, TOP_BIT) {
+ const table = new Array(256n);
+ for (let byte = 0n; byte < 256n; byte++) {
+ let value = ((byte << width - 8n) & MASK);
+ for (let bit = 0n; bit < 8n; bit++) {
+ value = (value & TOP_BIT) === 0n ?
+ ((value << 1n) & MASK) :
+ ((value << 1n) & MASK) ^ poly;
+ }
+ table[byte] = value;
+ }
+ return table;
+ }
+
+ /**
+ * Performs the CRC Checksum calculation byte per byte using a computed table to accelerate it
+ *
+ * @param {BigInt} width
+ * @param {ArrayBuffer} input
+ * @param {BigInt} poly
+ * @param {BigInt} remainder
+ * @param {boolean} reflectIn
+ * @param {boolean} reflectOut
+ * @param {BigInt} xorOut
+ */
+ calculateCrcBytePerByte(width, input, poly, remainder, reflectIn, reflectOut, xorOut) {
+ const TOP_BIT = 1n << (width - 1n);
+ const MASK = (1n << width) - 1n;
+ const TABLE = this.generateTable(width, poly, MASK, TOP_BIT);
+
+ for (let byte of input) {
+ byte = BigInt(byte);
+ if (reflectIn) {
+ byte = this.reflectData(byte, 8n);
+ }
+ remainder ^= (byte << width - 8n) & MASK;
+
+ const INDEX = remainder >> width - 8n;
+ remainder = (remainder << 8n) & MASK;
+ remainder ^= TABLE[INDEX];
+ }
+
+ if (reflectOut) {
+ remainder = this.reflectData(remainder, width);
+ }
+ return remainder ^ xorOut;
+ }
+
+ /**
+ * Calculates the CRC Checksum using Bigint (https://developer.mozilla.org/en-US/docs/Glossary/BigInt)
+ *
+ * @param {BigInt} width
+ * @param {ArrayBuffer} input
+ * @param {BigInt} poly
+ * @param {BigInt} init
+ * @param {boolean} reflectIn
+ * @param {boolean} reflectOut
+ * @param {BigInt} xorOut
+ */
+ crc(width, input, poly, init, reflectIn, reflectOut, xorOut) {
+ const VALUE = width < 8n ?
+ this.calculateCrcBitPerBit(width, input, poly, init, reflectIn, reflectOut, xorOut) :
+ this.calculateCrcBytePerByte(width, input, poly, init, reflectIn, reflectOut, xorOut);
+
+ return VALUE.toString(16).padStart(Math.ceil(Number(width) / 4), "0");
+ }
+
+ /**
+ * Validates user input to perform a custom CRC
+ *
+ * @param {Object} widthObject
+ * @param {ArrayBuffer} input
+ * @param {Object} polyObject
+ * @param {Object} initObject
+ * @param {Object} reflectInObject
+ * @param {Object} reflectOutObject
+ * @param {Object} xorOutObject
+ */
+ custom(widthObject, input, polyObject, initObject, reflectInObject, reflectOutObject, xorOutObject) {
+ try {
+ const width = BigInt(widthObject.string);
+ const poly = BigInt("0x" + polyObject.string);
+ const init = BigInt("0x" + initObject.string);
+ const reflectIn = reflectInObject === "True";
+ const reflectOut = reflectOutObject === "True";
+ const xorOut = BigInt("0x" + xorOutObject.string);
+
+ return this.crc(width, input, poly, init, reflectIn, reflectOut, xorOut);
+ } catch (error) {
+ throw new OperationError("Invalid custom CRC arguments");
+ }
+ }
+
+ /**
+ * Calculation of all known CRCs. Names and constants extracted from https://reveng.sourceforge.io/crc-catalogue/all.htm
+ *
+ * @param {ArrayBuffer} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ const algorithm = args[0];
+ input = new Uint8Array(input);
+
+ switch (algorithm) {
+ case "Custom": return this.custom(args[1], input, args[2], args[3], args[4], args[5], args[6]);
+ case "CRC-3/GSM": return this.crc(3n, input, 0x3n, 0x0n, false, false, 0x7n);
+ case "CRC-3/ROHC": return this.crc(3n, input, 0x3n, 0x7n, true, true, 0x0n);
+ case "CRC-4/G-704": return this.crc(4n, input, 0x3n, 0x0n, true, true, 0x0n);
+ case "CRC-4/INTERLAKEN": return this.crc(4n, input, 0x3n, 0xFn, false, false, 0xFn);
+ case "CRC-4/ITU": return this.crc(4n, input, 0x3n, 0x0n, true, true, 0x0n);
+ case "CRC-5/EPC": return this.crc(5n, input, 0x09n, 0x09n, false, false, 0x00n);
+ case "CRC-5/EPC-C1G2": return this.crc(5n, input, 0x09n, 0x09n, false, false, 0x00n);
+ case "CRC-5/G-704": return this.crc(5n, input, 0x15n, 0x00n, true, true, 0x00n);
+ case "CRC-5/ITU": return this.crc(5n, input, 0x15n, 0x00n, true, true, 0x00n);
+ case "CRC-5/USB": return this.crc(5n, input, 0x05n, 0x1Fn, true, true, 0x1Fn);
+ case "CRC-6/CDMA2000-A": return this.crc(6n, input, 0x27n, 0x3Fn, false, false, 0x00n);
+ case "CRC-6/CDMA2000-B": return this.crc(6n, input, 0x07n, 0x3Fn, false, false, 0x00n);
+ case "CRC-6/DARC": return this.crc(6n, input, 0x19n, 0x00n, true, true, 0x00n);
+ case "CRC-6/G-704": return this.crc(6n, input, 0x03n, 0x00n, true, true, 0x00n);
+ case "CRC-6/GSM": return this.crc(6n, input, 0x2Fn, 0x00n, false, false, 0x3Fn);
+ case "CRC-6/ITU": return this.crc(6n, input, 0x03n, 0x00n, true, true, 0x00n);
+ case "CRC-7/MMC": return this.crc(7n, input, 0x09n, 0x00n, false, false, 0x00n);
+ case "CRC-7/ROHC": return this.crc(7n, input, 0x4Fn, 0x7Fn, true, true, 0x00n);
+ case "CRC-7/UMTS": return this.crc(7n, input, 0x45n, 0x00n, false, false, 0x00n);
+ case "CRC-8": return this.crc(8n, input, 0x07n, 0x00n, false, false, 0x00n);
+ case "CRC-8/8H2F": return this.crc(8n, input, 0x2Fn, 0xFFn, false, false, 0xFFn);
+ case "CRC-8/AES": return this.crc(8n, input, 0x1Dn, 0xFFn, true, true, 0x00n);
+ case "CRC-8/AUTOSAR": return this.crc(8n, input, 0x2Fn, 0xFFn, false, false, 0xFFn);
+ case "CRC-8/BLUETOOTH": return this.crc(8n, input, 0xA7n, 0x00n, true, true, 0x00n);
+ case "CRC-8/CDMA2000": return this.crc(8n, input, 0x9Bn, 0xFFn, false, false, 0x00n);
+ case "CRC-8/DARC": return this.crc(8n, input, 0x39n, 0x00n, true, true, 0x00n);
+ case "CRC-8/DVB-S2": return this.crc(8n, input, 0xD5n, 0x00n, false, false, 0x00n);
+ case "CRC-8/EBU": return this.crc(8n, input, 0x1Dn, 0xFFn, true, true, 0x00n);
+ case "CRC-8/GSM-A": return this.crc(8n, input, 0x1Dn, 0x00n, false, false, 0x00n);
+ case "CRC-8/GSM-B": return this.crc(8n, input, 0x49n, 0x00n, false, false, 0xFFn);
+ case "CRC-8/HITAG": return this.crc(8n, input, 0x1Dn, 0xFFn, false, false, 0x00n);
+ case "CRC-8/I-432-1": return this.crc(8n, input, 0x07n, 0x00n, false, false, 0x55n);
+ case "CRC-8/I-CODE": return this.crc(8n, input, 0x1Dn, 0xFDn, false, false, 0x00n);
+ case "CRC-8/ITU": return this.crc(8n, input, 0x07n, 0x00n, false, false, 0x55n);
+ case "CRC-8/LTE": return this.crc(8n, input, 0x9Bn, 0x00n, false, false, 0x00n);
+ case "CRC-8/MAXIM": return this.crc(8n, input, 0x31n, 0x00n, true, true, 0x00n);
+ case "CRC-8/MAXIM-DOW": return this.crc(8n, input, 0x31n, 0x00n, true, true, 0x00n);
+ case "CRC-8/MIFARE-MAD": return this.crc(8n, input, 0x1Dn, 0xC7n, false, false, 0x00n);
+ case "CRC-8/NRSC-5": return this.crc(8n, input, 0x31n, 0xFFn, false, false, 0x00n);
+ case "CRC-8/OPENSAFETY": return this.crc(8n, input, 0x2Fn, 0x00n, false, false, 0x00n);
+ case "CRC-8/ROHC": return this.crc(8n, input, 0x07n, 0xFFn, true, true, 0x00n);
+ case "CRC-8/SAE-J1850": return this.crc(8n, input, 0x1Dn, 0xFFn, false, false, 0xFFn);
+ case "CRC-8/SAE-J1850-ZERO": return this.crc(8n, input, 0x1Dn, 0x00n, false, false, 0x00n);
+ case "CRC-8/SMBUS": return this.crc(8n, input, 0x07n, 0x00n, false, false, 0x00n);
+ case "CRC-8/TECH-3250": return this.crc(8n, input, 0x1Dn, 0xFFn, true, true, 0x00n);
+ case "CRC-8/WCDMA": return this.crc(8n, input, 0x9Bn, 0x00n, true, true, 0x00n);
+ case "CRC-10/ATM": return this.crc(10n, input, 0x233n, 0x000n, false, false, 0x000n);
+ case "CRC-10/CDMA2000": return this.crc(10n, input, 0x3D9n, 0x3FFn, false, false, 0x000n);
+ case "CRC-10/GSM": return this.crc(10n, input, 0x175n, 0x000n, false, false, 0x3FFn);
+ case "CRC-10/I-610": return this.crc(10n, input, 0x233n, 0x000n, false, false, 0x000n);
+ case "CRC-11/FLEXRAY": return this.crc(11n, input, 0x385n, 0x01An, false, false, 0x000n);
+ case "CRC-11/UMTS": return this.crc(11n, input, 0x307n, 0x000n, false, false, 0x000n);
+ case "CRC-12/3GPP": return this.crc(12n, input, 0x80Fn, 0x000n, false, true, 0x000n);
+ case "CRC-12/CDMA2000": return this.crc(12n, input, 0xF13n, 0xFFFn, false, false, 0x000n);
+ case "CRC-12/DECT": return this.crc(12n, input, 0x80Fn, 0x000n, false, false, 0x000n);
+ case "CRC-12/GSM": return this.crc(12n, input, 0xD31n, 0x000n, false, false, 0xFFFn);
+ case "CRC-12/UMTS": return this.crc(12n, input, 0x80Fn, 0x000n, false, true, 0x000n);
+ case "CRC-13/BBC": return this.crc(13n, input, 0x1CF5n, 0x0000n, false, false, 0x0000n);
+ case "CRC-14/DARC": return this.crc(14n, input, 0x0805n, 0x0000n, true, true, 0x0000n);
+ case "CRC-14/GSM": return this.crc(14n, input, 0x202Dn, 0x0000n, false, false, 0x3FFFn);
+ case "CRC-15/CAN": return this.crc(15n, input, 0x4599n, 0x0000n, false, false, 0x0000n);
+ case "CRC-15/MPT1327": return this.crc(15n, input, 0x6815n, 0x0000n, false, false, 0x0001n);
+ case "CRC-16": return this.crc(16n, input, 0x8005n, 0x0000n, true, true, 0x0000n);
+ case "CRC-16/A": return this.crc(16n, input, 0x1021n, 0xC6C6n, true, true, 0x0000n);
+ case "CRC-16/ACORN": return this.crc(16n, input, 0x1021n, 0x0000n, false, false, 0x0000n);
+ case "CRC-16/ARC": return this.crc(16n, input, 0x8005n, 0x0000n, true, true, 0x0000n);
+ case "CRC-16/AUG-CCITT": return this.crc(16n, input, 0x1021n, 0x1D0Fn, false, false, 0x0000n);
+ case "CRC-16/AUTOSAR": return this.crc(16n, input, 0x1021n, 0xFFFFn, false, false, 0x0000n);
+ case "CRC-16/B": return this.crc(16n, input, 0x1021n, 0xFFFFn, true, true, 0xFFFFn);
+ case "CRC-16/BLUETOOTH": return this.crc(16n, input, 0x1021n, 0x0000n, true, true, 0x0000n);
+ case "CRC-16/BUYPASS": return this.crc(16n, input, 0x8005n, 0x0000n, false, false, 0x0000n);
+ case "CRC-16/CCITT": return this.crc(16n, input, 0x1021n, 0x0000n, true, true, 0x0000n);
+ case "CRC-16/CCITT-FALSE": return this.crc(16n, input, 0x1021n, 0xFFFFn, false, false, 0x0000n);
+ case "CRC-16/CCITT-TRUE": return this.crc(16n, input, 0x1021n, 0x0000n, true, true, 0x0000n);
+ case "CRC-16/CCITT-ZERO": return this.crc(16n, input, 0x1021n, 0x0000n, false, false, 0x0000n);
+ case "CRC-16/CDMA2000": return this.crc(16n, input, 0xC867n, 0xFFFFn, false, false, 0x0000n);
+ case "CRC-16/CMS": return this.crc(16n, input, 0x8005n, 0xFFFFn, false, false, 0x0000n);
+ case "CRC-16/DARC": return this.crc(16n, input, 0x1021n, 0xFFFFn, false, false, 0xFFFFn);
+ case "CRC-16/DDS-110": return this.crc(16n, input, 0x8005n, 0x800Dn, false, false, 0x0000n);
+ case "CRC-16/DECT-R": return this.crc(16n, input, 0x0589n, 0x0000n, false, false, 0x0001n);
+ case "CRC-16/DECT-X": return this.crc(16n, input, 0x0589n, 0x0000n, false, false, 0x0000n);
+ case "CRC-16/DNP": return this.crc(16n, input, 0x3D65n, 0x0000n, true, true, 0xFFFFn);
+ case "CRC-16/EN-13757": return this.crc(16n, input, 0x3D65n, 0x0000n, false, false, 0xFFFFn);
+ case "CRC-16/EPC": return this.crc(16n, input, 0x1021n, 0xFFFFn, false, false, 0xFFFFn);
+ case "CRC-16/EPC-C1G2": return this.crc(16n, input, 0x1021n, 0xFFFFn, false, false, 0xFFFFn);
+ case "CRC-16/GENIBUS": return this.crc(16n, input, 0x1021n, 0xFFFFn, false, false, 0xFFFFn);
+ case "CRC-16/GSM": return this.crc(16n, input, 0x1021n, 0x0000n, false, false, 0xFFFFn);
+ case "CRC-16/I-CODE": return this.crc(16n, input, 0x1021n, 0xFFFFn, false, false, 0xFFFFn);
+ case "CRC-16/IBM": return this.crc(16n, input, 0x8005n, 0x0000n, true, true, 0x0000n);
+ case "CRC-16/IBM-3740": return this.crc(16n, input, 0x1021n, 0xFFFFn, false, false, 0x0000n);
+ case "CRC-16/IBM-SDLC": return this.crc(16n, input, 0x1021n, 0xFFFFn, true, true, 0xFFFFn);
+ case "CRC-16/IEC-61158-2": return this.crc(16n, input, 0x1DCFn, 0xFFFFn, false, false, 0xFFFFn);
+ case "CRC-16/ISO-HDLC": return this.crc(16n, input, 0x1021n, 0xFFFFn, true, true, 0xFFFFn);
+ case "CRC-16/ISO-IEC-14443-3-A": return this.crc(16n, input, 0x1021n, 0xC6C6n, true, true, 0x0000n);
+ case "CRC-16/ISO-IEC-14443-3-B": return this.crc(16n, input, 0x1021n, 0xFFFFn, true, true, 0xFFFFn);
+ case "CRC-16/KERMIT": return this.crc(16n, input, 0x1021n, 0x0000n, true, true, 0x0000n);
+ case "CRC-16/LHA": return this.crc(16n, input, 0x8005n, 0x0000n, true, true, 0x0000n);
+ case "CRC-16/LJ1200": return this.crc(16n, input, 0x6F63n, 0x0000n, false, false, 0x0000n);
+ case "CRC-16/LTE": return this.crc(16n, input, 0x1021n, 0x0000n, false, false, 0x0000n);
+ case "CRC-16/M17": return this.crc(16n, input, 0x5935n, 0xFFFFn, false, false, 0x0000n);
+ case "CRC-16/MAXIM": return this.crc(16n, input, 0x8005n, 0x0000n, true, true, 0xFFFFn);
+ case "CRC-16/MAXIM-DOW": return this.crc(16n, input, 0x8005n, 0x0000n, true, true, 0xFFFFn);
+ case "CRC-16/MCRF4XX": return this.crc(16n, input, 0x1021n, 0xFFFFn, true, true, 0x0000n);
+ case "CRC-16/MODBUS": return this.crc(16n, input, 0x8005n, 0xFFFFn, true, true, 0x0000n);
+ case "CRC-16/NRSC-5": return this.crc(16n, input, 0x080Bn, 0xFFFFn, true, true, 0x0000n);
+ case "CRC-16/OPENSAFETY-A": return this.crc(16n, input, 0x5935n, 0x0000n, false, false, 0x0000n);
+ case "CRC-16/OPENSAFETY-B": return this.crc(16n, input, 0x755Bn, 0x0000n, false, false, 0x0000n);
+ case "CRC-16/PROFIBUS": return this.crc(16n, input, 0x1DCFn, 0xFFFFn, false, false, 0xFFFFn);
+ case "CRC-16/RIELLO": return this.crc(16n, input, 0x1021n, 0xB2AAn, true, true, 0x0000n);
+ case "CRC-16/SPI-FUJITSU": return this.crc(16n, input, 0x1021n, 0x1D0Fn, false, false, 0x0000n);
+ case "CRC-16/T10-DIF": return this.crc(16n, input, 0x8BB7n, 0x0000n, false, false, 0x0000n);
+ case "CRC-16/TELEDISK": return this.crc(16n, input, 0xA097n, 0x0000n, false, false, 0x0000n);
+ case "CRC-16/TMS37157": return this.crc(16n, input, 0x1021n, 0x89ECn, true, true, 0x0000n);
+ case "CRC-16/UMTS": return this.crc(16n, input, 0x8005n, 0x0000n, false, false, 0x0000n);
+ case "CRC-16/USB": return this.crc(16n, input, 0x8005n, 0xFFFFn, true, true, 0xFFFFn);
+ case "CRC-16/V-41-LSB": return this.crc(16n, input, 0x1021n, 0x0000n, true, true, 0x0000n);
+ case "CRC-16/V-41-MSB": return this.crc(16n, input, 0x1021n, 0x0000n, false, false, 0x0000n);
+ case "CRC-16/VERIFONE": return this.crc(16n, input, 0x8005n, 0x0000n, false, false, 0x0000n);
+ case "CRC-16/X-25": return this.crc(16n, input, 0x1021n, 0xFFFFn, true, true, 0xFFFFn);
+ case "CRC-16/XMODEM": return this.crc(16n, input, 0x1021n, 0x0000n, false, false, 0x0000n);
+ case "CRC-16/ZMODEM": return this.crc(16n, input, 0x1021n, 0x0000n, false, false, 0x0000n);
+ case "CRC-17/CAN-FD": return this.crc(17n, input, 0x1685Bn, 0x00000n, false, false, 0x00000n);
+ case "CRC-21/CAN-FD": return this.crc(21n, input, 0x102899n, 0x000000n, false, false, 0x000000n);
+ case "CRC-24/BLE": return this.crc(24n, input, 0x00065Bn, 0x555555n, true, true, 0x000000n);
+ case "CRC-24/FLEXRAY-A": return this.crc(24n, input, 0x5D6DCBn, 0xFEDCBAn, false, false, 0x000000n);
+ case "CRC-24/FLEXRAY-B": return this.crc(24n, input, 0x5D6DCBn, 0xABCDEFn, false, false, 0x000000n);
+ case "CRC-24/INTERLAKEN": return this.crc(24n, input, 0x328B63n, 0xFFFFFFn, false, false, 0xFFFFFFn);
+ case "CRC-24/LTE-A": return this.crc(24n, input, 0x864CFBn, 0x000000n, false, false, 0x000000n);
+ case "CRC-24/LTE-B": return this.crc(24n, input, 0x800063n, 0x000000n, false, false, 0x000000n);
+ case "CRC-24/OPENPGP": return this.crc(24n, input, 0x864CFBn, 0xB704CEn, false, false, 0x000000n);
+ case "CRC-24/OS-9": return this.crc(24n, input, 0x800063n, 0xFFFFFFn, false, false, 0xFFFFFFn);
+ case "CRC-30/CDMA": return this.crc(30n, input, 0x2030B9C7n, 0x3FFFFFFFn, false, false, 0x3FFFFFFFn);
+ case "CRC-31/PHILIPS": return this.crc(31n, input, 0x04C11DB7n, 0x7FFFFFFFn, false, false, 0x7FFFFFFFn);
+ case "CRC-32": return this.crc(32n, input, 0x04C11DB7n, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn);
+ case "CRC-32/AAL5": return this.crc(32n, input, 0x04C11DB7n, 0xFFFFFFFFn, false, false, 0xFFFFFFFFn);
+ case "CRC-32/ADCCP": return this.crc(32n, input, 0x04C11DB7n, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn);
+ case "CRC-32/AIXM": return this.crc(32n, input, 0x814141ABn, 0x00000000n, false, false, 0x00000000n);
+ case "CRC-32/AUTOSAR": return this.crc(32n, input, 0xF4ACFB13n, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn);
+ case "CRC-32/BASE91-C": return this.crc(32n, input, 0x1EDC6F41n, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn);
+ case "CRC-32/BASE91-D": return this.crc(32n, input, 0xA833982Bn, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn);
+ case "CRC-32/BZIP2": return this.crc(32n, input, 0x04C11DB7n, 0xFFFFFFFFn, false, false, 0xFFFFFFFFn);
+ case "CRC-32/C": return this.crc(32n, input, 0x1EDC6F41n, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn);
+ case "CRC-32/CASTAGNOLI": return this.crc(32n, input, 0x1EDC6F41n, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn);
+ case "CRC-32/CD-ROM-EDC": return this.crc(32n, input, 0x8001801Bn, 0x00000000n, true, true, 0x00000000n);
+ case "CRC-32/CKSUM": return this.crc(32n, input, 0x04C11DB7n, 0x00000000n, false, false, 0xFFFFFFFFn);
+ case "CRC-32/D": return this.crc(32n, input, 0xA833982Bn, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn);
+ case "CRC-32/DECT-B": return this.crc(32n, input, 0x04C11DB7n, 0xFFFFFFFFn, false, false, 0xFFFFFFFFn);
+ case "CRC-32/INTERLAKEN": return this.crc(32n, input, 0x1EDC6F41n, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn);
+ case "CRC-32/ISCSI": return this.crc(32n, input, 0x1EDC6F41n, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn);
+ case "CRC-32/ISO-HDLC": return this.crc(32n, input, 0x04C11DB7n, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn);
+ case "CRC-32/JAMCRC": return this.crc(32n, input, 0x04C11DB7n, 0xFFFFFFFFn, true, true, 0x00000000n);
+ case "CRC-32/MEF": return this.crc(32n, input, 0x741B8CD7n, 0xFFFFFFFFn, true, true, 0x00000000n);
+ case "CRC-32/MPEG-2": return this.crc(32n, input, 0x04C11DB7n, 0xFFFFFFFFn, false, false, 0x00000000n);
+ case "CRC-32/NVME": return this.crc(32n, input, 0x1EDC6F41n, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn);
+ case "CRC-32/PKZIP": return this.crc(32n, input, 0x04C11DB7n, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn);
+ case "CRC-32/POSIX": return this.crc(32n, input, 0x04C11DB7n, 0x00000000n, false, false, 0xFFFFFFFFn);
+ case "CRC-32/Q": return this.crc(32n, input, 0x814141ABn, 0x00000000n, false, false, 0x00000000n);
+ case "CRC-32/SATA": return this.crc(32n, input, 0x04C11DB7n, 0x52325032n, false, false, 0x00000000n);
+ case "CRC-32/V-42": return this.crc(32n, input, 0x04C11DB7n, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn);
+ case "CRC-32/XFER": return this.crc(32n, input, 0x000000AFn, 0x00000000n, false, false, 0x00000000n);
+ case "CRC-32/XZ": return this.crc(32n, input, 0x04C11DB7n, 0xFFFFFFFFn, true, true, 0xFFFFFFFFn);
+ case "CRC-40/GSM": return this.crc(40n, input, 0x0004820009n, 0x0000000000n, false, false, 0xFFFFFFFFFFn);
+ case "CRC-64/ECMA-182": return this.crc(64n, input, 0x42F0E1EBA9EA3693n, 0x0000000000000000n, false, false, 0x0000000000000000n);
+ case "CRC-64/GO-ECMA": return this.crc(64n, input, 0x42F0E1EBA9EA3693n, 0xFFFFFFFFFFFFFFFFn, true, true, 0xFFFFFFFFFFFFFFFFn);
+ case "CRC-64/GO-ISO": return this.crc(64n, input, 0x000000000000001Bn, 0xFFFFFFFFFFFFFFFFn, true, true, 0xFFFFFFFFFFFFFFFFn);
+ case "CRC-64/MS": return this.crc(64n, input, 0x259C84CBA6426349n, 0xFFFFFFFFFFFFFFFFn, true, true, 0x0000000000000000n);
+ case "CRC-64/NVME": return this.crc(64n, input, 0xAD93D23594C93659n, 0xFFFFFFFFFFFFFFFFn, true, true, 0xFFFFFFFFFFFFFFFFn);
+ case "CRC-64/REDIS": return this.crc(64n, input, 0xAD93D23594C935A9n, 0x0000000000000000n, true, true, 0x0000000000000000n);
+ case "CRC-64/WE": return this.crc(64n, input, 0x42F0E1EBA9EA3693n, 0xFFFFFFFFFFFFFFFFn, false, false, 0xFFFFFFFFFFFFFFFFn);
+ case "CRC-64/XZ": return this.crc(64n, input, 0x42F0E1EBA9EA3693n, 0xFFFFFFFFFFFFFFFFn, true, true, 0xFFFFFFFFFFFFFFFFn);
+ case "CRC-82/DARC": return this.crc(82n, input, 0x0308C0111011401440411n, 0x000000000000000000000n, true, true, 0x000000000000000000000n);
+ default: throw new OperationError("Unknown checksum algorithm");
+ }
+ }
+
+}
+
+export default CRCChecksum;
diff --git a/src/core/operations/ConvertLeetSpeak.mjs b/src/core/operations/ConvertLeetSpeak.mjs
index 54fa62f6e..1a7cb2fcd 100644
--- a/src/core/operations/ConvertLeetSpeak.mjs
+++ b/src/core/operations/ConvertLeetSpeak.mjs
@@ -18,7 +18,7 @@ class ConvertLeetSpeak extends Operation {
this.name = "Convert Leet Speak";
this.module = "Default";
- this.description = "Converts to and from Leet Speak";
+ this.description = "Converts to and from Leet Speak.";
this.infoURL = "https://wikipedia.org/wiki/Leet";
this.inputType = "string";
this.outputType = "string";
@@ -39,13 +39,16 @@ class ConvertLeetSpeak extends Operation {
*/
run(input, args) {
const direction = args[0];
+
if (direction === "To Leet Speak") {
- return input.replace(/[abcdefghijklmnopqrstuvwxyz]/gi, char => {
- return toLeetMap[char.toLowerCase()] || char;
+ return input.replace(/[a-z]/gi, char => {
+ const leetChar = toLeetMap[char.toLowerCase()] || char;
+ return char === char.toUpperCase() ? leetChar.toUpperCase() : leetChar;
});
} else if (direction === "From Leet Speak") {
- return input.replace(/[48cd3f6h1jklmn0pqr57uvwxyz]/g, char => {
- return fromLeetMap[char] || char;
+ return input.replace(/[48cd3f6h1jklmn0pqr57uvwxyz]/gi, char => {
+ const normalChar = fromLeetMap[char] || char;
+ return normalChar;
});
}
}
diff --git a/src/core/operations/ECDSAVerify.mjs b/src/core/operations/ECDSAVerify.mjs
index 7e46e867d..1f8a53ea6 100644
--- a/src/core/operations/ECDSAVerify.mjs
+++ b/src/core/operations/ECDSAVerify.mjs
@@ -9,6 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
import { fromBase64 } from "../lib/Base64.mjs";
import { toHexFast } from "../lib/Hex.mjs";
import r from "jsrsasign";
+import Utils from "../Utils.mjs";
/**
* ECDSA Verify operation
@@ -59,6 +60,11 @@ class ECDSAVerify extends Operation {
name: "Message",
type: "text",
value: ""
+ },
+ {
+ name: "Message format",
+ type: "option",
+ value: ["Raw", "Hex", "Base64"]
}
];
}
@@ -70,7 +76,7 @@ class ECDSAVerify extends Operation {
*/
run(input, args) {
let inputFormat = args[0];
- const [, mdAlgo, keyPem, msg] = args;
+ const [, mdAlgo, keyPem, msg, msgFormat] = args;
if (keyPem.replace("-----BEGIN PUBLIC KEY-----", "").length === 0) {
throw new OperationError("Please enter a public key.");
@@ -145,7 +151,8 @@ class ECDSAVerify extends Operation {
throw new OperationError("Provided key is not a public key.");
}
sig.init(key);
- sig.updateString(msg);
+ const messageStr = Utils.convertToByteString(msg, msgFormat);
+ sig.updateString(messageStr);
const result = sig.verify(signatureASN1Hex);
return result ? "Verified OK" : "Verification Failure";
}
diff --git a/src/core/operations/ExtractDomains.mjs b/src/core/operations/ExtractDomains.mjs
index c28efbb5b..9e78bf3a2 100644
--- a/src/core/operations/ExtractDomains.mjs
+++ b/src/core/operations/ExtractDomains.mjs
@@ -5,7 +5,7 @@
*/
import Operation from "../Operation.mjs";
-import { search, DOMAIN_REGEX } from "../lib/Extract.mjs";
+import { search, DOMAIN_REGEX, DMARC_DOMAIN_REGEX } from "../lib/Extract.mjs";
import { caseInsensitiveSort } from "../lib/Sort.mjs";
/**
@@ -39,6 +39,11 @@ class ExtractDomains extends Operation {
name: "Unique",
type: "boolean",
value: false
+ },
+ {
+ name: "Underscore (DMARC, DKIM, etc)",
+ type: "boolean",
+ value: false
}
];
}
@@ -49,11 +54,11 @@ class ExtractDomains extends Operation {
* @returns {string}
*/
run(input, args) {
- const [displayTotal, sort, unique] = args;
+ const [displayTotal, sort, unique, dmarc] = args;
const results = search(
input,
- DOMAIN_REGEX,
+ dmarc ? DMARC_DOMAIN_REGEX : DOMAIN_REGEX,
null,
sort ? caseInsensitiveSort : null,
unique
diff --git a/src/core/operations/ExtractEmailAddresses.mjs b/src/core/operations/ExtractEmailAddresses.mjs
index f50e1aaf5..34b838ab3 100644
--- a/src/core/operations/ExtractEmailAddresses.mjs
+++ b/src/core/operations/ExtractEmailAddresses.mjs
@@ -51,7 +51,7 @@ class ExtractEmailAddresses extends Operation {
run(input, args) {
const [displayTotal, sort, unique] = args,
// email regex from: https://www.regextester.com/98066
- regex = /(?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9])?\.)+[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}\])/ig;
+ regex = /(?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9])?\.)+[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\])/ig;
const results = search(
input,
diff --git a/src/core/operations/ExtractIPAddresses.mjs b/src/core/operations/ExtractIPAddresses.mjs
index 97b52478d..b74ec8fe2 100644
--- a/src/core/operations/ExtractIPAddresses.mjs
+++ b/src/core/operations/ExtractIPAddresses.mjs
@@ -21,7 +21,7 @@ class ExtractIPAddresses extends Operation {
this.name = "Extract IP addresses";
this.module = "Regex";
- this.description = "Extracts all IPv4 and IPv6 addresses.
Warning: Given a string 710.65.0.456, this will match 10.65.0.45 so always check the original input!";
+ this.description = "Extracts all IPv4 and IPv6 addresses.
Warning: Given a string 1.2.3.4.5.6.7.8, this will match 1.2.3.4 and 5.6.7.8 so always check the original input!";
this.inputType = "string";
this.outputType = "string";
this.args = [
@@ -65,7 +65,21 @@ class ExtractIPAddresses extends Operation {
*/
run(input, args) {
const [includeIpv4, includeIpv6, removeLocal, displayTotal, sort, unique] = args,
- ipv4 = "(?:(?:\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d|\\d)(?:\\/\\d{1,2})?",
+
+ // IPv4 decimal groups can have values 0 to 255. To construct a regex the following sub-regex is reused:
+ ipv4DecimalByte = "(?:25[0-5]|2[0-4]\\d|1?[0-9]\\d|\\d)",
+ ipv4OctalByte = "(?:0[1-3]?[0-7]{1,2})",
+
+ // Look behind and ahead will be used to exclude matches with additional decimal digits left and right of IP address
+ lookBehind = "(? {
+ const checksumLength = checksum.name.match(new RegExp("-(\\d{1,2})(\\/|$)"))[1];
+ if (length === "All" || length === checksumLength) {
+ const value = checksum.algo.run(new Uint8Array(input), checksum.params || []);
+ output += includeNames ?
+ `${checksum.name}:${" ".repeat(25-checksum.name.length)}${value}\n`:
+ `${value}\n`;
+ }
+ });
+ return output;
+ }
+}
+
+export default GenerateAllChecksums;
diff --git a/src/core/operations/GenerateAllHashes.mjs b/src/core/operations/GenerateAllHashes.mjs
index d9af80658..df09aa858 100644
--- a/src/core/operations/GenerateAllHashes.mjs
+++ b/src/core/operations/GenerateAllHashes.mjs
@@ -22,14 +22,6 @@ import HAS160 from "./HAS160.mjs";
import Whirlpool from "./Whirlpool.mjs";
import SSDEEP from "./SSDEEP.mjs";
import CTPH from "./CTPH.mjs";
-import Fletcher8Checksum from "./Fletcher8Checksum.mjs";
-import Fletcher16Checksum from "./Fletcher16Checksum.mjs";
-import Fletcher32Checksum from "./Fletcher32Checksum.mjs";
-import Fletcher64Checksum from "./Fletcher64Checksum.mjs";
-import Adler32Checksum from "./Adler32Checksum.mjs";
-import CRC8Checksum from "./CRC8Checksum.mjs";
-import CRC16Checksum from "./CRC16Checksum.mjs";
-import CRC32Checksum from "./CRC32Checksum.mjs";
import BLAKE2b from "./BLAKE2b.mjs";
import BLAKE2s from "./BLAKE2s.mjs";
import Streebog from "./Streebog.mjs";
@@ -114,16 +106,6 @@ class GenerateAllHashes extends Operation {
{name: "SSDEEP", algo: (new SSDEEP()), inputType: "str"},
{name: "CTPH", algo: (new CTPH()), inputType: "str"}
];
- this.checksums = [
- {name: "Fletcher-8", algo: (new Fletcher8Checksum), inputType: "byteArray", params: []},
- {name: "Fletcher-16", algo: (new Fletcher16Checksum), inputType: "byteArray", params: []},
- {name: "Fletcher-32", algo: (new Fletcher32Checksum), inputType: "byteArray", params: []},
- {name: "Fletcher-64", algo: (new Fletcher64Checksum), inputType: "byteArray", params: []},
- {name: "Adler-32", algo: (new Adler32Checksum), inputType: "byteArray", params: []},
- {name: "CRC-8", algo: (new CRC8Checksum), inputType: "arrayBuffer", params: ["CRC-8"]},
- {name: "CRC-16", algo: (new CRC16Checksum), inputType: "arrayBuffer", params: []},
- {name: "CRC-32", algo: (new CRC32Checksum), inputType: "arrayBuffer", params: []}
- ];
}
/**
@@ -144,14 +126,6 @@ class GenerateAllHashes extends Operation {
output += this.formatDigest(digest, length, includeNames, hash.name);
});
- if (length === "All") {
- output += "\nChecksums:\n";
- this.checksums.forEach(checksum => {
- digest = this.executeAlgo(checksum.algo, checksum.inputType, checksum.params || []);
- output += this.formatDigest(digest, length, includeNames, checksum.name);
- });
- }
-
return output;
}
diff --git a/src/core/operations/GenerateUUID.mjs b/src/core/operations/GenerateUUID.mjs
index 1ee0faba6..21d063e3e 100644
--- a/src/core/operations/GenerateUUID.mjs
+++ b/src/core/operations/GenerateUUID.mjs
@@ -5,8 +5,8 @@
*/
import Operation from "../Operation.mjs";
-import crypto from "crypto";
-
+import * as uuid from "uuid";
+import OperationError from "../errors/OperationError.mjs";
/**
* Generate UUID operation
*/
@@ -20,11 +20,38 @@ class GenerateUUID extends Operation {
this.name = "Generate UUID";
this.module = "Crypto";
- this.description = "Generates an RFC 4122 version 4 compliant Universally Unique Identifier (UUID), also known as a Globally Unique Identifier (GUID).
A version 4 UUID relies on random numbers, in this case generated using window.crypto if available and falling back to Math.random if not.";
+ this.description =
+ "Generates an RFC 9562 (formerly RFC 4122) compliant Universally Unique Identifier (UUID), " +
+ "also known as a Globally Unique Identifier (GUID).
" +
+ "
" +
+ "We currently support generating the following UUID versions:
" +
+ "
uuid package.object tags.PHP Deserialize.[5,"abc",true]a:3:{i:0;i:5;i:1;s:3:"abc";i:2;b:1;}";
+ this.infoURL = "https://www.phpinternalsbook.com/php5/classes_objects/serialization.html";
+ this.inputType = "JSON";
+ this.outputType = "string";
+ this.args = [];
+ }
+
+ /**
+ * @param {JSON} input
+ * @param {Object[]} args
+ * @returns {string}
+ */
+ run(input, args) {
+ /**
+ * Determines if a number is an integer
+ * @param {number} value
+ * @returns {boolean}
+ */
+ function isInteger(value) {
+ return typeof value === "number" && parseInt(value.toString(), 10) === value;
+ }
+
+ /**
+ * Serialize basic types
+ * @param {string | number | boolean} content
+ * @returns {string}
+ */
+ function serializeBasicTypes(content) {
+ const basicTypes = {
+ "string": "s",
+ "integer": "i",
+ "float": "d",
+ "boolean": "b"
+ };
+ /**
+ * Booleans
+ * cast to 0 or 1
+ */
+ if (typeof content === "boolean") {
+ return `${basicTypes.boolean}:${content ? 1 : 0}`;
+ }
+ /* Numbers */
+ if (typeof content === "number") {
+ if (isInteger(content)) {
+ return `${basicTypes.integer}:${content.toString()}`;
+ } else {
+ return `${basicTypes.float}:${content.toString()}`;
+ }
+ }
+ /* Strings */
+ if (typeof content === "string")
+ return `${basicTypes.string}:${content.length}:"${content}"`;
+
+ /** This should be unreachable */
+ throw new OperationError(`Encountered a non-implemented type: ${typeof content}`);
+ }
+
+ /**
+ * Recursively serialize
+ * @param {*} object
+ * @returns {string}
+ */
+ function serialize(object) {
+ /* Null */
+ if (object == null) {
+ return `N;`;
+ }
+
+ if (typeof object !== "object") {
+ /* Basic types */
+ return `${serializeBasicTypes(object)};`;
+ } else if (object instanceof Array) {
+ /* Arrays */
+ const serializedElements = [];
+
+ for (let i = 0; i < object.length; i++) {
+ serializedElements.push(`${serialize(i)}${serialize(object[i])}`);
+ }
+
+ return `a:${object.length}:{${serializedElements.join("")}}`;
+ } else if (object instanceof Object) {
+ /**
+ * Objects
+ * Note: the output cannot be guaranteed to be in the same order as the input
+ */
+ const serializedElements = [];
+ const keys = Object.keys(object);
+
+ for (const key of keys) {
+ serializedElements.push(`${serialize(key)}${serialize(object[key])}`);
+ }
+
+ return `a:${keys.length}:{${serializedElements.join("")}}`;
+ }
+
+ /** This should be unreachable */
+ throw new OperationError(`Encountered a non-implemented type: ${typeof object}`);
+ }
+
+ return serialize(input);
+ }
+}
+
+export default PHPSerialize;
diff --git a/src/core/operations/ParseX509Certificate.mjs b/src/core/operations/ParseX509Certificate.mjs
index 11e63424d..cdd1e9c7c 100644
--- a/src/core/operations/ParseX509Certificate.mjs
+++ b/src/core/operations/ParseX509Certificate.mjs
@@ -6,7 +6,8 @@
import r from "jsrsasign";
import { fromBase64 } from "../lib/Base64.mjs";
-import { toHex } from "../lib/Hex.mjs";
+import { runHash } from "../lib/Hash.mjs";
+import { fromHex, toHex } from "../lib/Hex.mjs";
import { formatByteStr, formatDnObj } from "../lib/PublicKey.mjs";
import Operation from "../Operation.mjs";
import Utils from "../Utils.mjs";
@@ -81,7 +82,8 @@ class ParseX509Certificate extends Operation {
}
if (undefinedInputFormat) throw "Undefined input format";
- const sn = cert.getSerialNumberHex(),
+ const hex = Utils.strToArrayBuffer(Utils.byteArrayToChars(fromHex(cert.hex))),
+ sn = cert.getSerialNumberHex(),
issuer = cert.getIssuer(),
subject = cert.getSubject(),
pk = cert.getPublicKey(),
@@ -191,6 +193,10 @@ Issuer
${issuerStr}
Subject
${subjectStr}
+Fingerprints
+ MD5: ${runHash("md5", hex)}
+ SHA1: ${runHash("sha1", hex)}
+ SHA256: ${runHash("sha256", hex)}
Public Key
${pkStr.slice(0, -1)}
Certificate Signature
diff --git a/src/core/operations/RailFenceCipherDecode.mjs b/src/core/operations/RailFenceCipherDecode.mjs
index be54ee124..39795f215 100644
--- a/src/core/operations/RailFenceCipherDecode.mjs
+++ b/src/core/operations/RailFenceCipherDecode.mjs
@@ -72,7 +72,7 @@ class RailFenceCipherDecode extends Operation {
}
}
- return plaintext.join("").trim();
+ return plaintext.join("");
}
}
diff --git a/src/core/operations/RailFenceCipherEncode.mjs b/src/core/operations/RailFenceCipherEncode.mjs
index 03651f857..89eddde75 100644
--- a/src/core/operations/RailFenceCipherEncode.mjs
+++ b/src/core/operations/RailFenceCipherEncode.mjs
@@ -66,7 +66,7 @@ class RailFenceCipherEncode extends Operation {
rows[rowIdx] += plaintext[pos];
}
- return rows.join("").trim();
+ return rows.join("");
}
}
diff --git a/src/core/operations/SM2Decrypt.mjs b/src/core/operations/SM2Decrypt.mjs
new file mode 100644
index 000000000..396571105
--- /dev/null
+++ b/src/core/operations/SM2Decrypt.mjs
@@ -0,0 +1,71 @@
+/**
+ * @author flakjacket95 [dflack95@gmail.com]
+ * @copyright Crown Copyright 2024
+ * @license Apache-2.0
+ */
+
+import OperationError from "../errors/OperationError.mjs";
+import Operation from "../Operation.mjs";
+
+import { SM2 } from "../lib/SM2.mjs";
+
+/**
+ * SM2Decrypt operation
+ */
+class SM2Decrypt extends Operation {
+
+ /**
+ * SM2Decrypt constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "SM2 Decrypt";
+ this.module = "Crypto";
+ this.description = "Decrypts a message utilizing the SM2 standard";
+ this.infoURL = ""; // Usually a Wikipedia link. Remember to remove localisation (i.e. https://wikipedia.org/etc rather than https://en.wikipedia.org/etc)
+ this.inputType = "string";
+ this.outputType = "ArrayBuffer";
+ this.args = [
+ {
+ name: "Private Key",
+ type: "string",
+ value: "DEADBEEF"
+ },
+ {
+ "name": "Input Format",
+ "type": "option",
+ "value": ["C1C3C2", "C1C2C3"],
+ "defaultIndex": 0
+ },
+ {
+ name: "Curve",
+ type: "option",
+ "value": ["sm2p256v1"],
+ "defaultIndex": 0
+ }
+ ];
+ }
+
+ /**
+ * @param {string} input
+ * @param {Object[]} args
+ * @returns {ArrayBuffer}
+ */
+ run(input, args) {
+ const [privateKey, inputFormat, curveName] = args;
+
+ if (privateKey.length !== 64) {
+ throw new OperationError("Input private key must be in hex; and should be 32 bytes");
+ }
+
+ const sm2 = new SM2(curveName, inputFormat);
+ sm2.setPrivateKey(privateKey);
+
+ const result = sm2.decrypt(input);
+ return result;
+ }
+
+}
+
+export default SM2Decrypt;
diff --git a/src/core/operations/SM2Encrypt.mjs b/src/core/operations/SM2Encrypt.mjs
new file mode 100644
index 000000000..b1e5f9018
--- /dev/null
+++ b/src/core/operations/SM2Encrypt.mjs
@@ -0,0 +1,77 @@
+/**
+ * @author flakjacket95 [dflack95@gmail.com]
+ * @copyright Crown Copyright 2024
+ * @license Apache-2.0
+ */
+
+import OperationError from "../errors/OperationError.mjs";
+import Operation from "../Operation.mjs";
+
+import { SM2 } from "../lib/SM2.mjs";
+
+/**
+ * SM2 Encrypt operation
+ */
+class SM2Encrypt extends Operation {
+
+ /**
+ * SM2Encrypt constructor
+ */
+ constructor() {
+ super();
+
+ this.name = "SM2 Encrypt";
+ this.module = "Crypto";
+ this.description = "Encrypts a message utilizing the SM2 standard";
+ this.infoURL = ""; // Usually a Wikipedia link. Remember to remove localisation (i.e. https://wikipedia.org/etc rather than https://en.wikipedia.org/etc)
+ this.inputType = "ArrayBuffer";
+ this.outputType = "string";
+
+ this.args = [
+ {
+ name: "Public Key X",
+ type: "string",
+ value: "DEADBEEF"
+ },
+ {
+ name: "Public Key Y",
+ type: "string",
+ value: "DEADBEEF"
+ },
+ {
+ "name": "Output Format",
+ "type": "option",
+ "value": ["C1C3C2", "C1C2C3"],
+ "defaultIndex": 0
+ },
+ {
+ name: "Curve",
+ type: "option",
+ "value": ["sm2p256v1"],
+ "defaultIndex": 0
+ }
+ ];
+ }
+
+ /**
+ * @param {ArrayBuffer} input
+ * @param {Object[]} args
+ * @returns {byteArray}
+ */
+ run(input, args) {
+ const [publicKeyX, publicKeyY, outputFormat, curveName] = args;
+ this.outputFormat = outputFormat;
+
+ if (publicKeyX.length !== 64 || publicKeyY.length !== 64) {
+ throw new OperationError("Invalid Public Key - Ensure each component is 32 bytes in size and in hex");
+ }
+
+ const sm2 = new SM2(curveName, outputFormat);
+ sm2.setPublicKey(publicKeyX, publicKeyY);
+
+ const result = sm2.encrypt(new Uint8Array(input));
+ return result;
+ }
+}
+
+export default SM2Encrypt;
diff --git a/src/core/operations/ShowOnMap.mjs b/src/core/operations/ShowOnMap.mjs
index c2ac1c6e3..d75c2aa6a 100644
--- a/src/core/operations/ShowOnMap.mjs
+++ b/src/core/operations/ShowOnMap.mjs
@@ -1,6 +1,7 @@
/**
* @author j433866 [j433866@gmail.com]
- * @copyright Crown Copyright 2019
+ * @author 0xff1ce [github.com/0xff1ce]
+ * @copyright Crown Copyright 2024
* @license Apache-2.0
*/
@@ -22,7 +23,7 @@ class ShowOnMap extends Operation {
this.name = "Show on map";
this.module = "Hashing";
this.description = "Displays co-ordinates on a slippy map.
Co-ordinates will be converted to decimal degrees before being shown on the map.
Supported formats:- Degrees Minutes Seconds (DMS)
- Degrees Decimal Minutes (DDM)
- Decimal Degrees (DD)
- Geohash
- Military Grid Reference System (MGRS)
- Ordnance Survey National Grid (OSNG)
- Universal Transverse Mercator (UTM)
This operation will not work offline.";
- this.infoURL = "https://foundation.wikimedia.org/wiki/Maps_Terms_of_Use";
+ this.infoURL = "https://osmfoundation.org/wiki/Terms_of_Use";
this.inputType = "string";
this.outputType = "string";
this.presentType = "html";
@@ -85,10 +86,10 @@ class ShowOnMap extends Operation {
data = "0, 0";
}
const zoomLevel = args[0];
- const tileUrl = "https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png",
- tileAttribution = "Wikimedia maps | © OpenStreetMap contributors",
- leafletUrl = "https://unpkg.com/leaflet@1.5.0/dist/leaflet.js",
- leafletCssUrl = "https://unpkg.com/leaflet@1.5.0/dist/leaflet.css";
+ const tileUrl = "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
+ tileAttribution = "© OpenStreetMap contributors",
+ leafletUrl = "https://unpkg.com/leaflet@1.9.4/dist/leaflet.js",
+ leafletCssUrl = "https://unpkg.com/leaflet@1.9.4/dist/leaflet.css";
return `