diff --git a/npm/.npmignore b/npm/.npmignore
new file mode 100644
index 0000000..73c86de
--- /dev/null
+++ b/npm/.npmignore
@@ -0,0 +1,78 @@
+src/
+esm/test/kyber.test.js
+esm/test/kyber.test.d.ts
+esm/test/utils.js
+esm/test/utils.d.ts
+esm/deps/deno.land/std@0.213.0/testing/_test_suite.js
+esm/deps/deno.land/std@0.213.0/testing/_test_suite.d.ts
+esm/deps/deno.land/std@0.213.0/testing/bdd.js
+esm/deps/deno.land/std@0.213.0/testing/bdd.d.ts
+esm/deps/deno.land/std@0.216.0/assert/_constants.js
+esm/deps/deno.land/std@0.216.0/assert/_constants.d.ts
+esm/deps/deno.land/std@0.216.0/assert/_diff.js
+esm/deps/deno.land/std@0.216.0/assert/_diff.d.ts
+esm/deps/deno.land/std@0.216.0/assert/_format.js
+esm/deps/deno.land/std@0.216.0/assert/_format.d.ts
+esm/deps/deno.land/std@0.216.0/assert/assert.js
+esm/deps/deno.land/std@0.216.0/assert/assert.d.ts
+esm/deps/deno.land/std@0.216.0/assert/assert_almost_equals.js
+esm/deps/deno.land/std@0.216.0/assert/assert_almost_equals.d.ts
+esm/deps/deno.land/std@0.216.0/assert/assert_array_includes.js
+esm/deps/deno.land/std@0.216.0/assert/assert_array_includes.d.ts
+esm/deps/deno.land/std@0.216.0/assert/assert_equals.js
+esm/deps/deno.land/std@0.216.0/assert/assert_equals.d.ts
+esm/deps/deno.land/std@0.216.0/assert/assert_exists.js
+esm/deps/deno.land/std@0.216.0/assert/assert_exists.d.ts
+esm/deps/deno.land/std@0.216.0/assert/assert_false.js
+esm/deps/deno.land/std@0.216.0/assert/assert_false.d.ts
+esm/deps/deno.land/std@0.216.0/assert/assert_greater.js
+esm/deps/deno.land/std@0.216.0/assert/assert_greater.d.ts
+esm/deps/deno.land/std@0.216.0/assert/assert_greater_or_equal.js
+esm/deps/deno.land/std@0.216.0/assert/assert_greater_or_equal.d.ts
+esm/deps/deno.land/std@0.216.0/assert/assert_instance_of.js
+esm/deps/deno.land/std@0.216.0/assert/assert_instance_of.d.ts
+esm/deps/deno.land/std@0.216.0/assert/assert_is_error.js
+esm/deps/deno.land/std@0.216.0/assert/assert_is_error.d.ts
+esm/deps/deno.land/std@0.216.0/assert/assert_less.js
+esm/deps/deno.land/std@0.216.0/assert/assert_less.d.ts
+esm/deps/deno.land/std@0.216.0/assert/assert_less_or_equal.js
+esm/deps/deno.land/std@0.216.0/assert/assert_less_or_equal.d.ts
+esm/deps/deno.land/std@0.216.0/assert/assert_match.js
+esm/deps/deno.land/std@0.216.0/assert/assert_match.d.ts
+esm/deps/deno.land/std@0.216.0/assert/assert_not_equals.js
+esm/deps/deno.land/std@0.216.0/assert/assert_not_equals.d.ts
+esm/deps/deno.land/std@0.216.0/assert/assert_not_instance_of.js
+esm/deps/deno.land/std@0.216.0/assert/assert_not_instance_of.d.ts
+esm/deps/deno.land/std@0.216.0/assert/assert_not_match.js
+esm/deps/deno.land/std@0.216.0/assert/assert_not_match.d.ts
+esm/deps/deno.land/std@0.216.0/assert/assert_not_strict_equals.js
+esm/deps/deno.land/std@0.216.0/assert/assert_not_strict_equals.d.ts
+esm/deps/deno.land/std@0.216.0/assert/assert_object_match.js
+esm/deps/deno.land/std@0.216.0/assert/assert_object_match.d.ts
+esm/deps/deno.land/std@0.216.0/assert/assert_rejects.js
+esm/deps/deno.land/std@0.216.0/assert/assert_rejects.d.ts
+esm/deps/deno.land/std@0.216.0/assert/assert_strict_equals.js
+esm/deps/deno.land/std@0.216.0/assert/assert_strict_equals.d.ts
+esm/deps/deno.land/std@0.216.0/assert/assert_string_includes.js
+esm/deps/deno.land/std@0.216.0/assert/assert_string_includes.d.ts
+esm/deps/deno.land/std@0.216.0/assert/assert_throws.js
+esm/deps/deno.land/std@0.216.0/assert/assert_throws.d.ts
+esm/deps/deno.land/std@0.216.0/assert/assertion_error.js
+esm/deps/deno.land/std@0.216.0/assert/assertion_error.d.ts
+esm/deps/deno.land/std@0.216.0/assert/equal.js
+esm/deps/deno.land/std@0.216.0/assert/equal.d.ts
+esm/deps/deno.land/std@0.216.0/assert/fail.js
+esm/deps/deno.land/std@0.216.0/assert/fail.d.ts
+esm/deps/deno.land/std@0.216.0/assert/mod.js
+esm/deps/deno.land/std@0.216.0/assert/mod.d.ts
+esm/deps/deno.land/std@0.216.0/assert/unimplemented.js
+esm/deps/deno.land/std@0.216.0/assert/unimplemented.d.ts
+esm/deps/deno.land/std@0.216.0/assert/unreachable.js
+esm/deps/deno.land/std@0.216.0/assert/unreachable.d.ts
+esm/deps/deno.land/std@0.216.0/fmt/colors.js
+esm/deps/deno.land/std@0.216.0/fmt/colors.d.ts
+esm/_dnt.test_shims.js
+esm/_dnt.test_shims.d.ts
+test_runner.js
+yarn.lock
+pnpm-lock.yaml
diff --git a/npm/LICENSE b/npm/LICENSE
new file mode 100644
index 0000000..3d8da59
--- /dev/null
+++ b/npm/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 Ajitomi Daisuke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/npm/README.md b/npm/README.md
new file mode 100644
index 0000000..884ec60
--- /dev/null
+++ b/npm/README.md
@@ -0,0 +1,246 @@
+
crystals-kyber-js
+
+
+
+[![deno doc](https://doc.deno.land/badge.svg)](https://doc.deno.land/https/deno.land/x/crystals_kyber/mod.ts)
+![Browser CI](https://github.com/dajiaji/crystals-kyber-js/actions/workflows/ci_browsers.yml/badge.svg)
+![Node.js CI](https://github.com/dajiaji/crystals-kyber-js/actions/workflows/ci_node.yml/badge.svg)
+![Deno CI](https://github.com/dajiaji/crystals-kyber-js/actions/workflows/ci_deno.yml/badge.svg)
+![Cloudflare Workers CI](https://github.com/dajiaji/crystals-kyber-js/actions/workflows/ci_cloudflare.yml/badge.svg)
+![Bun CI](https://github.com/dajiaji/crystals-kyber-js/actions/workflows/ci_bun.yml/badge.svg)
+[![codecov](https://codecov.io/gh/dajiaji/crystals-kyber-js/branch/main/graph/badge.svg?token=7I7JGKDDJ2)](https://codecov.io/gh/dajiaji/crystals-kyber-js)
+
+
+
+
+A CRYSTALS-KYBER implementation written in TypeScript for various JavaScript runtimes.
+
+
+
+
+
+[Documentation for main](https://dajiaji.github.io/crystals-kyber-js/docs/main/)
+
+
+
+This module is based on
+ntontutoveanu/crystals-kyber-javascript ,
+but includes the following improvements:
+
+- ✅ Available on various JavaScript runtimes: Browsers, Node.js, Deno,
+ Cloudflare Workers, etc.
+- ✅ Written in TypeScript.
+- ✅ Deterministic key generation support.
+- ✅ Constant-time validation for ciphertext.
+- ✅ Better performance: 1.4 to 1.8 times faster than the original
+ implementation.
+- ✅ Tree-shaking friendly.
+
+For Node.js, you can install `crystals-kyber-js` via npm/yarn:
+
+```sh
+npm install crystals-kyber-js
+```
+
+Then, you can use it as follows:
+
+```js
+import { MlKem768 } from "crystals-kyber-js";
+
+async function doKyber() {
+ // A recipient generates a key pair.
+ const recipient = new MlKem768(); // MlKem512 and MlKem1024 are also available.
+ const [pkR, skR] = await recipient.generateKeyPair();
+ //// Deterministic key generation is also supported
+ // const seed = new Uint8Array(64);
+ // globalThis.crypto.getRandomValues(seed); // node >= 19
+ // const [pkR, skR] = await recipient.deriveKeyPair(seed);
+
+ // A sender generates a ciphertext and a shared secret with pkR.
+ const sender = new MlKem768();
+ const [ct, ssS] = await sender.encap(pkR);
+
+ // The recipient decapsulates the ciphertext and generates the same shared secret with skR.
+ const ssR = await recipient.decap(ct, skR);
+
+ // ssS === ssR
+ return;
+}
+
+try {
+ doKyber();
+} catch (err) {
+ console.log("failed: ", err.message);
+}
+```
+
+## Index
+
+- [Installation](#installation)
+ - [Node.js](#nodejs)
+ - [Deno](#deno)
+ - [Web Browsers](#web-browsers)
+ - [Cloudflare Workers](#cloudflare-workers)
+- [Usage](#usage)
+- [Contributing](#contributing)
+
+## Installation
+
+### Node.js
+
+Using npm:
+
+```sh
+npm install crystals-kyber-js
+```
+
+Using yarn:
+
+```sh
+yarn add crystals-kyber-js
+```
+
+### Deno
+
+Using deno.land:
+
+```js
+// use a specific version
+import { MlKem768 } from "https://deno.land/x/crystals_kyber@1.1.1/mod.ts";
+
+// use the latest stable version
+import { MlKem768 } from "https://deno.land/x/crystals_kyber/mod.ts";
+```
+
+### Web Browsers
+
+Followings are how to use this module with typical CDNs. Other CDNs can be used
+as well.
+
+Using esm.sh:
+
+```html
+
+
+
+
+
+```
+
+Using unpkg:
+
+```html
+
+
+```
+
+### Cloudflare Workers
+
+```sh
+git clone git@github.com:dajiaji/crystals-kyber-js.git
+cd crystals-kyber-js
+npm install -g esbuild
+deno task dnt
+deno task minify > $YOUR_SRC_PATH/crystals-kyber.js
+```
+
+## Usage
+
+This section shows some typical usage examples.
+
+### Node.js
+
+```js
+import { MlKem768 } from "crystals-kyber-js";
+// const { MlKem768 } = require("crystals-kyber-js");
+
+async function doKyber() {
+ const recipient = new MlKem768();
+ const [pkR, skR] = await recipient.generateKeyPair();
+
+ const sender = new MlKem768();
+ const [ct, ssS] = await sender.encap(pkR);
+
+ const ssR = await recipient.decap(ct, skR);
+
+ // ssS === ssR
+ return;
+}
+
+try {
+ doKyber();
+} catch (err) {
+ console.log("failed: ", err.message);
+}
+```
+
+### Deno
+
+```js
+import { MlKem512 } from "https://deno.land/x/crystals_kyber@1.1.1/mod.ts";
+
+async function doKyber() {
+
+ const recipient = new MlKem512();
+ const [pkR, skR] = await recipient.generateKeyPair();
+
+ const sender = new MlKem512();
+ const [ct, ssS] = await sender.encap(pkR);
+
+ const ssR = await recipient.decap(ct, skR);
+
+ // ssS === ssR
+ return;
+}
+
+try {
+ doKyber();
+} catch (_err: unknown) {
+ console.log("failed.");
+}
+```
+
+### Browsers
+
+```html
+
+
+
+
+ do CRYSTALS-KYBER
+
+
+```
+
+## Contributing
+
+We welcome all kind of contributions, filing issues, suggesting new features or
+sending PRs.
diff --git a/npm/esm/_dnt.shims.d.ts b/npm/esm/_dnt.shims.d.ts
new file mode 100644
index 0000000..cefb7f5
--- /dev/null
+++ b/npm/esm/_dnt.shims.d.ts
@@ -0,0 +1 @@
+export declare const dntGlobalThis: Omit;
diff --git a/npm/esm/_dnt.shims.js b/npm/esm/_dnt.shims.js
new file mode 100644
index 0000000..bfdccc4
--- /dev/null
+++ b/npm/esm/_dnt.shims.js
@@ -0,0 +1,57 @@
+const dntGlobals = {};
+export const dntGlobalThis = createMergeProxy(globalThis, dntGlobals);
+function createMergeProxy(baseObj, extObj) {
+ return new Proxy(baseObj, {
+ get(_target, prop, _receiver) {
+ if (prop in extObj) {
+ return extObj[prop];
+ }
+ else {
+ return baseObj[prop];
+ }
+ },
+ set(_target, prop, value) {
+ if (prop in extObj) {
+ delete extObj[prop];
+ }
+ baseObj[prop] = value;
+ return true;
+ },
+ deleteProperty(_target, prop) {
+ let success = false;
+ if (prop in extObj) {
+ delete extObj[prop];
+ success = true;
+ }
+ if (prop in baseObj) {
+ delete baseObj[prop];
+ success = true;
+ }
+ return success;
+ },
+ ownKeys(_target) {
+ const baseKeys = Reflect.ownKeys(baseObj);
+ const extKeys = Reflect.ownKeys(extObj);
+ const extKeysSet = new Set(extKeys);
+ return [...baseKeys.filter((k) => !extKeysSet.has(k)), ...extKeys];
+ },
+ defineProperty(_target, prop, desc) {
+ if (prop in extObj) {
+ delete extObj[prop];
+ }
+ Reflect.defineProperty(baseObj, prop, desc);
+ return true;
+ },
+ getOwnPropertyDescriptor(_target, prop) {
+ if (prop in extObj) {
+ return Reflect.getOwnPropertyDescriptor(extObj, prop);
+ }
+ else {
+ return Reflect.getOwnPropertyDescriptor(baseObj, prop);
+ }
+ },
+ has(_target, prop) {
+ return prop in extObj || prop in baseObj;
+ },
+ });
+}
diff --git a/npm/esm/_dnt.test_shims.d.ts b/npm/esm/_dnt.test_shims.d.ts
new file mode 100644
index 0000000..2b1b022
--- /dev/null
+++ b/npm/esm/_dnt.test_shims.d.ts
@@ -0,0 +1,5 @@
+import { Deno } from "@deno/shim-deno";
+export { Deno } from "@deno/shim-deno";
+export declare const dntGlobalThis: Omit & {
+ Deno: typeof Deno;
+};
diff --git a/npm/esm/_dnt.test_shims.js b/npm/esm/_dnt.test_shims.js
new file mode 100644
index 0000000..aacb619
--- /dev/null
+++ b/npm/esm/_dnt.test_shims.js
@@ -0,0 +1,61 @@
+import { Deno } from "@deno/shim-deno";
+export { Deno } from "@deno/shim-deno";
+const dntGlobals = {
+ Deno,
+};
+export const dntGlobalThis = createMergeProxy(globalThis, dntGlobals);
+function createMergeProxy(baseObj, extObj) {
+ return new Proxy(baseObj, {
+ get(_target, prop, _receiver) {
+ if (prop in extObj) {
+ return extObj[prop];
+ }
+ else {
+ return baseObj[prop];
+ }
+ },
+ set(_target, prop, value) {
+ if (prop in extObj) {
+ delete extObj[prop];
+ }
+ baseObj[prop] = value;
+ return true;
+ },
+ deleteProperty(_target, prop) {
+ let success = false;
+ if (prop in extObj) {
+ delete extObj[prop];
+ success = true;
+ }
+ if (prop in baseObj) {
+ delete baseObj[prop];
+ success = true;
+ }
+ return success;
+ },
+ ownKeys(_target) {
+ const baseKeys = Reflect.ownKeys(baseObj);
+ const extKeys = Reflect.ownKeys(extObj);
+ const extKeysSet = new Set(extKeys);
+ return [...baseKeys.filter((k) => !extKeysSet.has(k)), ...extKeys];
+ },
+ defineProperty(_target, prop, desc) {
+ if (prop in extObj) {
+ delete extObj[prop];
+ }
+ Reflect.defineProperty(baseObj, prop, desc);
+ return true;
+ },
+ getOwnPropertyDescriptor(_target, prop) {
+ if (prop in extObj) {
+ return Reflect.getOwnPropertyDescriptor(extObj, prop);
+ }
+ else {
+ return Reflect.getOwnPropertyDescriptor(baseObj, prop);
+ }
+ },
+ has(_target, prop) {
+ return prop in extObj || prop in baseObj;
+ },
+ });
+}
diff --git a/npm/esm/deps/deno.land/std@0.213.0/testing/_test_suite.d.ts b/npm/esm/deps/deno.land/std@0.213.0/testing/_test_suite.d.ts
new file mode 100644
index 0000000..98ab128
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.213.0/testing/_test_suite.d.ts
@@ -0,0 +1,70 @@
+/** The options for creating a test suite with the describe function. */
+import * as dntShim from "../../../../_dnt.test_shims.js";
+export interface DescribeDefinition extends Omit {
+ fn?: () => void;
+ /**
+ * The `describe` function returns a `TestSuite` representing the group of tests.
+ * If `describe` is called within another `describe` calls `fn`, the suite will default to that parent `describe` calls returned `TestSuite`.
+ * If `describe` is not called within another `describe` calls `fn`, the suite will default to the `TestSuite` representing the global group of tests.
+ */
+ suite?: TestSuite;
+ /** Run some shared setup before all of the tests in the suite. */
+ beforeAll?: ((this: T) => void | Promise) | ((this: T) => void | Promise)[];
+ /** Run some shared teardown after all of the tests in the suite. */
+ afterAll?: ((this: T) => void | Promise) | ((this: T) => void | Promise)[];
+ /** Run some shared setup before each test in the suite. */
+ beforeEach?: ((this: T) => void | Promise) | ((this: T) => void | Promise)[];
+ /** Run some shared teardown after each test in the suite. */
+ afterEach?: ((this: T) => void | Promise) | ((this: T) => void | Promise)[];
+}
+/** The options for creating an individual test case with the it function. */
+export interface ItDefinition extends Omit {
+ fn: (this: T, t: dntShim.Deno.TestContext) => void | Promise;
+ /**
+ * The `describe` function returns a `TestSuite` representing the group of tests.
+ * If `it` is called within a `describe` calls `fn`, the suite will default to that parent `describe` calls returned `TestSuite`.
+ * If `it` is not called within a `describe` calls `fn`, the suite will default to the `TestSuite` representing the global group of tests.
+ */
+ suite?: TestSuite;
+}
+/** The names of all the different types of hooks. */
+export type HookNames = "beforeAll" | "afterAll" | "beforeEach" | "afterEach";
+/**
+ * A group of tests.
+ */
+export interface TestSuite {
+ symbol: symbol;
+}
+/**
+ * An internal representation of a group of tests.
+ */
+export declare class TestSuiteInternal implements TestSuite {
+ symbol: symbol;
+ protected describe: DescribeDefinition;
+ protected steps: (TestSuiteInternal | ItDefinition)[];
+ protected hasOnlyStep: boolean;
+ constructor(describe: DescribeDefinition);
+ /** Stores how many test suites are executing. */
+ static runningCount: number;
+ /** If a test has been registered yet. Block adding global hooks if a test has been registered. */
+ static started: boolean;
+ /** A map of all test suites by symbol. */
+ static suites: Map>;
+ /** The current test suite being registered. */
+ static current: TestSuiteInternal | null;
+ /** The stack of tests that are actively running. */
+ static active: symbol[];
+ /** This is used internally for testing this module. */
+ static reset(): void;
+ /** This is used internally to register tests. */
+ static registerTest(options: dntShim.Deno.TestDefinition): void;
+ /** Updates all steps within top level suite to have ignore set to true if only is not set to true on step. */
+ static addingOnlyStep(suite: TestSuiteInternal): void;
+ /** This is used internally to add steps to a test suite. */
+ static addStep(suite: TestSuiteInternal, step: TestSuiteInternal | ItDefinition): void;
+ /** This is used internally to add hooks to a test suite. */
+ static setHook(suite: TestSuiteInternal, name: HookNames, fn: (this: T) => void | Promise): void;
+ /** This is used internally to run all steps for a test suite. */
+ static run(suite: TestSuiteInternal, context: T, t: dntShim.Deno.TestContext): Promise;
+ static runTest(t: dntShim.Deno.TestContext, fn: (this: T, t: dntShim.Deno.TestContext) => void | Promise, context: T, activeIndex?: number): Promise;
+}
diff --git a/npm/esm/deps/deno.land/std@0.213.0/testing/_test_suite.js b/npm/esm/deps/deno.land/std@0.213.0/testing/_test_suite.js
new file mode 100644
index 0000000..ab28466
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.213.0/testing/_test_suite.js
@@ -0,0 +1,321 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+/** The options for creating a test suite with the describe function. */
+import * as dntShim from "../../../../_dnt.test_shims.js";
+/** Optional test definition keys. */
+const optionalTestDefinitionKeys = [
+ "only",
+ "permissions",
+ "ignore",
+ "sanitizeExit",
+ "sanitizeOps",
+ "sanitizeResources",
+];
+/** Optional test step definition keys. */
+const optionalTestStepDefinitionKeys = [
+ "ignore",
+ "sanitizeExit",
+ "sanitizeOps",
+ "sanitizeResources",
+];
+/**
+ * An internal representation of a group of tests.
+ */
+export class TestSuiteInternal {
+ constructor(describe) {
+ Object.defineProperty(this, "symbol", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: void 0
+ });
+ Object.defineProperty(this, "describe", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: void 0
+ });
+ Object.defineProperty(this, "steps", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: void 0
+ });
+ Object.defineProperty(this, "hasOnlyStep", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: void 0
+ });
+ this.describe = describe;
+ this.steps = [];
+ this.hasOnlyStep = false;
+ const { suite } = describe;
+ if (suite && !TestSuiteInternal.suites.has(suite.symbol)) {
+ throw new Error("suite does not represent a registered test suite");
+ }
+ const testSuite = suite
+ ? TestSuiteInternal.suites.get(suite.symbol)
+ : TestSuiteInternal.current;
+ this.symbol = Symbol();
+ TestSuiteInternal.suites.set(this.symbol, this);
+ const { fn } = describe;
+ if (fn) {
+ const temp = TestSuiteInternal.current;
+ TestSuiteInternal.current = this;
+ try {
+ fn();
+ }
+ finally {
+ TestSuiteInternal.current = temp;
+ }
+ }
+ if (testSuite) {
+ TestSuiteInternal.addStep(testSuite, this);
+ }
+ else {
+ const { name, ignore, permissions, sanitizeExit, sanitizeOps, sanitizeResources, } = describe;
+ let { only } = describe;
+ if (!ignore && this.hasOnlyStep) {
+ only = true;
+ }
+ TestSuiteInternal.registerTest({
+ name,
+ ignore,
+ only,
+ permissions,
+ sanitizeExit,
+ sanitizeOps,
+ sanitizeResources,
+ fn: async (t) => {
+ TestSuiteInternal.runningCount++;
+ try {
+ const context = {};
+ const { beforeAll } = this.describe;
+ if (typeof beforeAll === "function") {
+ await beforeAll.call(context);
+ }
+ else if (beforeAll) {
+ for (const hook of beforeAll) {
+ await hook.call(context);
+ }
+ }
+ try {
+ TestSuiteInternal.active.push(this.symbol);
+ await TestSuiteInternal.run(this, context, t);
+ }
+ finally {
+ TestSuiteInternal.active.pop();
+ const { afterAll } = this.describe;
+ if (typeof afterAll === "function") {
+ await afterAll.call(context);
+ }
+ else if (afterAll) {
+ for (const hook of afterAll) {
+ await hook.call(context);
+ }
+ }
+ }
+ }
+ finally {
+ TestSuiteInternal.runningCount--;
+ }
+ },
+ });
+ }
+ }
+ /** This is used internally for testing this module. */
+ static reset() {
+ TestSuiteInternal.runningCount = 0;
+ TestSuiteInternal.started = false;
+ TestSuiteInternal.current = null;
+ TestSuiteInternal.active = [];
+ }
+ /** This is used internally to register tests. */
+ static registerTest(options) {
+ options = { ...options };
+ optionalTestDefinitionKeys.forEach((key) => {
+ if (typeof options[key] === "undefined")
+ delete options[key];
+ });
+ dntShim.Deno.test(options);
+ }
+ /** Updates all steps within top level suite to have ignore set to true if only is not set to true on step. */
+ static addingOnlyStep(suite) {
+ if (!suite.hasOnlyStep) {
+ for (let i = 0; i < suite.steps.length; i++) {
+ const step = suite.steps[i];
+ if (!(step instanceof TestSuiteInternal) && !step.only) {
+ suite.steps.splice(i--, 1);
+ }
+ }
+ suite.hasOnlyStep = true;
+ }
+ const parentSuite = suite.describe.suite;
+ const parentTestSuite = parentSuite &&
+ TestSuiteInternal.suites.get(parentSuite.symbol);
+ if (parentTestSuite) {
+ TestSuiteInternal.addingOnlyStep(parentTestSuite);
+ }
+ }
+ /** This is used internally to add steps to a test suite. */
+ static addStep(suite, step) {
+ if (!suite.hasOnlyStep) {
+ if (step instanceof TestSuiteInternal) {
+ if (step.hasOnlyStep || step.describe.only) {
+ TestSuiteInternal.addingOnlyStep(suite);
+ }
+ }
+ else {
+ if (step.only)
+ TestSuiteInternal.addingOnlyStep(suite);
+ }
+ }
+ if (!(suite.hasOnlyStep && !(step instanceof TestSuiteInternal) && !step.only)) {
+ suite.steps.push(step);
+ }
+ }
+ /** This is used internally to add hooks to a test suite. */
+ static setHook(suite, name, fn) {
+ if (suite.describe[name]) {
+ if (typeof suite.describe[name] === "function") {
+ suite.describe[name] = [
+ suite.describe[name],
+ ];
+ }
+ suite.describe[name].push(fn);
+ }
+ else {
+ suite.describe[name] = fn;
+ }
+ }
+ /** This is used internally to run all steps for a test suite. */
+ static async run(suite, context, t) {
+ const hasOnly = suite.hasOnlyStep || suite.describe.only || false;
+ for (const step of suite.steps) {
+ if (hasOnly && step instanceof TestSuiteInternal &&
+ !(step.hasOnlyStep || step.describe.only || false)) {
+ continue;
+ }
+ const { name, fn, ignore, permissions, sanitizeExit, sanitizeOps, sanitizeResources, } = step instanceof TestSuiteInternal ? step.describe : step;
+ const options = {
+ name,
+ ignore,
+ sanitizeExit,
+ sanitizeOps,
+ sanitizeResources,
+ fn: async (t) => {
+ if (permissions) {
+ throw new Error("permissions option not available for nested tests");
+ }
+ context = { ...context };
+ if (step instanceof TestSuiteInternal) {
+ const { beforeAll } = step.describe;
+ if (typeof beforeAll === "function") {
+ await beforeAll.call(context);
+ }
+ else if (beforeAll) {
+ for (const hook of beforeAll) {
+ await hook.call(context);
+ }
+ }
+ try {
+ TestSuiteInternal.active.push(step.symbol);
+ await TestSuiteInternal.run(step, context, t);
+ }
+ finally {
+ TestSuiteInternal.active.pop();
+ const { afterAll } = step.describe;
+ if (typeof afterAll === "function") {
+ await afterAll.call(context);
+ }
+ else if (afterAll) {
+ for (const hook of afterAll) {
+ await hook.call(context);
+ }
+ }
+ }
+ }
+ else {
+ await TestSuiteInternal.runTest(t, fn, context);
+ }
+ },
+ };
+ optionalTestStepDefinitionKeys.forEach((key) => {
+ if (typeof options[key] === "undefined")
+ delete options[key];
+ });
+ await t.step(options);
+ }
+ }
+ static async runTest(t, fn, context, activeIndex = 0) {
+ const suite = TestSuiteInternal.active[activeIndex];
+ const testSuite = suite && TestSuiteInternal.suites.get(suite);
+ if (testSuite) {
+ if (activeIndex === 0)
+ context = { ...context };
+ const { beforeEach } = testSuite.describe;
+ if (typeof beforeEach === "function") {
+ await beforeEach.call(context);
+ }
+ else if (beforeEach) {
+ for (const hook of beforeEach) {
+ await hook.call(context);
+ }
+ }
+ try {
+ await TestSuiteInternal.runTest(t, fn, context, activeIndex + 1);
+ }
+ finally {
+ const { afterEach } = testSuite.describe;
+ if (typeof afterEach === "function") {
+ await afterEach.call(context);
+ }
+ else if (afterEach) {
+ for (const hook of afterEach) {
+ await hook.call(context);
+ }
+ }
+ }
+ }
+ else {
+ await fn.call(context, t);
+ }
+ }
+}
+/** Stores how many test suites are executing. */
+Object.defineProperty(TestSuiteInternal, "runningCount", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: 0
+});
+/** If a test has been registered yet. Block adding global hooks if a test has been registered. */
+Object.defineProperty(TestSuiteInternal, "started", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: false
+});
+/** A map of all test suites by symbol. */
+// deno-lint-ignore no-explicit-any
+Object.defineProperty(TestSuiteInternal, "suites", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: new Map()
+});
+/** The current test suite being registered. */
+// deno-lint-ignore no-explicit-any
+Object.defineProperty(TestSuiteInternal, "current", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: null
+});
+/** The stack of tests that are actively running. */
+Object.defineProperty(TestSuiteInternal, "active", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: []
+});
diff --git a/npm/esm/deps/deno.land/std@0.213.0/testing/bdd.d.ts b/npm/esm/deps/deno.land/std@0.213.0/testing/bdd.d.ts
new file mode 100644
index 0000000..606c79a
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.213.0/testing/bdd.d.ts
@@ -0,0 +1,524 @@
+/** A [BDD](https://en.wikipedia.org/wiki/Behavior-driven_development) interface
+ * to `Deno.test()` API.
+ *
+ * With the `bdd.ts` module you can write your tests in a familiar format for
+ * grouping tests and adding setup/teardown hooks used by other JavaScript testing
+ * frameworks like Jasmine, Jest, and Mocha.
+ *
+ * The `describe` function creates a block that groups together several related
+ * tests. The `it` function registers an individual test case.
+ *
+ * ## Hooks
+ *
+ * There are 4 types of hooks available for test suites. A test suite can have
+ * multiples of each type of hook, they will be called in the order that they are
+ * registered. The `afterEach` and `afterAll` hooks will be called whether or not
+ * the test case passes. The *All hooks will be called once for the whole group
+ * while the *Each hooks will be called for each individual test case.
+ *
+ * - `beforeAll`: Runs before all of the tests in the test suite.
+ * - `afterAll`: Runs after all of the tests in the test suite finish.
+ * - `beforeEach`: Runs before each of the individual test cases in the test suite.
+ * - `afterEach`: Runs after each of the individual test cases in the test suite.
+ *
+ * If a hook is registered at the top level, a global test suite will be registered
+ * and all tests will belong to it. Hooks registered at the top level must be
+ * registered before any individual test cases or test suites.
+ *
+ * ## Focusing tests
+ *
+ * If you would like to run only specific test cases, you can do so by calling
+ * `it.only` instead of `it`. If you would like to run only specific test suites,
+ * you can do so by calling `describe.only` instead of `describe`.
+ *
+ * There is one limitation to this when using the flat test grouping style. When
+ * `describe` is called without being nested, it registers the test with
+ * `Deno.test`. If a child test case or suite is registered with `it.only` or
+ * `describe.only`, it will be scoped to the top test suite instead of the file. To
+ * make them the only tests that run in the file, you would need to register the
+ * top test suite with `describe.only` too.
+ *
+ * ## Ignoring tests
+ *
+ * If you would like to not run specific individual test cases, you can do so by
+ * calling `it.ignore` instead of `it`. If you would like to not run specific test
+ * suites, you can do so by calling `describe.ignore` instead of `describe`.
+ *
+ * ## Sanitization options
+ *
+ * Like `Deno.TestDefinition`, the `DescribeDefinition` and `ItDefinition` have
+ * sanitization options. They work in the same way.
+ *
+ * - `sanitizeExit`: Ensure the test case does not prematurely cause the process to
+ * exit, for example via a call to Deno.exit. Defaults to true.
+ * - `sanitizeOps`: Check that the number of async completed ops after the test is
+ * the same as number of dispatched ops. Defaults to true.
+ * - `sanitizeResources`: Ensure the test case does not "leak" resources - ie. the
+ * resource table after the test has exactly the same contents as before the
+ * test. Defaults to true.
+ *
+ * ## Permissions option
+ *
+ * Like `Deno.TestDefinition`, the `DescribeDefinition` and `ItDefinition` have a
+ * `permissions` option. They specify the permissions that should be used to run an
+ * individual test case or test suite. Set this to `"inherit"` to keep the calling
+ * thread's permissions. Set this to `"none"` to revoke all permissions.
+ *
+ * This setting defaults to `"inherit"`.
+ *
+ * There is currently one limitation to this, you cannot use the permissions option
+ * on an individual test case or test suite that belongs to another test suite.
+ * That's because internally those tests are registered with `t.step` which does
+ * not support the permissions option.
+ *
+ * ## Comparing to Deno\.test
+ *
+ * The default way of writing tests is using `Deno.test` and `t.step`. The
+ * `describe` and `it` functions have similar call signatures to `Deno.test`,
+ * making it easy to switch between the default style and the behavior-driven
+ * development style of writing tests. Internally, `describe` and `it` are
+ * registering tests with `Deno.test` and `t.step`.
+ *
+ * Below is an example of a test file using `Deno.test` and `t.step`. In the
+ * following sections there are examples of how the same test could be written with
+ * `describe` and `it` using nested test grouping, flat test grouping, or a mix of
+ * both styles.
+ *
+ * ```ts
+ * import {
+ * assertEquals,
+ * assertStrictEquals,
+ * assertThrows,
+ * } from "https://deno.land/std@$STD_VERSION/assert/mod.ts";
+ *
+ * class User {
+ * static users: Map = new Map();
+ * age?: number;
+ *
+ * constructor(public name: string) {
+ * if (User.users.has(name)) {
+ * throw new Deno.errors.AlreadyExists(`User ${name} already exists`);
+ * }
+ * User.users.set(name, this);
+ * }
+ *
+ * getAge(): number {
+ * if (!this.age) {
+ * throw new Error("Age unknown");
+ * }
+ * return this.age;
+ * }
+ *
+ * setAge(age: number) {
+ * this.age = age;
+ * }
+ * }
+ *
+ * Deno.test("User.users initially empty", () => {
+ * assertEquals(User.users.size, 0);
+ * });
+ *
+ * Deno.test("User constructor", () => {
+ * try {
+ * const user = new User("Kyle");
+ * assertEquals(user.name, "Kyle");
+ * assertStrictEquals(User.users.get("Kyle"), user);
+ * } finally {
+ * User.users.clear();
+ * }
+ * });
+ *
+ * Deno.test("User age", async (t) => {
+ * const user = new User("Kyle");
+ *
+ * await t.step("getAge", () => {
+ * assertThrows(() => user.getAge(), Error, "Age unknown");
+ * user.age = 18;
+ * assertEquals(user.getAge(), 18);
+ * });
+ *
+ * await t.step("setAge", () => {
+ * user.setAge(18);
+ * assertEquals(user.getAge(), 18);
+ * });
+ * });
+ * ```
+ *
+ * ### Nested test grouping
+ *
+ * Tests created within the callback of a `describe` function call will belong to
+ * the new test suite it creates. The hooks can be created within it or be added to
+ * the options argument for describe.
+ *
+ * ```ts
+ * import {
+ * assertEquals,
+ * assertStrictEquals,
+ * assertThrows,
+ * } from "https://deno.land/std@$STD_VERSION/assert/mod.ts";
+ * import {
+ * afterEach,
+ * beforeEach,
+ * describe,
+ * it,
+ * } from "https://deno.land/std@$STD_VERSION/testing/bdd.ts";
+ *
+ * class User {
+ * static users: Map = new Map();
+ * age?: number;
+ *
+ * constructor(public name: string) {
+ * if (User.users.has(name)) {
+ * throw new Deno.errors.AlreadyExists(`User ${name} already exists`);
+ * }
+ * User.users.set(name, this);
+ * }
+ *
+ * getAge(): number {
+ * if (!this.age) {
+ * throw new Error("Age unknown");
+ * }
+ * return this.age;
+ * }
+ *
+ * setAge(age: number) {
+ * this.age = age;
+ * }
+ * }
+ *
+ * describe("User", () => {
+ * it("users initially empty", () => {
+ * assertEquals(User.users.size, 0);
+ * });
+ *
+ * it("constructor", () => {
+ * try {
+ * const user = new User("Kyle");
+ * assertEquals(user.name, "Kyle");
+ * assertStrictEquals(User.users.get("Kyle"), user);
+ * } finally {
+ * User.users.clear();
+ * }
+ * });
+ *
+ * describe("age", () => {
+ * let user: User;
+ *
+ * beforeEach(() => {
+ * user = new User("Kyle");
+ * });
+ *
+ * afterEach(() => {
+ * User.users.clear();
+ * });
+ *
+ * it("getAge", function () {
+ * assertThrows(() => user.getAge(), Error, "Age unknown");
+ * user.age = 18;
+ * assertEquals(user.getAge(), 18);
+ * });
+ *
+ * it("setAge", function () {
+ * user.setAge(18);
+ * assertEquals(user.getAge(), 18);
+ * });
+ * });
+ * });
+ * ```
+ *
+ * ### Flat test grouping
+ *
+ * The `describe` function returns a unique symbol that can be used to reference
+ * the test suite for adding tests to it without having to create them within a
+ * callback. The gives you the ability to have test grouping without any extra
+ * indentation in front of the grouped tests.
+ *
+ * ```ts
+ * import {
+ * assertEquals,
+ * assertStrictEquals,
+ * assertThrows,
+ * } from "https://deno.land/std@$STD_VERSION/assert/mod.ts";
+ * import {
+ * describe,
+ * it,
+ * } from "https://deno.land/std@$STD_VERSION/testing/bdd.ts";
+ *
+ * class User {
+ * static users: Map = new Map();
+ * age?: number;
+ *
+ * constructor(public name: string) {
+ * if (User.users.has(name)) {
+ * throw new Deno.errors.AlreadyExists(`User ${name} already exists`);
+ * }
+ * User.users.set(name, this);
+ * }
+ *
+ * getAge(): number {
+ * if (!this.age) {
+ * throw new Error("Age unknown");
+ * }
+ * return this.age;
+ * }
+ *
+ * setAge(age: number) {
+ * this.age = age;
+ * }
+ * }
+ *
+ * const userTests = describe("User");
+ *
+ * it(userTests, "users initially empty", () => {
+ * assertEquals(User.users.size, 0);
+ * });
+ *
+ * it(userTests, "constructor", () => {
+ * try {
+ * const user = new User("Kyle");
+ * assertEquals(user.name, "Kyle");
+ * assertStrictEquals(User.users.get("Kyle"), user);
+ * } finally {
+ * User.users.clear();
+ * }
+ * });
+ *
+ * const ageTests = describe({
+ * name: "age",
+ * suite: userTests,
+ * beforeEach(this: { user: User }) {
+ * this.user = new User("Kyle");
+ * },
+ * afterEach() {
+ * User.users.clear();
+ * },
+ * });
+ *
+ * it(ageTests, "getAge", function () {
+ * const { user } = this;
+ * assertThrows(() => user.getAge(), Error, "Age unknown");
+ * user.age = 18;
+ * assertEquals(user.getAge(), 18);
+ * });
+ *
+ * it(ageTests, "setAge", function () {
+ * const { user } = this;
+ * user.setAge(18);
+ * assertEquals(user.getAge(), 18);
+ * });
+ * ```
+ *
+ * ### Mixed test grouping
+ *
+ * Both nested test grouping and flat test grouping can be used together. This can
+ * be useful if you'd like to create deep groupings without all the extra
+ * indentation in front of each line.
+ *
+ * ```ts
+ * import {
+ * assertEquals,
+ * assertStrictEquals,
+ * assertThrows,
+ * } from "https://deno.land/std@$STD_VERSION/assert/mod.ts";
+ * import {
+ * describe,
+ * it,
+ * } from "https://deno.land/std@$STD_VERSION/testing/bdd.ts";
+ *
+ * class User {
+ * static users: Map = new Map();
+ * age?: number;
+ *
+ * constructor(public name: string) {
+ * if (User.users.has(name)) {
+ * throw new Deno.errors.AlreadyExists(`User ${name} already exists`);
+ * }
+ * User.users.set(name, this);
+ * }
+ *
+ * getAge(): number {
+ * if (!this.age) {
+ * throw new Error("Age unknown");
+ * }
+ * return this.age;
+ * }
+ *
+ * setAge(age: number) {
+ * this.age = age;
+ * }
+ * }
+ *
+ * describe("User", () => {
+ * it("users initially empty", () => {
+ * assertEquals(User.users.size, 0);
+ * });
+ *
+ * it("constructor", () => {
+ * try {
+ * const user = new User("Kyle");
+ * assertEquals(user.name, "Kyle");
+ * assertStrictEquals(User.users.get("Kyle"), user);
+ * } finally {
+ * User.users.clear();
+ * }
+ * });
+ *
+ * const ageTests = describe({
+ * name: "age",
+ * beforeEach(this: { user: User }) {
+ * this.user = new User("Kyle");
+ * },
+ * afterEach() {
+ * User.users.clear();
+ * },
+ * });
+ *
+ * it(ageTests, "getAge", function () {
+ * const { user } = this;
+ * assertThrows(() => user.getAge(), Error, "Age unknown");
+ * user.age = 18;
+ * assertEquals(user.getAge(), 18);
+ * });
+ *
+ * it(ageTests, "setAge", function () {
+ * const { user } = this;
+ * user.setAge(18);
+ * assertEquals(user.getAge(), 18);
+ * });
+ * });
+ * ```
+ *
+ * @module
+ */
+import * as dntShim from "../../../../_dnt.test_shims.js";
+import { DescribeDefinition, ItDefinition, TestSuite } from "./_test_suite.js";
+export type { DescribeDefinition, ItDefinition, TestSuite };
+/** The arguments for an ItFunction. */
+export type ItArgs = [options: ItDefinition] | [
+ name: string,
+ options: Omit, "name">
+] | [
+ name: string,
+ fn: (this: T, t: dntShim.Deno.TestContext) => void | Promise
+] | [fn: (this: T, t: dntShim.Deno.TestContext) => void | Promise] | [
+ name: string,
+ options: Omit, "fn" | "name">,
+ fn: (this: T, t: dntShim.Deno.TestContext) => void | Promise
+] | [
+ options: Omit, "fn">,
+ fn: (this: T, t: dntShim.Deno.TestContext) => void | Promise
+] | [
+ options: Omit, "fn" | "name">,
+ fn: (this: T, t: dntShim.Deno.TestContext) => void | Promise
+] | [
+ suite: TestSuite,
+ name: string,
+ options: Omit, "name" | "suite">
+] | [
+ suite: TestSuite,
+ name: string,
+ fn: (this: T, t: dntShim.Deno.TestContext) => void | Promise
+] | [
+ suite: TestSuite,
+ fn: (this: T, t: dntShim.Deno.TestContext) => void | Promise
+] | [
+ suite: TestSuite,
+ name: string,
+ options: Omit, "fn" | "name" | "suite">,
+ fn: (this: T, t: dntShim.Deno.TestContext) => void | Promise
+] | [
+ suite: TestSuite,
+ options: Omit, "fn" | "suite">,
+ fn: (this: T, t: dntShim.Deno.TestContext) => void | Promise
+] | [
+ suite: TestSuite,
+ options: Omit, "fn" | "name" | "suite">,
+ fn: (this: T, t: dntShim.Deno.TestContext) => void | Promise
+];
+/** Registers an individual test case. */
+export interface it {
+ (...args: ItArgs): void;
+ /** Registers an individual test case with only set to true. */
+ only(...args: ItArgs): void;
+ /** Registers an individual test case with ignore set to true. */
+ ignore(...args: ItArgs): void;
+ /**
+ * Registers an individual test case with ignore set to true. Alias of
+ * `.ignore()`.
+ */
+ skip(...args: ItArgs): void;
+}
+/** Registers an individual test case. */
+export declare function it(...args: ItArgs): void;
+export declare namespace it {
+ var only: (...args: ItArgs) => void;
+ var ignore: (...args: ItArgs) => void;
+ var skip: (...args: ItArgs) => void;
+}
+/** Run some shared setup before all of the tests in the suite. */
+export declare function beforeAll(fn: (this: T) => void | Promise): void;
+/** Run some shared teardown after all of the tests in the suite. */
+export declare function afterAll(fn: (this: T) => void | Promise): void;
+/** Run some shared setup before each test in the suite. */
+export declare function beforeEach(fn: (this: T) => void | Promise): void;
+/** Run some shared teardown after each test in the suite. */
+export declare function afterEach(fn: (this: T) => void | Promise): void;
+/** The arguments for a DescribeFunction. */
+export type DescribeArgs = [options: DescribeDefinition] | [name: string] | [
+ name: string,
+ options: Omit, "name">
+] | [name: string, fn: () => void] | [fn: () => void] | [
+ name: string,
+ options: Omit, "fn" | "name">,
+ fn: () => void
+] | [
+ options: Omit, "fn">,
+ fn: () => void
+] | [
+ options: Omit, "fn" | "name">,
+ fn: () => void
+] | [
+ suite: TestSuite,
+ name: string
+] | [
+ suite: TestSuite,
+ name: string,
+ options: Omit, "name" | "suite">
+] | [
+ suite: TestSuite,
+ name: string,
+ fn: () => void
+] | [
+ suite: TestSuite,
+ fn: () => void
+] | [
+ suite: TestSuite,
+ name: string,
+ options: Omit, "fn" | "name" | "suite">,
+ fn: () => void
+] | [
+ suite: TestSuite,
+ options: Omit, "fn" | "suite">,
+ fn: () => void
+] | [
+ suite: TestSuite,
+ options: Omit, "fn" | "name" | "suite">,
+ fn: () => void
+];
+/** Registers a test suite. */
+export interface describe {
+ (...args: DescribeArgs): TestSuite;
+ /** Registers a test suite with only set to true. */
+ only(...args: DescribeArgs): TestSuite;
+ /** Registers a test suite with ignore set to true. */
+ ignore(...args: DescribeArgs): TestSuite;
+ /** Registers a test suite with ignore set to true. Alias of `.ignore()`. */
+ skip(...args: ItArgs): void;
+}
+/** Registers a test suite. */
+export declare function describe(...args: DescribeArgs): TestSuite;
+export declare namespace describe {
+ var only: (...args: DescribeArgs) => TestSuite;
+ var ignore: (...args: DescribeArgs) => TestSuite;
+ var skip: (...args: DescribeArgs) => TestSuite;
+}
diff --git a/npm/esm/deps/deno.land/std@0.213.0/testing/bdd.js b/npm/esm/deps/deno.land/std@0.213.0/testing/bdd.js
new file mode 100644
index 0000000..d9c0035
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.213.0/testing/bdd.js
@@ -0,0 +1,215 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+import { TestSuiteInternal, } from "./_test_suite.js";
+/** Generates an ItDefinition from ItArgs. */
+function itDefinition(...args) {
+ let [suiteOptionsOrNameOrFn, optionsOrNameOrFn, optionsOrFn, fn,] = args;
+ let suite = undefined;
+ let name;
+ let options;
+ if (typeof suiteOptionsOrNameOrFn === "object" &&
+ typeof suiteOptionsOrNameOrFn.symbol === "symbol") {
+ suite = suiteOptionsOrNameOrFn;
+ }
+ else {
+ fn = optionsOrFn;
+ optionsOrFn = optionsOrNameOrFn;
+ optionsOrNameOrFn = suiteOptionsOrNameOrFn;
+ }
+ if (typeof optionsOrNameOrFn === "string") {
+ name = optionsOrNameOrFn;
+ if (typeof optionsOrFn === "function") {
+ fn = optionsOrFn;
+ options = {};
+ }
+ else {
+ options = optionsOrFn;
+ if (!fn)
+ fn = options.fn;
+ }
+ }
+ else if (typeof optionsOrNameOrFn === "function") {
+ fn = optionsOrNameOrFn;
+ name = fn.name;
+ options = {};
+ }
+ else {
+ options = optionsOrNameOrFn;
+ if (typeof optionsOrFn === "function") {
+ fn = optionsOrFn;
+ }
+ else {
+ fn = options.fn;
+ }
+ name = options.name ?? fn.name;
+ }
+ return {
+ suite,
+ ...options,
+ name,
+ fn,
+ };
+}
+/** Registers an individual test case. */
+export function it(...args) {
+ if (TestSuiteInternal.runningCount > 0) {
+ throw new Error("cannot register new test cases after already registered test cases start running");
+ }
+ const options = itDefinition(...args);
+ const { suite } = options;
+ const testSuite = suite
+ ? TestSuiteInternal.suites.get(suite.symbol)
+ : TestSuiteInternal.current;
+ if (!TestSuiteInternal.started)
+ TestSuiteInternal.started = true;
+ if (testSuite) {
+ TestSuiteInternal.addStep(testSuite, options);
+ }
+ else {
+ const { name, fn, ignore, only, permissions, sanitizeExit, sanitizeOps, sanitizeResources, } = options;
+ TestSuiteInternal.registerTest({
+ name,
+ ignore,
+ only,
+ permissions,
+ sanitizeExit,
+ sanitizeOps,
+ sanitizeResources,
+ async fn(t) {
+ TestSuiteInternal.runningCount++;
+ try {
+ await fn.call({}, t);
+ }
+ finally {
+ TestSuiteInternal.runningCount--;
+ }
+ },
+ });
+ }
+}
+it.only = function itOnly(...args) {
+ const options = itDefinition(...args);
+ return it({
+ ...options,
+ only: true,
+ });
+};
+it.ignore = function itIgnore(...args) {
+ const options = itDefinition(...args);
+ return it({
+ ...options,
+ ignore: true,
+ });
+};
+it.skip = it.ignore;
+function addHook(name, fn) {
+ if (!TestSuiteInternal.current) {
+ if (TestSuiteInternal.started) {
+ throw new Error("cannot add global hooks after a global test is registered");
+ }
+ TestSuiteInternal.current = new TestSuiteInternal({
+ name: "global",
+ [name]: fn,
+ });
+ }
+ else {
+ TestSuiteInternal.setHook(TestSuiteInternal.current, name, fn);
+ }
+}
+/** Run some shared setup before all of the tests in the suite. */
+export function beforeAll(fn) {
+ addHook("beforeAll", fn);
+}
+/** Run some shared teardown after all of the tests in the suite. */
+export function afterAll(fn) {
+ addHook("afterAll", fn);
+}
+/** Run some shared setup before each test in the suite. */
+export function beforeEach(fn) {
+ addHook("beforeEach", fn);
+}
+/** Run some shared teardown after each test in the suite. */
+export function afterEach(fn) {
+ addHook("afterEach", fn);
+}
+/** Generates a DescribeDefinition from DescribeArgs. */
+function describeDefinition(...args) {
+ let [suiteOptionsOrNameOrFn, optionsOrNameOrFn, optionsOrFn, fn,] = args;
+ let suite = undefined;
+ let name;
+ let options;
+ if (typeof suiteOptionsOrNameOrFn === "object" &&
+ typeof suiteOptionsOrNameOrFn.symbol === "symbol") {
+ suite = suiteOptionsOrNameOrFn;
+ }
+ else {
+ fn = optionsOrFn;
+ optionsOrFn = optionsOrNameOrFn;
+ optionsOrNameOrFn = suiteOptionsOrNameOrFn;
+ }
+ if (typeof optionsOrNameOrFn === "string") {
+ name = optionsOrNameOrFn;
+ if (typeof optionsOrFn === "function") {
+ fn = optionsOrFn;
+ options = {};
+ }
+ else {
+ options = optionsOrFn ?? {};
+ if (!fn)
+ fn = options.fn;
+ }
+ }
+ else if (typeof optionsOrNameOrFn === "function") {
+ fn = optionsOrNameOrFn;
+ name = fn.name;
+ options = {};
+ }
+ else {
+ options = optionsOrNameOrFn ?? {};
+ if (typeof optionsOrFn === "function") {
+ fn = optionsOrFn;
+ }
+ else {
+ fn = options.fn;
+ }
+ name = options.name ?? fn?.name ?? "";
+ }
+ if (!suite) {
+ suite = options.suite;
+ }
+ if (!suite && TestSuiteInternal.current) {
+ const { symbol } = TestSuiteInternal.current;
+ suite = { symbol };
+ }
+ return {
+ ...options,
+ suite,
+ name,
+ fn,
+ };
+}
+/** Registers a test suite. */
+export function describe(...args) {
+ if (TestSuiteInternal.runningCount > 0) {
+ throw new Error("cannot register new test suites after already registered test cases start running");
+ }
+ const options = describeDefinition(...args);
+ if (!TestSuiteInternal.started)
+ TestSuiteInternal.started = true;
+ const { symbol } = new TestSuiteInternal(options);
+ return { symbol };
+}
+describe.only = function describeOnly(...args) {
+ const options = describeDefinition(...args);
+ return describe({
+ ...options,
+ only: true,
+ });
+};
+describe.ignore = function describeIgnore(...args) {
+ const options = describeDefinition(...args);
+ return describe({
+ ...options,
+ ignore: true,
+ });
+};
+describe.skip = describe.ignore;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/_constants.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/_constants.d.ts
new file mode 100644
index 0000000..53a0535
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/_constants.d.ts
@@ -0,0 +1 @@
+export declare const CAN_NOT_DISPLAY = "[Cannot display]";
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/_constants.js b/npm/esm/deps/deno.land/std@0.216.0/assert/_constants.js
new file mode 100644
index 0000000..0cfc1cf
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/_constants.js
@@ -0,0 +1,2 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+export const CAN_NOT_DISPLAY = "[Cannot display]";
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/_diff.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/_diff.d.ts
new file mode 100644
index 0000000..419fa2e
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/_diff.d.ts
@@ -0,0 +1,27 @@
+export declare const DiffType: {
+ readonly removed: "removed";
+ readonly common: "common";
+ readonly added: "added";
+};
+export type DiffType = keyof typeof DiffType;
+export interface DiffResult {
+ type: DiffType;
+ value: T;
+ details?: Array>;
+}
+/**
+ * Renders the differences between the actual and expected values
+ * @param A Actual value
+ * @param B Expected value
+ */
+export declare function diff(A: T[], B: T[]): Array>;
+/**
+ * Renders the differences between the actual and expected strings
+ * Partially inspired from https://github.com/kpdecker/jsdiff
+ * @param A Actual string
+ * @param B Expected string
+ */
+export declare function diffstr(A: string, B: string): DiffResult[];
+export declare function buildMessage(diffResult: ReadonlyArray>, { stringDiff }?: {
+ stringDiff?: boolean | undefined;
+}): string[];
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/_diff.js b/npm/esm/deps/deno.land/std@0.216.0/assert/_diff.js
new file mode 100644
index 0000000..e84ef0a
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/_diff.js
@@ -0,0 +1,338 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+// This module is browser compatible.
+import { bgGreen, bgRed, bold, gray, green, red, white, } from "../fmt/colors.js";
+export const DiffType = {
+ removed: "removed",
+ common: "common",
+ added: "added",
+};
+const REMOVED = 1;
+const COMMON = 2;
+const ADDED = 3;
+function createCommon(A, B, reverse) {
+ const common = [];
+ if (A.length === 0 || B.length === 0)
+ return [];
+ for (let i = 0; i < Math.min(A.length, B.length); i += 1) {
+ const a = reverse ? A[A.length - i - 1] : A[i];
+ const b = reverse ? B[B.length - i - 1] : B[i];
+ if (a !== undefined && a === b) {
+ common.push(a);
+ }
+ else {
+ return common;
+ }
+ }
+ return common;
+}
+function ensureDefined(item) {
+ if (item === undefined) {
+ throw Error("Unexpected missing FarthestPoint");
+ }
+ return item;
+}
+/**
+ * Renders the differences between the actual and expected values
+ * @param A Actual value
+ * @param B Expected value
+ */
+export function diff(A, B) {
+ const prefixCommon = createCommon(A, B);
+ const suffixCommon = createCommon(A.slice(prefixCommon.length), B.slice(prefixCommon.length), true).reverse();
+ A = suffixCommon.length
+ ? A.slice(prefixCommon.length, -suffixCommon.length)
+ : A.slice(prefixCommon.length);
+ B = suffixCommon.length
+ ? B.slice(prefixCommon.length, -suffixCommon.length)
+ : B.slice(prefixCommon.length);
+ const swapped = B.length > A.length;
+ [A, B] = swapped ? [B, A] : [A, B];
+ const M = A.length;
+ const N = B.length;
+ if (!M && !N && !suffixCommon.length && !prefixCommon.length)
+ return [];
+ if (!N) {
+ return [
+ ...prefixCommon.map((c) => ({ type: DiffType.common, value: c })),
+ ...A.map((a) => ({
+ type: swapped ? DiffType.added : DiffType.removed,
+ value: a,
+ })),
+ ...suffixCommon.map((c) => ({ type: DiffType.common, value: c })),
+ ];
+ }
+ const offset = N;
+ const delta = M - N;
+ const size = M + N + 1;
+ const fp = Array.from({ length: size }, () => ({ y: -1, id: -1 }));
+ /**
+ * INFO:
+ * This buffer is used to save memory and improve performance.
+ * The first half is used to save route and last half is used to save diff
+ * type.
+ * This is because, when I kept new uint8array area to save type,performance
+ * worsened.
+ */
+ const routes = new Uint32Array((M * N + size + 1) * 2);
+ const diffTypesPtrOffset = routes.length / 2;
+ let ptr = 0;
+ let p = -1;
+ function backTrace(A, B, current, swapped) {
+ const M = A.length;
+ const N = B.length;
+ const result = [];
+ let a = M - 1;
+ let b = N - 1;
+ let j = routes[current.id];
+ let type = routes[current.id + diffTypesPtrOffset];
+ while (true) {
+ if (!j && !type)
+ break;
+ const prev = j;
+ if (type === REMOVED) {
+ result.unshift({
+ type: swapped ? DiffType.removed : DiffType.added,
+ value: B[b],
+ });
+ b -= 1;
+ }
+ else if (type === ADDED) {
+ result.unshift({
+ type: swapped ? DiffType.added : DiffType.removed,
+ value: A[a],
+ });
+ a -= 1;
+ }
+ else {
+ result.unshift({ type: DiffType.common, value: A[a] });
+ a -= 1;
+ b -= 1;
+ }
+ j = routes[prev];
+ type = routes[prev + diffTypesPtrOffset];
+ }
+ return result;
+ }
+ function createFP(slide, down, k, M) {
+ if (slide && slide.y === -1 && down && down.y === -1) {
+ return { y: 0, id: 0 };
+ }
+ const isAdding = (down?.y === -1) ||
+ k === M ||
+ (slide?.y || 0) > (down?.y || 0) + 1;
+ if (slide && isAdding) {
+ const prev = slide.id;
+ ptr++;
+ routes[ptr] = prev;
+ routes[ptr + diffTypesPtrOffset] = ADDED;
+ return { y: slide.y, id: ptr };
+ }
+ else if (down && !isAdding) {
+ const prev = down.id;
+ ptr++;
+ routes[ptr] = prev;
+ routes[ptr + diffTypesPtrOffset] = REMOVED;
+ return { y: down.y + 1, id: ptr };
+ }
+ else {
+ throw new Error("Unexpected missing FarthestPoint");
+ }
+ }
+ function snake(k, slide, down, _offset, A, B) {
+ const M = A.length;
+ const N = B.length;
+ if (k < -N || M < k)
+ return { y: -1, id: -1 };
+ const fp = createFP(slide, down, k, M);
+ while (fp.y + k < M && fp.y < N && A[fp.y + k] === B[fp.y]) {
+ const prev = fp.id;
+ ptr++;
+ fp.id = ptr;
+ fp.y += 1;
+ routes[ptr] = prev;
+ routes[ptr + diffTypesPtrOffset] = COMMON;
+ }
+ return fp;
+ }
+ let currentFP = ensureDefined(fp[delta + offset]);
+ while (currentFP && currentFP.y < N) {
+ p = p + 1;
+ for (let k = -p; k < delta; ++k) {
+ fp[k + offset] = snake(k, fp[k - 1 + offset], fp[k + 1 + offset], offset, A, B);
+ }
+ for (let k = delta + p; k > delta; --k) {
+ fp[k + offset] = snake(k, fp[k - 1 + offset], fp[k + 1 + offset], offset, A, B);
+ }
+ fp[delta + offset] = snake(delta, fp[delta - 1 + offset], fp[delta + 1 + offset], offset, A, B);
+ currentFP = ensureDefined(fp[delta + offset]);
+ }
+ return [
+ ...prefixCommon.map((c) => ({ type: DiffType.common, value: c })),
+ ...backTrace(A, B, currentFP, swapped),
+ ...suffixCommon.map((c) => ({ type: DiffType.common, value: c })),
+ ];
+}
+/**
+ * Renders the differences between the actual and expected strings
+ * Partially inspired from https://github.com/kpdecker/jsdiff
+ * @param A Actual string
+ * @param B Expected string
+ */
+export function diffstr(A, B) {
+ function unescape(string) {
+ // unescape invisible characters.
+ // ref: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#escape_sequences
+ return string
+ .replaceAll("\b", "\\b")
+ .replaceAll("\f", "\\f")
+ .replaceAll("\t", "\\t")
+ .replaceAll("\v", "\\v")
+ .replaceAll(// does not remove line breaks
+ /\r\n|\r|\n/g, (str) => str === "\r" ? "\\r" : str === "\n" ? "\\n\n" : "\\r\\n\r\n");
+ }
+ function tokenize(string, { wordDiff = false } = {}) {
+ if (wordDiff) {
+ // Split string on whitespace symbols
+ const tokens = string.split(/([^\S\r\n]+|[()[\]{}'"\r\n]|\b)/);
+ // Extended Latin character set
+ const words = /^[a-zA-Z\u{C0}-\u{FF}\u{D8}-\u{F6}\u{F8}-\u{2C6}\u{2C8}-\u{2D7}\u{2DE}-\u{2FF}\u{1E00}-\u{1EFF}]+$/u;
+ // Join boundary splits that we do not consider to be boundaries and merge empty strings surrounded by word chars
+ for (let i = 0; i < tokens.length - 1; i++) {
+ const token = tokens[i];
+ const tokenPlusTwo = tokens[i + 2];
+ if (!tokens[i + 1] &&
+ token &&
+ tokenPlusTwo &&
+ words.test(token) &&
+ words.test(tokenPlusTwo)) {
+ tokens[i] += tokenPlusTwo;
+ tokens.splice(i + 1, 2);
+ i--;
+ }
+ }
+ return tokens.filter((token) => token);
+ }
+ else {
+ // Split string on new lines symbols
+ const tokens = [];
+ const lines = string.split(/(\n|\r\n)/);
+ // Ignore final empty token when text ends with a newline
+ if (!lines[lines.length - 1]) {
+ lines.pop();
+ }
+ // Merge the content and line separators into single tokens
+ for (const [i, line] of lines.entries()) {
+ if (i % 2) {
+ tokens[tokens.length - 1] += line;
+ }
+ else {
+ tokens.push(line);
+ }
+ }
+ return tokens;
+ }
+ }
+ // Create details by filtering relevant word-diff for current line
+ // and merge "space-diff" if surrounded by word-diff for cleaner displays
+ function createDetails(line, tokens) {
+ return tokens.filter(({ type }) => type === line.type || type === DiffType.common).map((result, i, t) => {
+ const token = t[i - 1];
+ if ((result.type === DiffType.common) && token &&
+ (token.type === t[i + 1]?.type) && /\s+/.test(result.value)) {
+ return {
+ ...result,
+ type: token.type,
+ };
+ }
+ return result;
+ });
+ }
+ // Compute multi-line diff
+ const diffResult = diff(tokenize(`${unescape(A)}\n`), tokenize(`${unescape(B)}\n`));
+ const added = [], removed = [];
+ for (const result of diffResult) {
+ if (result.type === DiffType.added) {
+ added.push(result);
+ }
+ if (result.type === DiffType.removed) {
+ removed.push(result);
+ }
+ }
+ // Compute word-diff
+ const hasMoreRemovedLines = added.length < removed.length;
+ const aLines = hasMoreRemovedLines ? added : removed;
+ const bLines = hasMoreRemovedLines ? removed : added;
+ for (const a of aLines) {
+ let tokens = [], b;
+ // Search another diff line with at least one common token
+ while (bLines.length) {
+ b = bLines.shift();
+ const tokenized = [
+ tokenize(a.value, { wordDiff: true }),
+ tokenize(b?.value ?? "", { wordDiff: true }),
+ ];
+ if (hasMoreRemovedLines)
+ tokenized.reverse();
+ tokens = diff(tokenized[0], tokenized[1]);
+ if (tokens.some(({ type, value }) => type === DiffType.common && value.trim().length)) {
+ break;
+ }
+ }
+ // Register word-diff details
+ a.details = createDetails(a, tokens);
+ if (b) {
+ b.details = createDetails(b, tokens);
+ }
+ }
+ return diffResult;
+}
+/**
+ * Colors the output of assertion diffs
+ * @param diffType Difference type, either added or removed
+ */
+function createColor(diffType, { background = false } = {}) {
+ // TODO(@littledivy): Remove this when we can detect
+ // true color terminals.
+ // https://github.com/denoland/deno_std/issues/2575
+ background = false;
+ switch (diffType) {
+ case DiffType.added:
+ return (s) => background ? bgGreen(white(s)) : green(bold(s));
+ case DiffType.removed:
+ return (s) => background ? bgRed(white(s)) : red(bold(s));
+ default:
+ return white;
+ }
+}
+/**
+ * Prefixes `+` or `-` in diff output
+ * @param diffType Difference type, either added or removed
+ */
+function createSign(diffType) {
+ switch (diffType) {
+ case DiffType.added:
+ return "+ ";
+ case DiffType.removed:
+ return "- ";
+ default:
+ return " ";
+ }
+}
+export function buildMessage(diffResult, { stringDiff = false } = {}) {
+ const messages = [], diffMessages = [];
+ messages.push("");
+ messages.push("");
+ messages.push(` ${gray(bold("[Diff]"))} ${red(bold("Actual"))} / ${green(bold("Expected"))}`);
+ messages.push("");
+ messages.push("");
+ diffResult.forEach((result) => {
+ const c = createColor(result.type);
+ const line = result.details?.map((detail) => detail.type !== DiffType.common
+ ? createColor(detail.type, { background: true })(detail.value)
+ : detail.value).join("") ?? result.value;
+ diffMessages.push(c(`${createSign(result.type)}${line}`));
+ });
+ messages.push(...(stringDiff ? [diffMessages.join("")] : diffMessages));
+ messages.push("");
+ return messages;
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/_format.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/_format.d.ts
new file mode 100644
index 0000000..47af53c
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/_format.d.ts
@@ -0,0 +1 @@
+export declare function format(v: unknown): string;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/_format.js b/npm/esm/deps/deno.land/std@0.216.0/assert/_format.js
new file mode 100644
index 0000000..a2ffcae
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/_format.js
@@ -0,0 +1,25 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+// This module is browser compatible.
+// This file been copied to `std/expect`.
+/**
+ * Converts the input into a string. Objects, Sets and Maps are sorted so as to
+ * make tests less flaky
+ * @param v Value to be formatted
+ */
+import * as dntShim from "../../../../_dnt.test_shims.js";
+export function format(v) {
+ // deno-lint-ignore no-explicit-any
+ const { Deno } = dntShim.dntGlobalThis;
+ return typeof Deno?.inspect === "function"
+ ? Deno.inspect(v, {
+ depth: Infinity,
+ sorted: true,
+ trailingComma: true,
+ compact: false,
+ iterableLimit: Infinity,
+ // getters should be true in assertEquals.
+ getters: true,
+ strAbbreviateSize: Infinity,
+ })
+ : `"${String(v).replace(/(?=["\\])/g, "\\")}"`;
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/assert.d.ts
new file mode 100644
index 0000000..260dd5d
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert.d.ts
@@ -0,0 +1,12 @@
+/**
+ * Make an assertion, error will be thrown if `expr` does not have truthy value.
+ *
+ * @example
+ * ```ts
+ * import { assert } from "https://deno.land/std@$STD_VERSION/assert/assert.ts";
+ *
+ * assert("hello".includes("ello")); // Doesn't throw
+ * assert("hello".includes("world")); // Throws
+ * ```
+ */
+export declare function assert(expr: unknown, msg?: string): asserts expr;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert.js b/npm/esm/deps/deno.land/std@0.216.0/assert/assert.js
new file mode 100644
index 0000000..b8dc7bd
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert.js
@@ -0,0 +1,18 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+import { AssertionError } from "./assertion_error.js";
+/**
+ * Make an assertion, error will be thrown if `expr` does not have truthy value.
+ *
+ * @example
+ * ```ts
+ * import { assert } from "https://deno.land/std@$STD_VERSION/assert/assert.ts";
+ *
+ * assert("hello".includes("ello")); // Doesn't throw
+ * assert("hello".includes("world")); // Throws
+ * ```
+ */
+export function assert(expr, msg = "") {
+ if (!expr) {
+ throw new AssertionError(msg);
+ }
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_almost_equals.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_almost_equals.d.ts
new file mode 100644
index 0000000..7481c85
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_almost_equals.d.ts
@@ -0,0 +1,17 @@
+/**
+ * Make an assertion that `actual` and `expected` are almost equal numbers
+ * through a given tolerance. It can be used to take into account IEEE-754
+ * double-precision floating-point representation limitations. If the values
+ * are not almost equal then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertAlmostEquals } from "https://deno.land/std@$STD_VERSION/assert/mod.ts";
+ *
+ * assertAlmostEquals(0.01, 0.02, 0.1); // Doesn't throw
+ * assertAlmostEquals(0.01, 0.02); // Throws
+ * assertAlmostEquals(0.1 + 0.2, 0.3, 1e-16); // Doesn't throw
+ * assertAlmostEquals(0.1 + 0.2, 0.3, 1e-17); // Throws
+ * ```
+ */
+export declare function assertAlmostEquals(actual: number, expected: number, tolerance?: number, msg?: string): void;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_almost_equals.js b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_almost_equals.js
new file mode 100644
index 0000000..58b0dd4
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_almost_equals.js
@@ -0,0 +1,31 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+import { AssertionError } from "./assertion_error.js";
+/**
+ * Make an assertion that `actual` and `expected` are almost equal numbers
+ * through a given tolerance. It can be used to take into account IEEE-754
+ * double-precision floating-point representation limitations. If the values
+ * are not almost equal then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertAlmostEquals } from "https://deno.land/std@$STD_VERSION/assert/mod.ts";
+ *
+ * assertAlmostEquals(0.01, 0.02, 0.1); // Doesn't throw
+ * assertAlmostEquals(0.01, 0.02); // Throws
+ * assertAlmostEquals(0.1 + 0.2, 0.3, 1e-16); // Doesn't throw
+ * assertAlmostEquals(0.1 + 0.2, 0.3, 1e-17); // Throws
+ * ```
+ */
+export function assertAlmostEquals(actual, expected, tolerance = 1e-7, msg) {
+ if (Object.is(actual, expected)) {
+ return;
+ }
+ const delta = Math.abs(expected - actual);
+ if (delta <= tolerance) {
+ return;
+ }
+ const msgSuffix = msg ? `: ${msg}` : ".";
+ const f = (n) => Number.isInteger(n) ? n : n.toExponential();
+ throw new AssertionError(`Expected actual: "${f(actual)}" to be close to "${f(expected)}": \
+delta "${f(delta)}" is greater than "${f(tolerance)}"${msgSuffix}`);
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_array_includes.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_array_includes.d.ts
new file mode 100644
index 0000000..9b79d23
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_array_includes.d.ts
@@ -0,0 +1,18 @@
+/** An array-like object (`Array`, `Uint8Array`, `NodeList`, etc.) that is not a string */
+export type ArrayLikeArg = ArrayLike & object;
+/**
+ * Make an assertion that `actual` includes the `expected` values. If not then
+ * an error will be thrown.
+ *
+ * Type parameter can be specified to ensure values under comparison have the
+ * same type.
+ *
+ * @example
+ * ```ts
+ * import { assertArrayIncludes } from "https://deno.land/std@$STD_VERSION/assert/assert_array_includes.ts";
+ *
+ * assertArrayIncludes([1, 2], [2]); // Doesn't throw
+ * assertArrayIncludes([1, 2], [3]); // Throws
+ * ```
+ */
+export declare function assertArrayIncludes(actual: ArrayLikeArg, expected: ArrayLikeArg, msg?: string): void;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_array_includes.js b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_array_includes.js
new file mode 100644
index 0000000..b0ea5a7
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_array_includes.js
@@ -0,0 +1,40 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+import { equal } from "./equal.js";
+import { format } from "./_format.js";
+import { AssertionError } from "./assertion_error.js";
+/**
+ * Make an assertion that `actual` includes the `expected` values. If not then
+ * an error will be thrown.
+ *
+ * Type parameter can be specified to ensure values under comparison have the
+ * same type.
+ *
+ * @example
+ * ```ts
+ * import { assertArrayIncludes } from "https://deno.land/std@$STD_VERSION/assert/assert_array_includes.ts";
+ *
+ * assertArrayIncludes([1, 2], [2]); // Doesn't throw
+ * assertArrayIncludes([1, 2], [3]); // Throws
+ * ```
+ */
+export function assertArrayIncludes(actual, expected, msg) {
+ const missing = [];
+ for (let i = 0; i < expected.length; i++) {
+ let found = false;
+ for (let j = 0; j < actual.length; j++) {
+ if (equal(expected[i], actual[j])) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ missing.push(expected[i]);
+ }
+ }
+ if (missing.length === 0) {
+ return;
+ }
+ const msgSuffix = msg ? `: ${msg}` : ".";
+ msg = `Expected actual: "${format(actual)}" to include: "${format(expected)}"${msgSuffix}\nmissing: ${format(missing)}`;
+ throw new AssertionError(msg);
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_equals.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_equals.d.ts
new file mode 100644
index 0000000..0a733ce
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_equals.d.ts
@@ -0,0 +1,20 @@
+/**
+ * Make an assertion that `actual` and `expected` are equal, deeply. If not
+ * deeply equal, then throw.
+ *
+ * Type parameter can be specified to ensure values under comparison have the
+ * same type.
+ *
+ * @example
+ * ```ts
+ * import { assertEquals } from "https://deno.land/std@$STD_VERSION/assert/assert_equals.ts";
+ *
+ * assertEquals("world", "world"); // Doesn't throw
+ * assertEquals("hello", "world"); // Throws
+ * ```
+ *
+ * Note: formatter option is experimental and may be removed in the future.
+ */
+export declare function assertEquals(actual: T, expected: T, msg?: string, options?: {
+ formatter?: (value: unknown) => string;
+}): void;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_equals.js b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_equals.js
new file mode 100644
index 0000000..5eb718f
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_equals.js
@@ -0,0 +1,47 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+import { equal } from "./equal.js";
+import { format } from "./_format.js";
+import { AssertionError } from "./assertion_error.js";
+import { red } from "../fmt/colors.js";
+import { buildMessage, diff, diffstr } from "./_diff.js";
+import { CAN_NOT_DISPLAY } from "./_constants.js";
+/**
+ * Make an assertion that `actual` and `expected` are equal, deeply. If not
+ * deeply equal, then throw.
+ *
+ * Type parameter can be specified to ensure values under comparison have the
+ * same type.
+ *
+ * @example
+ * ```ts
+ * import { assertEquals } from "https://deno.land/std@$STD_VERSION/assert/assert_equals.ts";
+ *
+ * assertEquals("world", "world"); // Doesn't throw
+ * assertEquals("hello", "world"); // Throws
+ * ```
+ *
+ * Note: formatter option is experimental and may be removed in the future.
+ */
+export function assertEquals(actual, expected, msg, options = {}) {
+ if (equal(actual, expected)) {
+ return;
+ }
+ const { formatter = format } = options;
+ const msgSuffix = msg ? `: ${msg}` : ".";
+ let message = `Values are not equal${msgSuffix}`;
+ const actualString = formatter(actual);
+ const expectedString = formatter(expected);
+ try {
+ const stringDiff = (typeof actual === "string") &&
+ (typeof expected === "string");
+ const diffResult = stringDiff
+ ? diffstr(actual, expected)
+ : diff(actualString.split("\n"), expectedString.split("\n"));
+ const diffMsg = buildMessage(diffResult, { stringDiff }).join("\n");
+ message = `${message}\n${diffMsg}`;
+ }
+ catch {
+ message = `${message}\n${red(CAN_NOT_DISPLAY)} + \n\n`;
+ }
+ throw new AssertionError(message);
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_exists.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_exists.d.ts
new file mode 100644
index 0000000..f643295
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_exists.d.ts
@@ -0,0 +1,13 @@
+/**
+ * Make an assertion that actual is not null or undefined.
+ * If not then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertExists } from "https://deno.land/std@$STD_VERSION/assert/assert_exists.ts";
+ *
+ * assertExists("something"); // Doesn't throw
+ * assertExists(undefined); // Throws
+ * ```
+ */
+export declare function assertExists(actual: T, msg?: string): asserts actual is NonNullable;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_exists.js b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_exists.js
new file mode 100644
index 0000000..2dee36f
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_exists.js
@@ -0,0 +1,22 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+import { AssertionError } from "./assertion_error.js";
+/**
+ * Make an assertion that actual is not null or undefined.
+ * If not then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertExists } from "https://deno.land/std@$STD_VERSION/assert/assert_exists.ts";
+ *
+ * assertExists("something"); // Doesn't throw
+ * assertExists(undefined); // Throws
+ * ```
+ */
+export function assertExists(actual, msg) {
+ if (actual === undefined || actual === null) {
+ const msgSuffix = msg ? `: ${msg}` : ".";
+ msg =
+ `Expected actual: "${actual}" to not be null or undefined${msgSuffix}`;
+ throw new AssertionError(msg);
+ }
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_false.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_false.d.ts
new file mode 100644
index 0000000..d523087
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_false.d.ts
@@ -0,0 +1,14 @@
+/** Assertion condition for {@linkcode assertFalse}. */
+export type Falsy = false | 0 | 0n | "" | null | undefined;
+/**
+ * Make an assertion, error will be thrown if `expr` have truthy value.
+ *
+ * @example
+ * ```ts
+ * import { assertFalse } from "https://deno.land/std@$STD_VERSION/assert/assert_false.ts";
+ *
+ * assertFalse(false); // Doesn't throw
+ * assertFalse(true); // Throws
+ * ```
+ */
+export declare function assertFalse(expr: unknown, msg?: string): asserts expr is Falsy;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_false.js b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_false.js
new file mode 100644
index 0000000..fc7a90f
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_false.js
@@ -0,0 +1,18 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+import { AssertionError } from "./assertion_error.js";
+/**
+ * Make an assertion, error will be thrown if `expr` have truthy value.
+ *
+ * @example
+ * ```ts
+ * import { assertFalse } from "https://deno.land/std@$STD_VERSION/assert/assert_false.ts";
+ *
+ * assertFalse(false); // Doesn't throw
+ * assertFalse(true); // Throws
+ * ```
+ */
+export function assertFalse(expr, msg = "") {
+ if (expr) {
+ throw new AssertionError(msg);
+ }
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_greater.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_greater.d.ts
new file mode 100644
index 0000000..143bd25
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_greater.d.ts
@@ -0,0 +1,14 @@
+/**
+ * Make an assertion that `actual` is greater than `expected`.
+ * If not then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertGreater } from "https://deno.land/std@$STD_VERSION/assert/assert_greater.ts";
+ *
+ * assertGreater(2, 1); // Doesn't throw
+ * assertGreater(1, 1); // Throws
+ * assertGreater(0, 1); // Throws
+ * ```
+ */
+export declare function assertGreater(actual: T, expected: T, msg?: string): void;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_greater.js b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_greater.js
new file mode 100644
index 0000000..d1ed003
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_greater.js
@@ -0,0 +1,23 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+import { format } from "./_format.js";
+import { AssertionError } from "./assertion_error.js";
+/**
+ * Make an assertion that `actual` is greater than `expected`.
+ * If not then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertGreater } from "https://deno.land/std@$STD_VERSION/assert/assert_greater.ts";
+ *
+ * assertGreater(2, 1); // Doesn't throw
+ * assertGreater(1, 1); // Throws
+ * assertGreater(0, 1); // Throws
+ * ```
+ */
+export function assertGreater(actual, expected, msg) {
+ if (actual > expected)
+ return;
+ const actualString = format(actual);
+ const expectedString = format(expected);
+ throw new AssertionError(msg ?? `Expect ${actualString} > ${expectedString}`);
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_greater_or_equal.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_greater_or_equal.d.ts
new file mode 100644
index 0000000..5c1a821
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_greater_or_equal.d.ts
@@ -0,0 +1,14 @@
+/**
+ * Make an assertion that `actual` is greater than or equal to `expected`.
+ * If not then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertGreaterOrEqual } from "https://deno.land/std@$STD_VERSION/assert/assert_greater_or_equal.ts";
+ *
+ * assertGreaterOrEqual(2, 1); // Doesn't throw
+ * assertGreaterOrEqual(1, 1); // Doesn't throw
+ * assertGreaterOrEqual(0, 1); // Throws
+ * ```
+ */
+export declare function assertGreaterOrEqual(actual: T, expected: T, msg?: string): void;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_greater_or_equal.js b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_greater_or_equal.js
new file mode 100644
index 0000000..5d98971
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_greater_or_equal.js
@@ -0,0 +1,23 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+import { format } from "./_format.js";
+import { AssertionError } from "./assertion_error.js";
+/**
+ * Make an assertion that `actual` is greater than or equal to `expected`.
+ * If not then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertGreaterOrEqual } from "https://deno.land/std@$STD_VERSION/assert/assert_greater_or_equal.ts";
+ *
+ * assertGreaterOrEqual(2, 1); // Doesn't throw
+ * assertGreaterOrEqual(1, 1); // Doesn't throw
+ * assertGreaterOrEqual(0, 1); // Throws
+ * ```
+ */
+export function assertGreaterOrEqual(actual, expected, msg) {
+ if (actual >= expected)
+ return;
+ const actualString = format(actual);
+ const expectedString = format(expected);
+ throw new AssertionError(msg ?? `Expect ${actualString} >= ${expectedString}`);
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_instance_of.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_instance_of.d.ts
new file mode 100644
index 0000000..04cebbb
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_instance_of.d.ts
@@ -0,0 +1,17 @@
+/** Any constructor */
+export type AnyConstructor = new (...args: any[]) => any;
+/** Gets constructor type */
+export type GetConstructorType = T extends new (...args: any) => infer C ? C : never;
+/**
+ * Make an assertion that `obj` is an instance of `type`.
+ * If not then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertInstanceOf } from "https://deno.land/std@$STD_VERSION/assert/assert_instance_of.ts";
+ *
+ * assertInstanceOf(new Date(), Date); // Doesn't throw
+ * assertInstanceOf(new Date(), Number); // Throws
+ * ```
+ */
+export declare function assertInstanceOf(actual: unknown, expectedType: T, msg?: string): asserts actual is GetConstructorType;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_instance_of.js b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_instance_of.js
new file mode 100644
index 0000000..fcb30c5
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_instance_of.js
@@ -0,0 +1,46 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+import { AssertionError } from "./assertion_error.js";
+/**
+ * Make an assertion that `obj` is an instance of `type`.
+ * If not then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertInstanceOf } from "https://deno.land/std@$STD_VERSION/assert/assert_instance_of.ts";
+ *
+ * assertInstanceOf(new Date(), Date); // Doesn't throw
+ * assertInstanceOf(new Date(), Number); // Throws
+ * ```
+ */
+export function assertInstanceOf(actual, expectedType, msg = "") {
+ if (actual instanceof expectedType)
+ return;
+ const msgSuffix = msg ? `: ${msg}` : ".";
+ const expectedTypeStr = expectedType.name;
+ let actualTypeStr = "";
+ if (actual === null) {
+ actualTypeStr = "null";
+ }
+ else if (actual === undefined) {
+ actualTypeStr = "undefined";
+ }
+ else if (typeof actual === "object") {
+ actualTypeStr = actual.constructor?.name ?? "Object";
+ }
+ else {
+ actualTypeStr = typeof actual;
+ }
+ if (expectedTypeStr === actualTypeStr) {
+ msg =
+ `Expected object to be an instance of "${expectedTypeStr}"${msgSuffix}`;
+ }
+ else if (actualTypeStr === "function") {
+ msg =
+ `Expected object to be an instance of "${expectedTypeStr}" but was not an instanced object${msgSuffix}`;
+ }
+ else {
+ msg =
+ `Expected object to be an instance of "${expectedTypeStr}" but was "${actualTypeStr}"${msgSuffix}`;
+ }
+ throw new AssertionError(msg);
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_is_error.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_is_error.d.ts
new file mode 100644
index 0000000..9db664b
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_is_error.d.ts
@@ -0,0 +1,18 @@
+/**
+ * Make an assertion that `error` is an `Error`.
+ * If not then an error will be thrown.
+ * An error class and a string that should be included in the
+ * error message can also be asserted.
+ *
+ * @example
+ * ```ts
+ * import { assertIsError } from "https://deno.land/std@$STD_VERSION/assert/assert_is_error.ts";
+ *
+ * assertIsError(null); // Throws
+ * assertIsError(new RangeError("Out of range")); // Doesn't throw
+ * assertIsError(new RangeError("Out of range"), SyntaxError); // Throws
+ * assertIsError(new RangeError("Out of range"), SyntaxError, "Out of range"); // Doesn't throw
+ * assertIsError(new RangeError("Out of range"), SyntaxError, "Within range"); // Throws
+ * ```
+ */
+export declare function assertIsError(error: unknown, ErrorClass?: new (...args: any[]) => E, msgMatches?: string | RegExp, msg?: string): asserts error is E;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_is_error.js b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_is_error.js
new file mode 100644
index 0000000..ad45769
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_is_error.js
@@ -0,0 +1,48 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+import { AssertionError } from "./assertion_error.js";
+import { stripAnsiCode } from "../fmt/colors.js";
+/**
+ * Make an assertion that `error` is an `Error`.
+ * If not then an error will be thrown.
+ * An error class and a string that should be included in the
+ * error message can also be asserted.
+ *
+ * @example
+ * ```ts
+ * import { assertIsError } from "https://deno.land/std@$STD_VERSION/assert/assert_is_error.ts";
+ *
+ * assertIsError(null); // Throws
+ * assertIsError(new RangeError("Out of range")); // Doesn't throw
+ * assertIsError(new RangeError("Out of range"), SyntaxError); // Throws
+ * assertIsError(new RangeError("Out of range"), SyntaxError, "Out of range"); // Doesn't throw
+ * assertIsError(new RangeError("Out of range"), SyntaxError, "Within range"); // Throws
+ * ```
+ */
+export function assertIsError(error,
+// deno-lint-ignore no-explicit-any
+ErrorClass, msgMatches, msg) {
+ const msgSuffix = msg ? `: ${msg}` : ".";
+ if (!(error instanceof Error)) {
+ throw new AssertionError(`Expected "error" to be an Error object${msgSuffix}}`);
+ }
+ if (ErrorClass && !(error instanceof ErrorClass)) {
+ msg = `Expected error to be instance of "${ErrorClass.name}", but was "${typeof error === "object" ? error?.constructor?.name : "[not an object]"}"${msgSuffix}`;
+ throw new AssertionError(msg);
+ }
+ let msgCheck;
+ if (typeof msgMatches === "string") {
+ msgCheck = stripAnsiCode(error.message).includes(stripAnsiCode(msgMatches));
+ }
+ if (msgMatches instanceof RegExp) {
+ msgCheck = msgMatches.test(stripAnsiCode(error.message));
+ }
+ if (msgMatches && !msgCheck) {
+ msg = `Expected error message to include ${msgMatches instanceof RegExp
+ ? msgMatches.toString()
+ : JSON.stringify(msgMatches)}, but got ${error instanceof Error
+ ? JSON.stringify(error.message)
+ : '"[not an Error]"' // TODO(kt3k): show more useful information
+ }${msgSuffix}`;
+ throw new AssertionError(msg);
+ }
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_less.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_less.d.ts
new file mode 100644
index 0000000..6fcdfa0
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_less.d.ts
@@ -0,0 +1,13 @@
+/**
+ * Make an assertion that `actual` is less than `expected`.
+ * If not then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertLess } from "https://deno.land/std@$STD_VERSION/assert/assert_less.ts";
+ *
+ * assertLess(1, 2); // Doesn't throw
+ * assertLess(2, 1); // Throws
+ * ```
+ */
+export declare function assertLess(actual: T, expected: T, msg?: string): void;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_less.js b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_less.js
new file mode 100644
index 0000000..01e7ca7
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_less.js
@@ -0,0 +1,22 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+import { format } from "./_format.js";
+import { AssertionError } from "./assertion_error.js";
+/**
+ * Make an assertion that `actual` is less than `expected`.
+ * If not then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertLess } from "https://deno.land/std@$STD_VERSION/assert/assert_less.ts";
+ *
+ * assertLess(1, 2); // Doesn't throw
+ * assertLess(2, 1); // Throws
+ * ```
+ */
+export function assertLess(actual, expected, msg) {
+ if (actual < expected)
+ return;
+ const actualString = format(actual);
+ const expectedString = format(expected);
+ throw new AssertionError(msg ?? `Expect ${actualString} < ${expectedString}`);
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_less_or_equal.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_less_or_equal.d.ts
new file mode 100644
index 0000000..f715009
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_less_or_equal.d.ts
@@ -0,0 +1,14 @@
+/**
+ * Make an assertion that `actual` is less than or equal to `expected`.
+ * If not then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertLessOrEqual } from "https://deno.land/std@$STD_VERSION/assert/assert_less_or_equal.ts";
+ *
+ * assertLessOrEqual(1, 2); // Doesn't throw
+ * assertLessOrEqual(1, 1); // Doesn't throw
+ * assertLessOrEqual(1, 0); // Throws
+ * ```
+ */
+export declare function assertLessOrEqual(actual: T, expected: T, msg?: string): void;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_less_or_equal.js b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_less_or_equal.js
new file mode 100644
index 0000000..abeeb68
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_less_or_equal.js
@@ -0,0 +1,23 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+import { format } from "./_format.js";
+import { AssertionError } from "./assertion_error.js";
+/**
+ * Make an assertion that `actual` is less than or equal to `expected`.
+ * If not then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertLessOrEqual } from "https://deno.land/std@$STD_VERSION/assert/assert_less_or_equal.ts";
+ *
+ * assertLessOrEqual(1, 2); // Doesn't throw
+ * assertLessOrEqual(1, 1); // Doesn't throw
+ * assertLessOrEqual(1, 0); // Throws
+ * ```
+ */
+export function assertLessOrEqual(actual, expected, msg) {
+ if (actual <= expected)
+ return;
+ const actualString = format(actual);
+ const expectedString = format(expected);
+ throw new AssertionError(msg ?? `Expect ${actualString} <= ${expectedString}`);
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_match.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_match.d.ts
new file mode 100644
index 0000000..fb0af0d
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_match.d.ts
@@ -0,0 +1,13 @@
+/**
+ * Make an assertion that `actual` match RegExp `expected`. If not
+ * then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertMatch } from "https://deno.land/std@$STD_VERSION/assert/assert_match.ts";
+ *
+ * assertMatch("Raptor", RegExp(/Raptor/)); // Doesn't throw
+ * assertMatch("Denosaurus", RegExp(/Raptor/)); // Throws
+ * ```
+ */
+export declare function assertMatch(actual: string, expected: RegExp, msg?: string): void;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_match.js b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_match.js
new file mode 100644
index 0000000..b9e0f54
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_match.js
@@ -0,0 +1,21 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+import { AssertionError } from "./assertion_error.js";
+/**
+ * Make an assertion that `actual` match RegExp `expected`. If not
+ * then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertMatch } from "https://deno.land/std@$STD_VERSION/assert/assert_match.ts";
+ *
+ * assertMatch("Raptor", RegExp(/Raptor/)); // Doesn't throw
+ * assertMatch("Denosaurus", RegExp(/Raptor/)); // Throws
+ * ```
+ */
+export function assertMatch(actual, expected, msg) {
+ if (!expected.test(actual)) {
+ const msgSuffix = msg ? `: ${msg}` : ".";
+ msg = `Expected actual: "${actual}" to match: "${expected}"${msgSuffix}`;
+ throw new AssertionError(msg);
+ }
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_not_equals.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_not_equals.d.ts
new file mode 100644
index 0000000..6357f36
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_not_equals.d.ts
@@ -0,0 +1,15 @@
+/**
+ * Make an assertion that `actual` and `expected` are not equal, deeply.
+ * If not then throw.
+ *
+ * Type parameter can be specified to ensure values under comparison have the same type.
+ *
+ * @example
+ * ```ts
+ * import { assertNotEquals } from "https://deno.land/std@$STD_VERSION/assert/assert_not_equals.ts";
+ *
+ * assertNotEquals(1, 2); // Doesn't throw
+ * assertNotEquals(1, 1); // Throws
+ * ```
+ */
+export declare function assertNotEquals(actual: T, expected: T, msg?: string): void;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_not_equals.js b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_not_equals.js
new file mode 100644
index 0000000..b9b693a
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_not_equals.js
@@ -0,0 +1,39 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+import { CAN_NOT_DISPLAY } from "./_constants.js";
+import { equal } from "./equal.js";
+import { AssertionError } from "./assertion_error.js";
+/**
+ * Make an assertion that `actual` and `expected` are not equal, deeply.
+ * If not then throw.
+ *
+ * Type parameter can be specified to ensure values under comparison have the same type.
+ *
+ * @example
+ * ```ts
+ * import { assertNotEquals } from "https://deno.land/std@$STD_VERSION/assert/assert_not_equals.ts";
+ *
+ * assertNotEquals(1, 2); // Doesn't throw
+ * assertNotEquals(1, 1); // Throws
+ * ```
+ */
+export function assertNotEquals(actual, expected, msg) {
+ if (!equal(actual, expected)) {
+ return;
+ }
+ let actualString;
+ let expectedString;
+ try {
+ actualString = String(actual);
+ }
+ catch {
+ actualString = CAN_NOT_DISPLAY;
+ }
+ try {
+ expectedString = String(expected);
+ }
+ catch {
+ expectedString = CAN_NOT_DISPLAY;
+ }
+ const msgSuffix = msg ? `: ${msg}` : ".";
+ throw new AssertionError(`Expected actual: ${actualString} not to be: ${expectedString}${msgSuffix}`);
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_not_instance_of.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_not_instance_of.d.ts
new file mode 100644
index 0000000..8fbbc20
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_not_instance_of.d.ts
@@ -0,0 +1,13 @@
+/**
+ * Make an assertion that `obj` is not an instance of `type`.
+ * If so, then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertNotInstanceOf } from "https://deno.land/std@$STD_VERSION/assert/assert_not_instance_of.ts";
+ *
+ * assertNotInstanceOf(new Date(), Number); // Doesn't throw
+ * assertNotInstanceOf(new Date(), Date); // Throws
+ * ```
+ */
+export declare function assertNotInstanceOf(actual: A, unexpectedType: new (...args: any[]) => T, msg?: string): asserts actual is Exclude ;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_not_instance_of.js b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_not_instance_of.js
new file mode 100644
index 0000000..cac39a2
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_not_instance_of.js
@@ -0,0 +1,22 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+import { assertFalse } from "./assert_false.js";
+/**
+ * Make an assertion that `obj` is not an instance of `type`.
+ * If so, then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertNotInstanceOf } from "https://deno.land/std@$STD_VERSION/assert/assert_not_instance_of.ts";
+ *
+ * assertNotInstanceOf(new Date(), Number); // Doesn't throw
+ * assertNotInstanceOf(new Date(), Date); // Throws
+ * ```
+ */
+export function assertNotInstanceOf(actual,
+// deno-lint-ignore no-explicit-any
+unexpectedType, msg) {
+ const msgSuffix = msg ? `: ${msg}` : ".";
+ msg =
+ `Expected object to not be an instance of "${typeof unexpectedType}"${msgSuffix}`;
+ assertFalse(actual instanceof unexpectedType, msg);
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_not_match.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_not_match.d.ts
new file mode 100644
index 0000000..f6bfb10
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_not_match.d.ts
@@ -0,0 +1,13 @@
+/**
+ * Make an assertion that `actual` not match RegExp `expected`. If match
+ * then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertNotMatch } from "https://deno.land/std@$STD_VERSION/assert/assert_not_match.ts";
+ *
+ * assertNotMatch("Denosaurus", RegExp(/Raptor/)); // Doesn't throw
+ * assertNotMatch("Raptor", RegExp(/Raptor/)); // Throws
+ * ```
+ */
+export declare function assertNotMatch(actual: string, expected: RegExp, msg?: string): void;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_not_match.js b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_not_match.js
new file mode 100644
index 0000000..675cf1d
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_not_match.js
@@ -0,0 +1,22 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+import { AssertionError } from "./assertion_error.js";
+/**
+ * Make an assertion that `actual` not match RegExp `expected`. If match
+ * then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertNotMatch } from "https://deno.land/std@$STD_VERSION/assert/assert_not_match.ts";
+ *
+ * assertNotMatch("Denosaurus", RegExp(/Raptor/)); // Doesn't throw
+ * assertNotMatch("Raptor", RegExp(/Raptor/)); // Throws
+ * ```
+ */
+export function assertNotMatch(actual, expected, msg) {
+ if (expected.test(actual)) {
+ const msgSuffix = msg ? `: ${msg}` : ".";
+ msg =
+ `Expected actual: "${actual}" to not match: "${expected}"${msgSuffix}`;
+ throw new AssertionError(msg);
+ }
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_not_strict_equals.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_not_strict_equals.d.ts
new file mode 100644
index 0000000..49e2921
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_not_strict_equals.d.ts
@@ -0,0 +1,13 @@
+/**
+ * Make an assertion that `actual` and `expected` are not strictly equal.
+ * If the values are strictly equal then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertNotStrictEquals } from "https://deno.land/std@$STD_VERSION/assert/assert_not_strict_equals.ts";
+ *
+ * assertNotStrictEquals(1, 1); // Doesn't throw
+ * assertNotStrictEquals(1, 2); // Throws
+ * ```
+ */
+export declare function assertNotStrictEquals(actual: T, expected: T, msg?: string): void;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_not_strict_equals.js b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_not_strict_equals.js
new file mode 100644
index 0000000..255e1cc
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_not_strict_equals.js
@@ -0,0 +1,22 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+import { AssertionError } from "./assertion_error.js";
+import { format } from "./_format.js";
+/**
+ * Make an assertion that `actual` and `expected` are not strictly equal.
+ * If the values are strictly equal then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertNotStrictEquals } from "https://deno.land/std@$STD_VERSION/assert/assert_not_strict_equals.ts";
+ *
+ * assertNotStrictEquals(1, 1); // Doesn't throw
+ * assertNotStrictEquals(1, 2); // Throws
+ * ```
+ */
+export function assertNotStrictEquals(actual, expected, msg) {
+ if (!Object.is(actual, expected)) {
+ return;
+ }
+ const msgSuffix = msg ? `: ${msg}` : ".";
+ throw new AssertionError(`Expected "actual" to not be strictly equal to: ${format(actual)}${msgSuffix}\n`);
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_object_match.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_object_match.d.ts
new file mode 100644
index 0000000..277bdcb
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_object_match.d.ts
@@ -0,0 +1,13 @@
+/**
+ * Make an assertion that `actual` object is a subset of `expected` object,
+ * deeply. If not, then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertObjectMatch } from "https://deno.land/std@$STD_VERSION/assert/assert_object_match.ts";
+ *
+ * assertObjectMatch({ foo: "bar" }, { foo: "bar" }); // Doesn't throw
+ * assertObjectMatch({ foo: "bar" }, { foo: "baz" }); // Throws
+ * ```
+ */
+export declare function assertObjectMatch(actual: Record, expected: Record, msg?: string): void;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_object_match.js b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_object_match.js
new file mode 100644
index 0000000..626533d
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_object_match.js
@@ -0,0 +1,86 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+import { assertEquals } from "./assert_equals.js";
+/**
+ * Make an assertion that `actual` object is a subset of `expected` object,
+ * deeply. If not, then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertObjectMatch } from "https://deno.land/std@$STD_VERSION/assert/assert_object_match.ts";
+ *
+ * assertObjectMatch({ foo: "bar" }, { foo: "bar" }); // Doesn't throw
+ * assertObjectMatch({ foo: "bar" }, { foo: "baz" }); // Throws
+ * ```
+ */
+export function assertObjectMatch(
+// deno-lint-ignore no-explicit-any
+actual, expected, msg) {
+ function filter(a, b) {
+ const seen = new WeakMap();
+ return fn(a, b);
+ function fn(a, b) {
+ // Prevent infinite loop with circular references with same filter
+ if ((seen.has(a)) && (seen.get(a) === b)) {
+ return a;
+ }
+ try {
+ seen.set(a, b);
+ }
+ catch (err) {
+ if (err instanceof TypeError) {
+ throw new TypeError(`Cannot assertObjectMatch ${a === null ? null : `type ${typeof a}`}`);
+ }
+ else
+ throw err;
+ }
+ // Filter keys and symbols which are present in both actual and expected
+ const filtered = {};
+ const entries = [
+ ...Object.getOwnPropertyNames(a),
+ ...Object.getOwnPropertySymbols(a),
+ ]
+ .filter((key) => key in b)
+ .map((key) => [key, a[key]]);
+ for (const [key, value] of entries) {
+ // On array references, build a filtered array and filter nested objects inside
+ if (Array.isArray(value)) {
+ const subset = b[key];
+ if (Array.isArray(subset)) {
+ filtered[key] = fn({ ...value }, { ...subset });
+ continue;
+ }
+ } // On regexp references, keep value as it to avoid loosing pattern and flags
+ else if (value instanceof RegExp) {
+ filtered[key] = value;
+ continue;
+ } // On nested objects references, build a filtered object recursively
+ else if (typeof value === "object" && value !== null) {
+ const subset = b[key];
+ if ((typeof subset === "object") && subset) {
+ // When both operands are maps, build a filtered map with common keys and filter nested objects inside
+ if ((value instanceof Map) && (subset instanceof Map)) {
+ filtered[key] = new Map([...value].filter(([k]) => subset.has(k)).map(([k, v]) => [k, typeof v === "object" ? fn(v, subset.get(k)) : v]));
+ continue;
+ }
+ // When both operands are set, build a filtered set with common values
+ if ((value instanceof Set) && (subset instanceof Set)) {
+ filtered[key] = new Set([...value].filter((v) => subset.has(v)));
+ continue;
+ }
+ filtered[key] = fn(value, subset);
+ continue;
+ }
+ }
+ filtered[key] = value;
+ }
+ return filtered;
+ }
+ }
+ return assertEquals(
+ // get the intersection of "actual" and "expected"
+ // side effect: all the instances' constructor field is "Object" now.
+ filter(actual, expected),
+ // set (nested) instances' constructor field to be "Object" without changing expected value.
+ // see https://github.com/denoland/deno_std/pull/1419
+ filter(expected, expected), msg);
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_rejects.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_rejects.d.ts
new file mode 100644
index 0000000..b746389
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_rejects.d.ts
@@ -0,0 +1,26 @@
+/**
+ * Executes a function which returns a promise, expecting it to reject.
+ *
+ * @example
+ * ```ts
+ * import { assertRejects } from "https://deno.land/std@$STD_VERSION/assert/assert_rejects.ts";
+ *
+ * await assertRejects(async () => Promise.reject(new Error())); // Doesn't throw
+ * await assertRejects(async () => console.log("Hello world")); // Throws
+ * ```
+ */
+export declare function assertRejects(fn: () => PromiseLike, msg?: string): Promise;
+/**
+ * Executes a function which returns a promise, expecting it to reject.
+ * If it does not, then it throws. An error class and a string that should be
+ * included in the error message can also be asserted.
+ *
+ * @example
+ * ```ts
+ * import { assertRejects } from "https://deno.land/std@$STD_VERSION/assert/assert_rejects.ts";
+ *
+ * await assertRejects(async () => Promise.reject(new Error()), Error); // Doesn't throw
+ * await assertRejects(async () => Promise.reject(new Error()), SyntaxError); // Throws
+ * ```
+ */
+export declare function assertRejects(fn: () => PromiseLike, ErrorClass: new (...args: any[]) => E, msgIncludes?: string, msg?: string): Promise;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_rejects.js b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_rejects.js
new file mode 100644
index 0000000..8b59d9e
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_rejects.js
@@ -0,0 +1,50 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+import { AssertionError } from "./assertion_error.js";
+import { assertIsError } from "./assert_is_error.js";
+export async function assertRejects(fn, errorClassOrMsg, msgIncludesOrMsg, msg) {
+ // deno-lint-ignore no-explicit-any
+ let ErrorClass = undefined;
+ let msgIncludes = undefined;
+ let err;
+ if (typeof errorClassOrMsg !== "string") {
+ if (errorClassOrMsg === undefined ||
+ errorClassOrMsg.prototype instanceof Error ||
+ errorClassOrMsg.prototype === Error.prototype) {
+ // deno-lint-ignore no-explicit-any
+ ErrorClass = errorClassOrMsg;
+ msgIncludes = msgIncludesOrMsg;
+ }
+ }
+ else {
+ msg = errorClassOrMsg;
+ }
+ let doesThrow = false;
+ let isPromiseReturned = false;
+ const msgSuffix = msg ? `: ${msg}` : ".";
+ try {
+ const possiblePromise = fn();
+ if (possiblePromise &&
+ typeof possiblePromise === "object" &&
+ typeof possiblePromise.then === "function") {
+ isPromiseReturned = true;
+ await possiblePromise;
+ }
+ }
+ catch (error) {
+ if (!isPromiseReturned) {
+ throw new AssertionError(`Function throws when expected to reject${msgSuffix}`);
+ }
+ if (ErrorClass) {
+ if (error instanceof Error === false) {
+ throw new AssertionError(`A non-Error object was rejected${msgSuffix}`);
+ }
+ assertIsError(error, ErrorClass, msgIncludes, msg);
+ }
+ err = error;
+ doesThrow = true;
+ }
+ if (!doesThrow) {
+ throw new AssertionError(`Expected function to reject${msgSuffix}`);
+ }
+ return err;
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_strict_equals.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_strict_equals.d.ts
new file mode 100644
index 0000000..5bda868
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_strict_equals.d.ts
@@ -0,0 +1,18 @@
+/**
+ * Make an assertion that `actual` and `expected` are strictly equal. If
+ * not then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertStrictEquals } from "https://deno.land/std@$STD_VERSION/assert/assert_strict_equals.ts";
+ *
+ * const a = {};
+ * const b = a;
+ * assertStrictEquals(a, b); // Doesn't throw
+ *
+ * const c = {};
+ * const d = {};
+ * assertStrictEquals(c, d); // Throws
+ * ```
+ */
+export declare function assertStrictEquals(actual: unknown, expected: T, msg?: string): asserts actual is T;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_strict_equals.js b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_strict_equals.js
new file mode 100644
index 0000000..09f1b57
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_strict_equals.js
@@ -0,0 +1,55 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+import { format } from "./_format.js";
+import { AssertionError } from "./assertion_error.js";
+import { buildMessage, diff, diffstr } from "./_diff.js";
+import { CAN_NOT_DISPLAY } from "./_constants.js";
+import { red } from "../fmt/colors.js";
+/**
+ * Make an assertion that `actual` and `expected` are strictly equal. If
+ * not then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertStrictEquals } from "https://deno.land/std@$STD_VERSION/assert/assert_strict_equals.ts";
+ *
+ * const a = {};
+ * const b = a;
+ * assertStrictEquals(a, b); // Doesn't throw
+ *
+ * const c = {};
+ * const d = {};
+ * assertStrictEquals(c, d); // Throws
+ * ```
+ */
+export function assertStrictEquals(actual, expected, msg) {
+ if (Object.is(actual, expected)) {
+ return;
+ }
+ const msgSuffix = msg ? `: ${msg}` : ".";
+ let message;
+ const actualString = format(actual);
+ const expectedString = format(expected);
+ if (actualString === expectedString) {
+ const withOffset = actualString
+ .split("\n")
+ .map((l) => ` ${l}`)
+ .join("\n");
+ message =
+ `Values have the same structure but are not reference-equal${msgSuffix}\n\n${red(withOffset)}\n`;
+ }
+ else {
+ try {
+ const stringDiff = (typeof actual === "string") &&
+ (typeof expected === "string");
+ const diffResult = stringDiff
+ ? diffstr(actual, expected)
+ : diff(actualString.split("\n"), expectedString.split("\n"));
+ const diffMsg = buildMessage(diffResult, { stringDiff }).join("\n");
+ message = `Values are not strictly equal${msgSuffix}\n${diffMsg}`;
+ }
+ catch {
+ message = `\n${red(CAN_NOT_DISPLAY)} + \n\n`;
+ }
+ }
+ throw new AssertionError(message);
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_string_includes.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_string_includes.d.ts
new file mode 100644
index 0000000..fa80f38
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_string_includes.d.ts
@@ -0,0 +1,13 @@
+/**
+ * Make an assertion that actual includes expected. If not
+ * then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertStringIncludes } from "https://deno.land/std@$STD_VERSION/assert/assert_string_includes.ts";
+ *
+ * assertStringIncludes("Hello", "ello"); // Doesn't throw
+ * assertStringIncludes("Hello", "world"); // Throws
+ * ```
+ */
+export declare function assertStringIncludes(actual: string, expected: string, msg?: string): void;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_string_includes.js b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_string_includes.js
new file mode 100644
index 0000000..434cb58
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_string_includes.js
@@ -0,0 +1,21 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+import { AssertionError } from "./assertion_error.js";
+/**
+ * Make an assertion that actual includes expected. If not
+ * then throw.
+ *
+ * @example
+ * ```ts
+ * import { assertStringIncludes } from "https://deno.land/std@$STD_VERSION/assert/assert_string_includes.ts";
+ *
+ * assertStringIncludes("Hello", "ello"); // Doesn't throw
+ * assertStringIncludes("Hello", "world"); // Throws
+ * ```
+ */
+export function assertStringIncludes(actual, expected, msg) {
+ if (!actual.includes(expected)) {
+ const msgSuffix = msg ? `: ${msg}` : ".";
+ msg = `Expected actual: "${actual}" to contain: "${expected}"${msgSuffix}`;
+ throw new AssertionError(msg);
+ }
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_throws.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_throws.d.ts
new file mode 100644
index 0000000..aef6774
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_throws.d.ts
@@ -0,0 +1,27 @@
+/**
+ * Executes a function, expecting it to throw. If it does not, then it
+ * throws.
+ *
+ * @example
+ * ```ts
+ * import { assertThrows } from "https://deno.land/std@$STD_VERSION/assert/assert_throws.ts";
+ *
+ * assertThrows(() => { throw new TypeError("hello world!"); }); // Doesn't throw
+ * assertThrows(() => console.log("hello world!")); // Throws
+ * ```
+ */
+export declare function assertThrows(fn: () => unknown, msg?: string): unknown;
+/**
+ * Executes a function, expecting it to throw. If it does not, then it
+ * throws. An error class and a string that should be included in the
+ * error message can also be asserted.
+ *
+ * @example
+ * ```ts
+ * import { assertThrows } from "https://deno.land/std@$STD_VERSION/assert/assert_throws.ts";
+ *
+ * assertThrows(() => { throw new TypeError("hello world!"); }, TypeError); // Doesn't throw
+ * assertThrows(() => { throw new TypeError("hello world!"); }, RangeError); // Throws
+ * ```
+ */
+export declare function assertThrows(fn: () => unknown, ErrorClass: new (...args: any[]) => E, msgIncludes?: string, msg?: string): E;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assert_throws.js b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_throws.js
new file mode 100644
index 0000000..c084a8f
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assert_throws.js
@@ -0,0 +1,44 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+import { assertIsError } from "./assert_is_error.js";
+import { AssertionError } from "./assertion_error.js";
+export function assertThrows(fn, errorClassOrMsg, msgIncludesOrMsg, msg) {
+ // deno-lint-ignore no-explicit-any
+ let ErrorClass = undefined;
+ let msgIncludes = undefined;
+ let err;
+ if (typeof errorClassOrMsg !== "string") {
+ if (errorClassOrMsg === undefined ||
+ errorClassOrMsg.prototype instanceof Error ||
+ errorClassOrMsg.prototype === Error.prototype) {
+ // deno-lint-ignore no-explicit-any
+ ErrorClass = errorClassOrMsg;
+ msgIncludes = msgIncludesOrMsg;
+ }
+ else {
+ msg = msgIncludesOrMsg;
+ }
+ }
+ else {
+ msg = errorClassOrMsg;
+ }
+ let doesThrow = false;
+ const msgSuffix = msg ? `: ${msg}` : ".";
+ try {
+ fn();
+ }
+ catch (error) {
+ if (ErrorClass) {
+ if (error instanceof Error === false) {
+ throw new AssertionError(`A non-Error object was thrown${msgSuffix}`);
+ }
+ assertIsError(error, ErrorClass, msgIncludes, msg);
+ }
+ err = error;
+ doesThrow = true;
+ }
+ if (!doesThrow) {
+ msg = `Expected function to throw${msgSuffix}`;
+ throw new AssertionError(msg);
+ }
+ return err;
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assertion_error.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/assertion_error.d.ts
new file mode 100644
index 0000000..bca16bf
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assertion_error.d.ts
@@ -0,0 +1,14 @@
+/**
+ * Error thrown when an assertion fails.
+ *
+ * @example
+ * ```ts
+ * import { AssertionError } from "https://deno.land/std@$STD_VERSION/assert/assertion_error.ts";
+ *
+ * throw new AssertionError("Assertion failed");
+ * ```
+ */
+export declare class AssertionError extends Error {
+ /** Constructs a new instance. */
+ constructor(message: string);
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/assertion_error.js b/npm/esm/deps/deno.land/std@0.216.0/assert/assertion_error.js
new file mode 100644
index 0000000..f635660
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/assertion_error.js
@@ -0,0 +1,18 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+/**
+ * Error thrown when an assertion fails.
+ *
+ * @example
+ * ```ts
+ * import { AssertionError } from "https://deno.land/std@$STD_VERSION/assert/assertion_error.ts";
+ *
+ * throw new AssertionError("Assertion failed");
+ * ```
+ */
+export class AssertionError extends Error {
+ /** Constructs a new instance. */
+ constructor(message) {
+ super(message);
+ this.name = "AssertionError";
+ }
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/equal.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/equal.d.ts
new file mode 100644
index 0000000..bb0eaf3
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/equal.d.ts
@@ -0,0 +1,14 @@
+/**
+ * Deep equality comparison used in assertions
+ * @param c actual value
+ * @param d expected value
+ *
+ * @example
+ * ```ts
+ * import { equal } from "https://deno.land/std@$STD_VERSION/assert/equal.ts";
+ *
+ * equal({ foo: "bar" }, { foo: "bar" }); // Returns `true`
+ * equal({ foo: "bar" }, { foo: "baz" }); // Returns `false
+ * ```
+ */
+export declare function equal(c: unknown, d: unknown): boolean;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/equal.js b/npm/esm/deps/deno.land/std@0.216.0/assert/equal.js
new file mode 100644
index 0000000..14c8a04
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/equal.js
@@ -0,0 +1,110 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+function isKeyedCollection(x) {
+ return [Symbol.iterator, "size"].every((k) => k in x);
+}
+function constructorsEqual(a, b) {
+ return a.constructor === b.constructor ||
+ a.constructor === Object && !b.constructor ||
+ !a.constructor && b.constructor === Object;
+}
+/**
+ * Deep equality comparison used in assertions
+ * @param c actual value
+ * @param d expected value
+ *
+ * @example
+ * ```ts
+ * import { equal } from "https://deno.land/std@$STD_VERSION/assert/equal.ts";
+ *
+ * equal({ foo: "bar" }, { foo: "bar" }); // Returns `true`
+ * equal({ foo: "bar" }, { foo: "baz" }); // Returns `false
+ * ```
+ */
+export function equal(c, d) {
+ const seen = new Map();
+ return (function compare(a, b) {
+ // Have to render RegExp & Date for string comparison
+ // unless it's mistreated as object
+ if (a &&
+ b &&
+ ((a instanceof RegExp && b instanceof RegExp) ||
+ (a instanceof URL && b instanceof URL))) {
+ return String(a) === String(b);
+ }
+ if (a instanceof Date && b instanceof Date) {
+ const aTime = a.getTime();
+ const bTime = b.getTime();
+ // Check for NaN equality manually since NaN is not
+ // equal to itself.
+ if (Number.isNaN(aTime) && Number.isNaN(bTime)) {
+ return true;
+ }
+ return aTime === bTime;
+ }
+ if (typeof a === "number" && typeof b === "number") {
+ return Number.isNaN(a) && Number.isNaN(b) || a === b;
+ }
+ if (Object.is(a, b)) {
+ return true;
+ }
+ if (a && typeof a === "object" && b && typeof b === "object") {
+ if (a && b && !constructorsEqual(a, b)) {
+ return false;
+ }
+ if (a instanceof WeakMap || b instanceof WeakMap) {
+ if (!(a instanceof WeakMap && b instanceof WeakMap))
+ return false;
+ throw new TypeError("cannot compare WeakMap instances");
+ }
+ if (a instanceof WeakSet || b instanceof WeakSet) {
+ if (!(a instanceof WeakSet && b instanceof WeakSet))
+ return false;
+ throw new TypeError("cannot compare WeakSet instances");
+ }
+ if (seen.get(a) === b) {
+ return true;
+ }
+ if (Object.keys(a || {}).length !== Object.keys(b || {}).length) {
+ return false;
+ }
+ seen.set(a, b);
+ if (isKeyedCollection(a) && isKeyedCollection(b)) {
+ if (a.size !== b.size) {
+ return false;
+ }
+ let unmatchedEntries = a.size;
+ for (const [aKey, aValue] of a.entries()) {
+ for (const [bKey, bValue] of b.entries()) {
+ /* Given that Map keys can be references, we need
+ * to ensure that they are also deeply equal */
+ if ((aKey === aValue && bKey === bValue && compare(aKey, bKey)) ||
+ (compare(aKey, bKey) && compare(aValue, bValue))) {
+ unmatchedEntries--;
+ break;
+ }
+ }
+ }
+ return unmatchedEntries === 0;
+ }
+ const merged = { ...a, ...b };
+ for (const key of [
+ ...Object.getOwnPropertyNames(merged),
+ ...Object.getOwnPropertySymbols(merged),
+ ]) {
+ if (!compare(a && a[key], b && b[key])) {
+ return false;
+ }
+ if (((key in a) && (!(key in b))) || ((key in b) && (!(key in a)))) {
+ return false;
+ }
+ }
+ if (a instanceof WeakRef || b instanceof WeakRef) {
+ if (!(a instanceof WeakRef && b instanceof WeakRef))
+ return false;
+ return compare(a.deref(), b.deref());
+ }
+ return true;
+ }
+ return false;
+ })(c, d);
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/fail.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/fail.d.ts
new file mode 100644
index 0000000..9e67653
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/fail.d.ts
@@ -0,0 +1,11 @@
+/**
+ * Forcefully throws a failed assertion.
+ *
+ * @example
+ * ```ts
+ * import { fail } from "https://deno.land/std@$STD_VERSION/assert/fail.ts";
+ *
+ * fail("Deliberately failed!"); // Throws
+ * ```
+ */
+export declare function fail(msg?: string): never;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/fail.js b/npm/esm/deps/deno.land/std@0.216.0/assert/fail.js
new file mode 100644
index 0000000..ee9d99b
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/fail.js
@@ -0,0 +1,16 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+import { assert } from "./assert.js";
+/**
+ * Forcefully throws a failed assertion.
+ *
+ * @example
+ * ```ts
+ * import { fail } from "https://deno.land/std@$STD_VERSION/assert/fail.ts";
+ *
+ * fail("Deliberately failed!"); // Throws
+ * ```
+ */
+export function fail(msg) {
+ const msgSuffix = msg ? `: ${msg}` : ".";
+ assert(false, `Failed assertion${msgSuffix}`);
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/mod.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/mod.d.ts
new file mode 100644
index 0000000..d35a266
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/mod.d.ts
@@ -0,0 +1,36 @@
+/** A library of assertion functions.
+ * If the assertion is false an `AssertionError` will be thrown which will
+ * result in pretty-printed diff of failing assertion.
+ *
+ * This module is browser compatible, but do not rely on good formatting of
+ * values for AssertionError messages in browsers.
+ *
+ * @module
+ */
+export * from "./assert_almost_equals.js";
+export * from "./assert_array_includes.js";
+export * from "./assert_equals.js";
+export * from "./assert_exists.js";
+export * from "./assert_false.js";
+export * from "./assert_greater_or_equal.js";
+export * from "./assert_greater.js";
+export * from "./assert_instance_of.js";
+export * from "./assert_is_error.js";
+export * from "./assert_less_or_equal.js";
+export * from "./assert_less.js";
+export * from "./assert_match.js";
+export * from "./assert_not_equals.js";
+export * from "./assert_not_instance_of.js";
+export * from "./assert_not_match.js";
+export * from "./assert_not_strict_equals.js";
+export * from "./assert_object_match.js";
+export * from "./assert_rejects.js";
+export * from "./assert_strict_equals.js";
+export * from "./assert_string_includes.js";
+export * from "./assert_throws.js";
+export * from "./assert.js";
+export * from "./assertion_error.js";
+export * from "./equal.js";
+export * from "./fail.js";
+export * from "./unimplemented.js";
+export * from "./unreachable.js";
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/mod.js b/npm/esm/deps/deno.land/std@0.216.0/assert/mod.js
new file mode 100644
index 0000000..e2f7b93
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/mod.js
@@ -0,0 +1,37 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+/** A library of assertion functions.
+ * If the assertion is false an `AssertionError` will be thrown which will
+ * result in pretty-printed diff of failing assertion.
+ *
+ * This module is browser compatible, but do not rely on good formatting of
+ * values for AssertionError messages in browsers.
+ *
+ * @module
+ */
+export * from "./assert_almost_equals.js";
+export * from "./assert_array_includes.js";
+export * from "./assert_equals.js";
+export * from "./assert_exists.js";
+export * from "./assert_false.js";
+export * from "./assert_greater_or_equal.js";
+export * from "./assert_greater.js";
+export * from "./assert_instance_of.js";
+export * from "./assert_is_error.js";
+export * from "./assert_less_or_equal.js";
+export * from "./assert_less.js";
+export * from "./assert_match.js";
+export * from "./assert_not_equals.js";
+export * from "./assert_not_instance_of.js";
+export * from "./assert_not_match.js";
+export * from "./assert_not_strict_equals.js";
+export * from "./assert_object_match.js";
+export * from "./assert_rejects.js";
+export * from "./assert_strict_equals.js";
+export * from "./assert_string_includes.js";
+export * from "./assert_throws.js";
+export * from "./assert.js";
+export * from "./assertion_error.js";
+export * from "./equal.js";
+export * from "./fail.js";
+export * from "./unimplemented.js";
+export * from "./unreachable.js";
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/unimplemented.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/unimplemented.d.ts
new file mode 100644
index 0000000..6aa08c6
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/unimplemented.d.ts
@@ -0,0 +1,11 @@
+/**
+ * Use this to stub out methods that will throw when invoked.
+ *
+ * @example
+ * ```ts
+ * import { unimplemented } from "https://deno.land/std@$STD_VERSION/assert/unimplemented.ts";
+ *
+ * unimplemented(); // Throws
+ * ```
+ */
+export declare function unimplemented(msg?: string): never;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/unimplemented.js b/npm/esm/deps/deno.land/std@0.216.0/assert/unimplemented.js
new file mode 100644
index 0000000..799e739
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/unimplemented.js
@@ -0,0 +1,16 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+import { AssertionError } from "./assertion_error.js";
+/**
+ * Use this to stub out methods that will throw when invoked.
+ *
+ * @example
+ * ```ts
+ * import { unimplemented } from "https://deno.land/std@$STD_VERSION/assert/unimplemented.ts";
+ *
+ * unimplemented(); // Throws
+ * ```
+ */
+export function unimplemented(msg) {
+ const msgSuffix = msg ? `: ${msg}` : ".";
+ throw new AssertionError(`Unimplemented${msgSuffix}`);
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/unreachable.d.ts b/npm/esm/deps/deno.land/std@0.216.0/assert/unreachable.d.ts
new file mode 100644
index 0000000..ce4bbf2
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/unreachable.d.ts
@@ -0,0 +1,11 @@
+/**
+ * Use this to assert unreachable code.
+ *
+ * @example
+ * ```ts
+ * import { unreachable } from "https://deno.land/std@$STD_VERSION/assert/unreachable.ts";
+ *
+ * unreachable(); // Throws
+ * ```
+ */
+export declare function unreachable(): never;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/assert/unreachable.js b/npm/esm/deps/deno.land/std@0.216.0/assert/unreachable.js
new file mode 100644
index 0000000..3144c4d
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/assert/unreachable.js
@@ -0,0 +1,15 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+import { AssertionError } from "./assertion_error.js";
+/**
+ * Use this to assert unreachable code.
+ *
+ * @example
+ * ```ts
+ * import { unreachable } from "https://deno.land/std@$STD_VERSION/assert/unreachable.ts";
+ *
+ * unreachable(); // Throws
+ * ```
+ */
+export function unreachable() {
+ throw new AssertionError("unreachable");
+}
diff --git a/npm/esm/deps/deno.land/std@0.216.0/fmt/colors.d.ts b/npm/esm/deps/deno.land/std@0.216.0/fmt/colors.d.ts
new file mode 100644
index 0000000..a9e5fd6
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/fmt/colors.d.ts
@@ -0,0 +1,285 @@
+/** RGB 8-bits per channel. Each in range `0->255` or `0x00->0xff` */
+export interface Rgb {
+ /** Red component value */
+ r: number;
+ /** Green component value */
+ g: number;
+ /** Blue component value */
+ b: number;
+}
+/**
+ * Set changing text color to enabled or disabled
+ * @param value
+ */
+export declare function setColorEnabled(value: boolean): void;
+/** Get whether text color change is enabled or disabled. */
+export declare function getColorEnabled(): boolean;
+/**
+ * Reset the text modified.
+ * @param str text to reset
+ */
+export declare function reset(str: string): string;
+/**
+ * Make the text bold.
+ * @param str text to make bold
+ */
+export declare function bold(str: string): string;
+/**
+ * The text emits only a small amount of light.
+ * @param str text to dim
+ *
+ * Warning: Not all terminal emulators support `dim`.
+ * For compatibility across all terminals, use {@linkcode gray} or {@linkcode brightBlack} instead.
+ */
+export declare function dim(str: string): string;
+/**
+ * Make the text italic.
+ * @param str text to make italic
+ */
+export declare function italic(str: string): string;
+/**
+ * Make the text underline.
+ * @param str text to underline
+ */
+export declare function underline(str: string): string;
+/**
+ * Invert background color and text color.
+ * @param str text to invert its color
+ */
+export declare function inverse(str: string): string;
+/**
+ * Make the text hidden.
+ * @param str text to hide
+ */
+export declare function hidden(str: string): string;
+/**
+ * Put horizontal line through the center of the text.
+ * @param str text to strike through
+ */
+export declare function strikethrough(str: string): string;
+/**
+ * Set text color to black.
+ * @param str text to make black
+ */
+export declare function black(str: string): string;
+/**
+ * Set text color to red.
+ * @param str text to make red
+ */
+export declare function red(str: string): string;
+/**
+ * Set text color to green.
+ * @param str text to make green
+ */
+export declare function green(str: string): string;
+/**
+ * Set text color to yellow.
+ * @param str text to make yellow
+ */
+export declare function yellow(str: string): string;
+/**
+ * Set text color to blue.
+ * @param str text to make blue
+ */
+export declare function blue(str: string): string;
+/**
+ * Set text color to magenta.
+ * @param str text to make magenta
+ */
+export declare function magenta(str: string): string;
+/**
+ * Set text color to cyan.
+ * @param str text to make cyan
+ */
+export declare function cyan(str: string): string;
+/**
+ * Set text color to white.
+ * @param str text to make white
+ */
+export declare function white(str: string): string;
+/**
+ * Set text color to gray.
+ * @param str text to make gray
+ */
+export declare function gray(str: string): string;
+/**
+ * Set text color to bright black.
+ * @param str text to make bright-black
+ */
+export declare function brightBlack(str: string): string;
+/**
+ * Set text color to bright red.
+ * @param str text to make bright-red
+ */
+export declare function brightRed(str: string): string;
+/**
+ * Set text color to bright green.
+ * @param str text to make bright-green
+ */
+export declare function brightGreen(str: string): string;
+/**
+ * Set text color to bright yellow.
+ * @param str text to make bright-yellow
+ */
+export declare function brightYellow(str: string): string;
+/**
+ * Set text color to bright blue.
+ * @param str text to make bright-blue
+ */
+export declare function brightBlue(str: string): string;
+/**
+ * Set text color to bright magenta.
+ * @param str text to make bright-magenta
+ */
+export declare function brightMagenta(str: string): string;
+/**
+ * Set text color to bright cyan.
+ * @param str text to make bright-cyan
+ */
+export declare function brightCyan(str: string): string;
+/**
+ * Set text color to bright white.
+ * @param str text to make bright-white
+ */
+export declare function brightWhite(str: string): string;
+/**
+ * Set background color to black.
+ * @param str text to make its background black
+ */
+export declare function bgBlack(str: string): string;
+/**
+ * Set background color to red.
+ * @param str text to make its background red
+ */
+export declare function bgRed(str: string): string;
+/**
+ * Set background color to green.
+ * @param str text to make its background green
+ */
+export declare function bgGreen(str: string): string;
+/**
+ * Set background color to yellow.
+ * @param str text to make its background yellow
+ */
+export declare function bgYellow(str: string): string;
+/**
+ * Set background color to blue.
+ * @param str text to make its background blue
+ */
+export declare function bgBlue(str: string): string;
+/**
+ * Set background color to magenta.
+ * @param str text to make its background magenta
+ */
+export declare function bgMagenta(str: string): string;
+/**
+ * Set background color to cyan.
+ * @param str text to make its background cyan
+ */
+export declare function bgCyan(str: string): string;
+/**
+ * Set background color to white.
+ * @param str text to make its background white
+ */
+export declare function bgWhite(str: string): string;
+/**
+ * Set background color to bright black.
+ * @param str text to make its background bright-black
+ */
+export declare function bgBrightBlack(str: string): string;
+/**
+ * Set background color to bright red.
+ * @param str text to make its background bright-red
+ */
+export declare function bgBrightRed(str: string): string;
+/**
+ * Set background color to bright green.
+ * @param str text to make its background bright-green
+ */
+export declare function bgBrightGreen(str: string): string;
+/**
+ * Set background color to bright yellow.
+ * @param str text to make its background bright-yellow
+ */
+export declare function bgBrightYellow(str: string): string;
+/**
+ * Set background color to bright blue.
+ * @param str text to make its background bright-blue
+ */
+export declare function bgBrightBlue(str: string): string;
+/**
+ * Set background color to bright magenta.
+ * @param str text to make its background bright-magenta
+ */
+export declare function bgBrightMagenta(str: string): string;
+/**
+ * Set background color to bright cyan.
+ * @param str text to make its background bright-cyan
+ */
+export declare function bgBrightCyan(str: string): string;
+/**
+ * Set background color to bright white.
+ * @param str text to make its background bright-white
+ */
+export declare function bgBrightWhite(str: string): string;
+/**
+ * Set text color using paletted 8bit colors.
+ * https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit
+ * @param str text color to apply paletted 8bit colors to
+ * @param color code
+ */
+export declare function rgb8(str: string, color: number): string;
+/**
+ * Set background color using paletted 8bit colors.
+ * https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit
+ * @param str text color to apply paletted 8bit background colors to
+ * @param color code
+ */
+export declare function bgRgb8(str: string, color: number): string;
+/**
+ * Set text color using 24bit rgb.
+ * `color` can be a number in range `0x000000` to `0xffffff` or
+ * an `Rgb`.
+ *
+ * To produce the color magenta:
+ *
+ * ```ts
+ * import { rgb24 } from "https://deno.land/std@$STD_VERSION/fmt/colors.ts";
+ *
+ * rgb24("foo", 0xff00ff);
+ * rgb24("foo", {r: 255, g: 0, b: 255});
+ * ```
+ * @param str text color to apply 24bit rgb to
+ * @param color code
+ */
+export declare function rgb24(str: string, color: number | Rgb): string;
+/**
+ * Set background color using 24bit rgb.
+ * `color` can be a number in range `0x000000` to `0xffffff` or
+ * an `Rgb`.
+ *
+ * To produce the color magenta:
+ *
+ * ```ts
+ * import { bgRgb24 } from "https://deno.land/std@$STD_VERSION/fmt/colors.ts";
+ *
+ * bgRgb24("foo", 0xff00ff);
+ * bgRgb24("foo", {r: 255, g: 0, b: 255});
+ * ```
+ * @param str text color to apply 24bit rgb to
+ * @param color code
+ */
+export declare function bgRgb24(str: string, color: number | Rgb): string;
+/**
+ * Remove ANSI escape codes from the string.
+ * @param string to remove ANSI escape codes from
+ *
+ * @deprecated (will be removed in 1.0.0) Use {@linkcode stripAnsiCode} instead.
+ */
+export declare function stripColor(string: string): string;
+/**
+ * Remove ANSI escape codes from the string.
+ *
+ * @param string to remove ANSI escape codes from
+ */
+export declare function stripAnsiCode(string: string): string;
diff --git a/npm/esm/deps/deno.land/std@0.216.0/fmt/colors.js b/npm/esm/deps/deno.land/std@0.216.0/fmt/colors.js
new file mode 100644
index 0000000..c2cace5
--- /dev/null
+++ b/npm/esm/deps/deno.land/std@0.216.0/fmt/colors.js
@@ -0,0 +1,489 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+// This module is browser compatible.
+// A module to print ANSI terminal colors. Inspired by chalk, kleur, and colors
+// on npm.
+/**
+ * String formatters and utilities for dealing with ANSI color codes.
+ *
+ * This module is browser compatible.
+ *
+ * This module supports `NO_COLOR` environmental variable disabling any coloring
+ * if `NO_COLOR` is set.
+ *
+ * @example
+ * ```ts
+ * import {
+ * bgBlue,
+ * bgRgb24,
+ * bgRgb8,
+ * bold,
+ * italic,
+ * red,
+ * rgb24,
+ * rgb8,
+ * } from "https://deno.land/std@$STD_VERSION/fmt/colors.ts";
+ *
+ * console.log(bgBlue(italic(red(bold("Hello, World!")))));
+ *
+ * // also supports 8bit colors
+ *
+ * console.log(rgb8("Hello, World!", 42));
+ *
+ * console.log(bgRgb8("Hello, World!", 42));
+ *
+ * // and 24bit rgb
+ *
+ * console.log(rgb24("Hello, World!", {
+ * r: 41,
+ * g: 42,
+ * b: 43,
+ * }));
+ *
+ * console.log(bgRgb24("Hello, World!", {
+ * r: 41,
+ * g: 42,
+ * b: 43,
+ * }));
+ * ```
+ *
+ * @module
+ */
+// deno-lint-ignore no-explicit-any
+import * as dntShim from "../../../../_dnt.test_shims.js";
+const { Deno } = dntShim.dntGlobalThis;
+const noColor = typeof Deno?.noColor === "boolean"
+ ? Deno.noColor
+ : false;
+let enabled = !noColor;
+/**
+ * Set changing text color to enabled or disabled
+ * @param value
+ */
+export function setColorEnabled(value) {
+ if (Deno?.noColor) {
+ return;
+ }
+ enabled = value;
+}
+/** Get whether text color change is enabled or disabled. */
+export function getColorEnabled() {
+ return enabled;
+}
+/**
+ * Builds color code
+ * @param open
+ * @param close
+ */
+function code(open, close) {
+ return {
+ open: `\x1b[${open.join(";")}m`,
+ close: `\x1b[${close}m`,
+ regexp: new RegExp(`\\x1b\\[${close}m`, "g"),
+ };
+}
+/**
+ * Applies color and background based on color code and its associated text
+ * @param str text to apply color settings to
+ * @param code color code to apply
+ */
+function run(str, code) {
+ return enabled
+ ? `${code.open}${str.replace(code.regexp, code.open)}${code.close}`
+ : str;
+}
+/**
+ * Reset the text modified.
+ * @param str text to reset
+ */
+export function reset(str) {
+ return run(str, code([0], 0));
+}
+/**
+ * Make the text bold.
+ * @param str text to make bold
+ */
+export function bold(str) {
+ return run(str, code([1], 22));
+}
+/**
+ * The text emits only a small amount of light.
+ * @param str text to dim
+ *
+ * Warning: Not all terminal emulators support `dim`.
+ * For compatibility across all terminals, use {@linkcode gray} or {@linkcode brightBlack} instead.
+ */
+export function dim(str) {
+ return run(str, code([2], 22));
+}
+/**
+ * Make the text italic.
+ * @param str text to make italic
+ */
+export function italic(str) {
+ return run(str, code([3], 23));
+}
+/**
+ * Make the text underline.
+ * @param str text to underline
+ */
+export function underline(str) {
+ return run(str, code([4], 24));
+}
+/**
+ * Invert background color and text color.
+ * @param str text to invert its color
+ */
+export function inverse(str) {
+ return run(str, code([7], 27));
+}
+/**
+ * Make the text hidden.
+ * @param str text to hide
+ */
+export function hidden(str) {
+ return run(str, code([8], 28));
+}
+/**
+ * Put horizontal line through the center of the text.
+ * @param str text to strike through
+ */
+export function strikethrough(str) {
+ return run(str, code([9], 29));
+}
+/**
+ * Set text color to black.
+ * @param str text to make black
+ */
+export function black(str) {
+ return run(str, code([30], 39));
+}
+/**
+ * Set text color to red.
+ * @param str text to make red
+ */
+export function red(str) {
+ return run(str, code([31], 39));
+}
+/**
+ * Set text color to green.
+ * @param str text to make green
+ */
+export function green(str) {
+ return run(str, code([32], 39));
+}
+/**
+ * Set text color to yellow.
+ * @param str text to make yellow
+ */
+export function yellow(str) {
+ return run(str, code([33], 39));
+}
+/**
+ * Set text color to blue.
+ * @param str text to make blue
+ */
+export function blue(str) {
+ return run(str, code([34], 39));
+}
+/**
+ * Set text color to magenta.
+ * @param str text to make magenta
+ */
+export function magenta(str) {
+ return run(str, code([35], 39));
+}
+/**
+ * Set text color to cyan.
+ * @param str text to make cyan
+ */
+export function cyan(str) {
+ return run(str, code([36], 39));
+}
+/**
+ * Set text color to white.
+ * @param str text to make white
+ */
+export function white(str) {
+ return run(str, code([37], 39));
+}
+/**
+ * Set text color to gray.
+ * @param str text to make gray
+ */
+export function gray(str) {
+ return brightBlack(str);
+}
+/**
+ * Set text color to bright black.
+ * @param str text to make bright-black
+ */
+export function brightBlack(str) {
+ return run(str, code([90], 39));
+}
+/**
+ * Set text color to bright red.
+ * @param str text to make bright-red
+ */
+export function brightRed(str) {
+ return run(str, code([91], 39));
+}
+/**
+ * Set text color to bright green.
+ * @param str text to make bright-green
+ */
+export function brightGreen(str) {
+ return run(str, code([92], 39));
+}
+/**
+ * Set text color to bright yellow.
+ * @param str text to make bright-yellow
+ */
+export function brightYellow(str) {
+ return run(str, code([93], 39));
+}
+/**
+ * Set text color to bright blue.
+ * @param str text to make bright-blue
+ */
+export function brightBlue(str) {
+ return run(str, code([94], 39));
+}
+/**
+ * Set text color to bright magenta.
+ * @param str text to make bright-magenta
+ */
+export function brightMagenta(str) {
+ return run(str, code([95], 39));
+}
+/**
+ * Set text color to bright cyan.
+ * @param str text to make bright-cyan
+ */
+export function brightCyan(str) {
+ return run(str, code([96], 39));
+}
+/**
+ * Set text color to bright white.
+ * @param str text to make bright-white
+ */
+export function brightWhite(str) {
+ return run(str, code([97], 39));
+}
+/**
+ * Set background color to black.
+ * @param str text to make its background black
+ */
+export function bgBlack(str) {
+ return run(str, code([40], 49));
+}
+/**
+ * Set background color to red.
+ * @param str text to make its background red
+ */
+export function bgRed(str) {
+ return run(str, code([41], 49));
+}
+/**
+ * Set background color to green.
+ * @param str text to make its background green
+ */
+export function bgGreen(str) {
+ return run(str, code([42], 49));
+}
+/**
+ * Set background color to yellow.
+ * @param str text to make its background yellow
+ */
+export function bgYellow(str) {
+ return run(str, code([43], 49));
+}
+/**
+ * Set background color to blue.
+ * @param str text to make its background blue
+ */
+export function bgBlue(str) {
+ return run(str, code([44], 49));
+}
+/**
+ * Set background color to magenta.
+ * @param str text to make its background magenta
+ */
+export function bgMagenta(str) {
+ return run(str, code([45], 49));
+}
+/**
+ * Set background color to cyan.
+ * @param str text to make its background cyan
+ */
+export function bgCyan(str) {
+ return run(str, code([46], 49));
+}
+/**
+ * Set background color to white.
+ * @param str text to make its background white
+ */
+export function bgWhite(str) {
+ return run(str, code([47], 49));
+}
+/**
+ * Set background color to bright black.
+ * @param str text to make its background bright-black
+ */
+export function bgBrightBlack(str) {
+ return run(str, code([100], 49));
+}
+/**
+ * Set background color to bright red.
+ * @param str text to make its background bright-red
+ */
+export function bgBrightRed(str) {
+ return run(str, code([101], 49));
+}
+/**
+ * Set background color to bright green.
+ * @param str text to make its background bright-green
+ */
+export function bgBrightGreen(str) {
+ return run(str, code([102], 49));
+}
+/**
+ * Set background color to bright yellow.
+ * @param str text to make its background bright-yellow
+ */
+export function bgBrightYellow(str) {
+ return run(str, code([103], 49));
+}
+/**
+ * Set background color to bright blue.
+ * @param str text to make its background bright-blue
+ */
+export function bgBrightBlue(str) {
+ return run(str, code([104], 49));
+}
+/**
+ * Set background color to bright magenta.
+ * @param str text to make its background bright-magenta
+ */
+export function bgBrightMagenta(str) {
+ return run(str, code([105], 49));
+}
+/**
+ * Set background color to bright cyan.
+ * @param str text to make its background bright-cyan
+ */
+export function bgBrightCyan(str) {
+ return run(str, code([106], 49));
+}
+/**
+ * Set background color to bright white.
+ * @param str text to make its background bright-white
+ */
+export function bgBrightWhite(str) {
+ return run(str, code([107], 49));
+}
+/* Special Color Sequences */
+/**
+ * Clam and truncate color codes
+ * @param n
+ * @param max number to truncate to
+ * @param min number to truncate from
+ */
+function clampAndTruncate(n, max = 255, min = 0) {
+ return Math.trunc(Math.max(Math.min(n, max), min));
+}
+/**
+ * Set text color using paletted 8bit colors.
+ * https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit
+ * @param str text color to apply paletted 8bit colors to
+ * @param color code
+ */
+export function rgb8(str, color) {
+ return run(str, code([38, 5, clampAndTruncate(color)], 39));
+}
+/**
+ * Set background color using paletted 8bit colors.
+ * https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit
+ * @param str text color to apply paletted 8bit background colors to
+ * @param color code
+ */
+export function bgRgb8(str, color) {
+ return run(str, code([48, 5, clampAndTruncate(color)], 49));
+}
+/**
+ * Set text color using 24bit rgb.
+ * `color` can be a number in range `0x000000` to `0xffffff` or
+ * an `Rgb`.
+ *
+ * To produce the color magenta:
+ *
+ * ```ts
+ * import { rgb24 } from "https://deno.land/std@$STD_VERSION/fmt/colors.ts";
+ *
+ * rgb24("foo", 0xff00ff);
+ * rgb24("foo", {r: 255, g: 0, b: 255});
+ * ```
+ * @param str text color to apply 24bit rgb to
+ * @param color code
+ */
+export function rgb24(str, color) {
+ if (typeof color === "number") {
+ return run(str, code([38, 2, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff], 39));
+ }
+ return run(str, code([
+ 38,
+ 2,
+ clampAndTruncate(color.r),
+ clampAndTruncate(color.g),
+ clampAndTruncate(color.b),
+ ], 39));
+}
+/**
+ * Set background color using 24bit rgb.
+ * `color` can be a number in range `0x000000` to `0xffffff` or
+ * an `Rgb`.
+ *
+ * To produce the color magenta:
+ *
+ * ```ts
+ * import { bgRgb24 } from "https://deno.land/std@$STD_VERSION/fmt/colors.ts";
+ *
+ * bgRgb24("foo", 0xff00ff);
+ * bgRgb24("foo", {r: 255, g: 0, b: 255});
+ * ```
+ * @param str text color to apply 24bit rgb to
+ * @param color code
+ */
+export function bgRgb24(str, color) {
+ if (typeof color === "number") {
+ return run(str, code([48, 2, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff], 49));
+ }
+ return run(str, code([
+ 48,
+ 2,
+ clampAndTruncate(color.r),
+ clampAndTruncate(color.g),
+ clampAndTruncate(color.b),
+ ], 49));
+}
+// https://github.com/chalk/ansi-regex/blob/02fa893d619d3da85411acc8fd4e2eea0e95a9d9/index.js
+const ANSI_PATTERN = new RegExp([
+ "[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)",
+ "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TXZcf-nq-uy=><~]))",
+].join("|"), "g");
+/**
+ * Remove ANSI escape codes from the string.
+ * @param string to remove ANSI escape codes from
+ *
+ * @deprecated (will be removed in 1.0.0) Use {@linkcode stripAnsiCode} instead.
+ */
+export function stripColor(string) {
+ return stripAnsiCode(string);
+}
+/**
+ * Remove ANSI escape codes from the string.
+ *
+ * @param string to remove ANSI escape codes from
+ */
+export function stripAnsiCode(string) {
+ return string.replace(ANSI_PATTERN, "");
+}
diff --git a/npm/esm/mod.d.ts b/npm/esm/mod.d.ts
new file mode 100644
index 0000000..7434bbb
--- /dev/null
+++ b/npm/esm/mod.d.ts
@@ -0,0 +1,4 @@
+export { MlKemError } from "./src/errors.js";
+export { MlKem512 } from "./src/kyber512.js";
+export { MlKem768 } from "./src/kyber768.js";
+export { MlKem1024 } from "./src/kyber1024.js";
diff --git a/npm/esm/mod.js b/npm/esm/mod.js
new file mode 100644
index 0000000..7434bbb
--- /dev/null
+++ b/npm/esm/mod.js
@@ -0,0 +1,4 @@
+export { MlKemError } from "./src/errors.js";
+export { MlKem512 } from "./src/kyber512.js";
+export { MlKem768 } from "./src/kyber768.js";
+export { MlKem1024 } from "./src/kyber1024.js";
diff --git a/npm/esm/package.json b/npm/esm/package.json
new file mode 100644
index 0000000..3dbc1ca
--- /dev/null
+++ b/npm/esm/package.json
@@ -0,0 +1,3 @@
+{
+ "type": "module"
+}
diff --git a/npm/esm/src/consts.d.ts b/npm/esm/src/consts.d.ts
new file mode 100644
index 0000000..05dbd2a
--- /dev/null
+++ b/npm/esm/src/consts.d.ts
@@ -0,0 +1,10 @@
+/**
+ * This implementation is based on https://github.com/antontutoveanu/crystals-kyber-javascript,
+ * which was deveploped under the MIT licence below:
+ * https://github.com/antontutoveanu/crystals-kyber-javascript/blob/main/LICENSE
+ */
+export declare const N = 256;
+export declare const Q = 3329;
+export declare const Q_INV = 62209;
+export declare const NTT_ZETAS: number[];
+export declare const NTT_ZETAS_INV: number[];
diff --git a/npm/esm/src/consts.js b/npm/esm/src/consts.js
new file mode 100644
index 0000000..d7a076e
--- /dev/null
+++ b/npm/esm/src/consts.js
@@ -0,0 +1,34 @@
+/**
+ * This implementation is based on https://github.com/antontutoveanu/crystals-kyber-javascript,
+ * which was deveploped under the MIT licence below:
+ * https://github.com/antontutoveanu/crystals-kyber-javascript/blob/main/LICENSE
+ */
+export const N = 256;
+export const Q = 3329;
+export const Q_INV = 62209;
+// deno-fmt-ignore
+export const NTT_ZETAS = [
+ 2285, 2571, 2970, 1812, 1493, 1422, 287, 202, 3158, 622, 1577, 182, 962,
+ 2127, 1855, 1468, 573, 2004, 264, 383, 2500, 1458, 1727, 3199, 2648, 1017,
+ 732, 608, 1787, 411, 3124, 1758, 1223, 652, 2777, 1015, 2036, 1491, 3047,
+ 1785, 516, 3321, 3009, 2663, 1711, 2167, 126, 1469, 2476, 3239, 3058, 830,
+ 107, 1908, 3082, 2378, 2931, 961, 1821, 2604, 448, 2264, 677, 2054, 2226,
+ 430, 555, 843, 2078, 871, 1550, 105, 422, 587, 177, 3094, 3038, 2869, 1574,
+ 1653, 3083, 778, 1159, 3182, 2552, 1483, 2727, 1119, 1739, 644, 2457, 349,
+ 418, 329, 3173, 3254, 817, 1097, 603, 610, 1322, 2044, 1864, 384, 2114, 3193,
+ 1218, 1994, 2455, 220, 2142, 1670, 2144, 1799, 2051, 794, 1819, 2475, 2459,
+ 478, 3221, 3021, 996, 991, 958, 1869, 1522, 1628,
+];
+// deno-fmt-ignore
+export const NTT_ZETAS_INV = [
+ 1701, 1807, 1460, 2371, 2338, 2333, 308, 108, 2851, 870, 854, 1510, 2535,
+ 1278, 1530, 1185, 1659, 1187, 3109, 874, 1335, 2111, 136, 1215, 2945, 1465,
+ 1285, 2007, 2719, 2726, 2232, 2512, 75, 156, 3000, 2911, 2980, 872, 2685,
+ 1590, 2210, 602, 1846, 777, 147, 2170, 2551, 246, 1676, 1755, 460, 291, 235,
+ 3152, 2742, 2907, 3224, 1779, 2458, 1251, 2486, 2774, 2899, 1103, 1275, 2652,
+ 1065, 2881, 725, 1508, 2368, 398, 951, 247, 1421, 3222, 2499, 271, 90, 853,
+ 1860, 3203, 1162, 1618, 666, 320, 8, 2813, 1544, 282, 1838, 1293, 2314, 552,
+ 2677, 2106, 1571, 205, 2918, 1542, 2721, 2597, 2312, 681, 130, 1602, 1871,
+ 829, 2946, 3065, 1325, 2756, 1861, 1474, 1202, 2367, 3147, 1752, 2707, 171,
+ 3127, 3042, 1907, 1836, 1517, 359, 758, 1441,
+];
diff --git a/npm/esm/src/deps.d.ts b/npm/esm/src/deps.d.ts
new file mode 100644
index 0000000..caf7f77
--- /dev/null
+++ b/npm/esm/src/deps.d.ts
@@ -0,0 +1 @@
+export { sha3_256, sha3_512, shake128, shake256, } from "@openpgp/noble-hashes/sha3";
diff --git a/npm/esm/src/deps.js b/npm/esm/src/deps.js
new file mode 100644
index 0000000..caf7f77
--- /dev/null
+++ b/npm/esm/src/deps.js
@@ -0,0 +1 @@
+export { sha3_256, sha3_512, shake128, shake256, } from "@openpgp/noble-hashes/sha3";
diff --git a/npm/esm/src/errors.d.ts b/npm/esm/src/errors.d.ts
new file mode 100644
index 0000000..c0e1484
--- /dev/null
+++ b/npm/esm/src/errors.d.ts
@@ -0,0 +1,6 @@
+/**
+ * The base error class of kyber-ts.
+ */
+export declare class MlKemError extends Error {
+ constructor(e: unknown);
+}
diff --git a/npm/esm/src/errors.js b/npm/esm/src/errors.js
new file mode 100644
index 0000000..2cc9f4f
--- /dev/null
+++ b/npm/esm/src/errors.js
@@ -0,0 +1,19 @@
+/**
+ * The base error class of kyber-ts.
+ */
+export class MlKemError extends Error {
+ constructor(e) {
+ let message;
+ if (e instanceof Error) {
+ message = e.message;
+ }
+ else if (typeof e === "string") {
+ message = e;
+ }
+ else {
+ message = "";
+ }
+ super(message);
+ this.name = this.constructor.name;
+ }
+}
diff --git a/npm/esm/src/kyber1024.d.ts b/npm/esm/src/kyber1024.d.ts
new file mode 100644
index 0000000..95958fa
--- /dev/null
+++ b/npm/esm/src/kyber1024.d.ts
@@ -0,0 +1,68 @@
+import { KyberBase } from "./kyberBase.js";
+/**
+ * Represents the MlKem1024 class.
+ *
+ * MlKem1024 is a subclass of KyberBase and implements specific methods for the Kyber-1024 parameter set.
+ *
+ * @example
+ *
+ * ```ts
+ * // import { MlKem1024 } from "crystals-kyber-js"; // Node.js
+ * import { MlKem1024 } from "http://deno.land/x/crystals_kyber/mod.ts"; // Deno
+ *
+ * const recipient = new MlKem1024();
+ * const [pkR, skR] = await recipient.generateKeyPair();
+
+ * const sender = new MlKem1024();
+ * const [ct, ssS] = await sender.encap(pkR);
+
+ * const ssR = await recipient.decap(ct, skR);
+ * // ssS === ssR
+ * ```
+ */
+export declare class MlKem1024 extends KyberBase {
+ protected _k: number;
+ protected _du: number;
+ protected _dv: number;
+ protected _eta1: number;
+ protected _eta2: number;
+ /**
+ * Constructs a new instance of the MlKem1024 class.
+ */
+ constructor();
+ /**
+ * Lossily compresses and serializes a vector of polynomials.
+ *
+ * @param u - The vector of polynomials to compress.
+ * @returns The compressed and serialized data as a Uint8Array.
+ */
+ protected _compressU(r: Uint8Array, u: Array>): Uint8Array;
+ /**
+ * Lossily compresses and serializes a polynomial.
+ *
+ * @param r - The output buffer to store the compressed data.
+ * @param v - The polynomial to compress.
+ * @returns The compressed and serialized data as a Uint8Array.
+ */
+ protected _compressV(r: Uint8Array, v: Array): Uint8Array;
+ /**
+ * Deserializes and decompresses a vector of polynomials.
+ * This is the approximate inverse of the `_compressU` method.
+ * Since compression is lossy, the decompressed data may not match the original vector of polynomials.
+ *
+ * @param a - The compressed and serialized data as a Uint8Array.
+ * @returns The decompressed vector of polynomials.
+ */
+ protected _decompressU(a: Uint8Array): Array>;
+ /**
+ * Decompresses a given polynomial, representing the approximate inverse of
+ * compress2, in Uint8Array into an array of numbers.
+ *
+ * Note that compression is lossy, and thus decompression will not match the
+ * original input.
+ *
+ * @param a - The Uint8Array to decompress.
+ * @returns An array of numbers obtained from the decompression process.
+ */
+ protected _decompressV(a: Uint8Array): Array;
+}
diff --git a/npm/esm/src/kyber1024.js b/npm/esm/src/kyber1024.js
new file mode 100644
index 0000000..4f37192
--- /dev/null
+++ b/npm/esm/src/kyber1024.js
@@ -0,0 +1,193 @@
+/**
+ * This implementation is based on https://github.com/antontutoveanu/crystals-kyber-javascript,
+ * which was deveploped under the MIT licence below:
+ * https://github.com/antontutoveanu/crystals-kyber-javascript/blob/main/LICENSE
+ */
+import { N, Q } from "./consts.js";
+import { KyberBase } from "./kyberBase.js";
+import { byte, int16, uint16, uint32 } from "./utils.js";
+/**
+ * Represents the MlKem1024 class.
+ *
+ * MlKem1024 is a subclass of KyberBase and implements specific methods for the Kyber-1024 parameter set.
+ *
+ * @example
+ *
+ * ```ts
+ * // import { MlKem1024 } from "crystals-kyber-js"; // Node.js
+ * import { MlKem1024 } from "http://deno.land/x/crystals_kyber/mod.ts"; // Deno
+ *
+ * const recipient = new MlKem1024();
+ * const [pkR, skR] = await recipient.generateKeyPair();
+
+ * const sender = new MlKem1024();
+ * const [ct, ssS] = await sender.encap(pkR);
+
+ * const ssR = await recipient.decap(ct, skR);
+ * // ssS === ssR
+ * ```
+ */
+export class MlKem1024 extends KyberBase {
+ /**
+ * Constructs a new instance of the MlKem1024 class.
+ */
+ constructor() {
+ super();
+ Object.defineProperty(this, "_k", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: 4
+ });
+ Object.defineProperty(this, "_du", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: 11
+ });
+ Object.defineProperty(this, "_dv", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: 5
+ });
+ Object.defineProperty(this, "_eta1", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: 2
+ });
+ Object.defineProperty(this, "_eta2", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: 2
+ });
+ this._skSize = 12 * this._k * N / 8;
+ this._pkSize = this._skSize + 32;
+ this._compressedUSize = this._k * this._du * N / 8;
+ this._compressedVSize = this._dv * N / 8;
+ }
+ // compressU lossily compresses and serializes a vector of polynomials.
+ /**
+ * Lossily compresses and serializes a vector of polynomials.
+ *
+ * @param u - The vector of polynomials to compress.
+ * @returns The compressed and serialized data as a Uint8Array.
+ */
+ _compressU(r, u) {
+ const t = new Array(8);
+ for (let rr = 0, i = 0; i < this._k; i++) {
+ for (let j = 0; j < N / 8; j++) {
+ for (let k = 0; k < 8; k++) {
+ t[k] = uint16((((uint32(u[i][8 * j + k]) << 11) + uint32(Q / 2)) /
+ uint32(Q)) & 0x7ff);
+ }
+ r[rr++] = byte(t[0] >> 0);
+ r[rr++] = byte((t[0] >> 8) | (t[1] << 3));
+ r[rr++] = byte((t[1] >> 5) | (t[2] << 6));
+ r[rr++] = byte(t[2] >> 2);
+ r[rr++] = byte((t[2] >> 10) | (t[3] << 1));
+ r[rr++] = byte((t[3] >> 7) | (t[4] << 4));
+ r[rr++] = byte((t[4] >> 4) | (t[5] << 7));
+ r[rr++] = byte(t[5] >> 1);
+ r[rr++] = byte((t[5] >> 9) | (t[6] << 2));
+ r[rr++] = byte((t[6] >> 6) | (t[7] << 5));
+ r[rr++] = byte(t[7] >> 3);
+ }
+ }
+ return r;
+ }
+ // compressV lossily compresses and subsequently serializes a polynomial.
+ /**
+ * Lossily compresses and serializes a polynomial.
+ *
+ * @param r - The output buffer to store the compressed data.
+ * @param v - The polynomial to compress.
+ * @returns The compressed and serialized data as a Uint8Array.
+ */
+ _compressV(r, v) {
+ const t = new Uint8Array(8);
+ for (let rr = 0, i = 0; i < N / 8; i++) {
+ for (let j = 0; j < 8; j++) {
+ t[j] = byte(((uint32(v[8 * i + j]) << 5) + uint32(Q / 2)) / uint32(Q)) & 31;
+ }
+ r[rr++] = byte((t[0] >> 0) | (t[1] << 5));
+ r[rr++] = byte((t[1] >> 3) | (t[2] << 2) | (t[3] << 7));
+ r[rr++] = byte((t[3] >> 1) | (t[4] << 4));
+ r[rr++] = byte((t[4] >> 4) | (t[5] << 1) | (t[6] << 6));
+ r[rr++] = byte((t[6] >> 2) | (t[7] << 3));
+ }
+ return r;
+ }
+ // decompressU de-serializes and decompresses a vector of polynomials and
+ // represents the approximate inverse of compress1. Since compression is lossy,
+ // the results of decompression will may not match the original vector of polynomials.
+ /**
+ * Deserializes and decompresses a vector of polynomials.
+ * This is the approximate inverse of the `_compressU` method.
+ * Since compression is lossy, the decompressed data may not match the original vector of polynomials.
+ *
+ * @param a - The compressed and serialized data as a Uint8Array.
+ * @returns The decompressed vector of polynomials.
+ */
+ _decompressU(a) {
+ const r = new Array(this._k);
+ for (let i = 0; i < this._k; i++) {
+ r[i] = new Array(384);
+ }
+ const t = new Array(8);
+ for (let aa = 0, i = 0; i < this._k; i++) {
+ for (let j = 0; j < N / 8; j++) {
+ t[0] = (uint16(a[aa + 0]) >> 0) | (uint16(a[aa + 1]) << 8);
+ t[1] = (uint16(a[aa + 1]) >> 3) | (uint16(a[aa + 2]) << 5);
+ t[2] = (uint16(a[aa + 2]) >> 6) | (uint16(a[aa + 3]) << 2) |
+ (uint16(a[aa + 4]) << 10);
+ t[3] = (uint16(a[aa + 4]) >> 1) | (uint16(a[aa + 5]) << 7);
+ t[4] = (uint16(a[aa + 5]) >> 4) | (uint16(a[aa + 6]) << 4);
+ t[5] = (uint16(a[aa + 6]) >> 7) | (uint16(a[aa + 7]) << 1) |
+ (uint16(a[aa + 8]) << 9);
+ t[6] = (uint16(a[aa + 8]) >> 2) | (uint16(a[aa + 9]) << 6);
+ t[7] = (uint16(a[aa + 9]) >> 5) | (uint16(a[aa + 10]) << 3);
+ aa = aa + 11;
+ for (let k = 0; k < 8; k++) {
+ r[i][8 * j + k] = (uint32(t[k] & 0x7FF) * Q + 1024) >> 11;
+ }
+ }
+ }
+ return r;
+ }
+ // decompressV de-serializes and subsequently decompresses a polynomial,
+ // representing the approximate inverse of compress2.
+ // Note that compression is lossy, and thus decompression will not match the
+ // original input.
+ /**
+ * Decompresses a given polynomial, representing the approximate inverse of
+ * compress2, in Uint8Array into an array of numbers.
+ *
+ * Note that compression is lossy, and thus decompression will not match the
+ * original input.
+ *
+ * @param a - The Uint8Array to decompress.
+ * @returns An array of numbers obtained from the decompression process.
+ */
+ _decompressV(a) {
+ const r = new Array(384);
+ const t = new Array(8);
+ for (let aa = 0, i = 0; i < N / 8; i++) {
+ t[0] = a[aa + 0] >> 0;
+ t[1] = (a[aa + 0] >> 5) | (a[aa + 1] << 3);
+ t[2] = a[aa + 1] >> 2;
+ t[3] = (a[aa + 1] >> 7) | (a[aa + 2] << 1);
+ t[4] = (a[aa + 2] >> 4) | (a[aa + 3] << 4);
+ t[5] = a[aa + 3] >> 1;
+ t[6] = (a[aa + 3] >> 6) | (a[aa + 4] << 2);
+ t[7] = a[aa + 4] >> 3;
+ aa = aa + 5;
+ for (let j = 0; j < 8; j++) {
+ r[8 * i + j] = int16(((uint32(t[j] & 31) * uint32(Q)) + 16) >> 5);
+ }
+ }
+ return r;
+ }
+}
diff --git a/npm/esm/src/kyber512.d.ts b/npm/esm/src/kyber512.d.ts
new file mode 100644
index 0000000..5c4af1a
--- /dev/null
+++ b/npm/esm/src/kyber512.d.ts
@@ -0,0 +1,37 @@
+import { KyberBase } from "./kyberBase.js";
+/**
+ * Represents the MlKem512 class.
+ *
+ * This class extends the KyberBase class and provides specific implementation for MlKem512.
+ *
+ * @remarks
+ *
+ * MlKem512 is a specific implementation of the Kyber key encapsulation mechanism.
+ *
+ * @example
+ *
+ * ```ts
+ * // import { MlKem512 } from "crystals-kyber-js"; // Node.js
+ * import { MlKem512 } from "http://deno.land/x/crystals_kyber/mod.ts"; // Deno
+ *
+ * const recipient = new MlKem512();
+ * const [pkR, skR] = await recipient.generateKeyPair();
+ *
+ * const sender = new MlKem512();
+ * const [ct, ssS] = await sender.encap(pkR);
+ *
+ * const ssR = await recipient.decap(ct, skR);
+ * // ssS === ssR
+ * ```
+ */
+export declare class MlKem512 extends KyberBase {
+ protected _k: number;
+ protected _du: number;
+ protected _dv: number;
+ protected _eta1: number;
+ protected _eta2: number;
+ /**
+ * Constructs a new instance of the MlKem512 class.
+ */
+ constructor();
+}
diff --git a/npm/esm/src/kyber512.js b/npm/esm/src/kyber512.js
new file mode 100644
index 0000000..5b5b3b2
--- /dev/null
+++ b/npm/esm/src/kyber512.js
@@ -0,0 +1,115 @@
+/**
+ * This implementation is based on https://github.com/antontutoveanu/crystals-kyber-javascript,
+ * which was deveploped under the MIT licence below:
+ * https://github.com/antontutoveanu/crystals-kyber-javascript/blob/main/LICENSE
+ */
+import { N } from "./consts.js";
+import { KyberBase } from "./kyberBase.js";
+import { byteopsLoad24, int16, prf } from "./utils.js";
+/**
+ * Represents the MlKem512 class.
+ *
+ * This class extends the KyberBase class and provides specific implementation for MlKem512.
+ *
+ * @remarks
+ *
+ * MlKem512 is a specific implementation of the Kyber key encapsulation mechanism.
+ *
+ * @example
+ *
+ * ```ts
+ * // import { MlKem512 } from "crystals-kyber-js"; // Node.js
+ * import { MlKem512 } from "http://deno.land/x/crystals_kyber/mod.ts"; // Deno
+ *
+ * const recipient = new MlKem512();
+ * const [pkR, skR] = await recipient.generateKeyPair();
+ *
+ * const sender = new MlKem512();
+ * const [ct, ssS] = await sender.encap(pkR);
+ *
+ * const ssR = await recipient.decap(ct, skR);
+ * // ssS === ssR
+ * ```
+ */
+export class MlKem512 extends KyberBase {
+ /**
+ * Constructs a new instance of the MlKem512 class.
+ */
+ constructor() {
+ super();
+ Object.defineProperty(this, "_k", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: 2
+ });
+ Object.defineProperty(this, "_du", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: 10
+ });
+ Object.defineProperty(this, "_dv", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: 4
+ });
+ Object.defineProperty(this, "_eta1", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: 3
+ });
+ Object.defineProperty(this, "_eta2", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: 2
+ });
+ this._skSize = 12 * this._k * N / 8;
+ this._pkSize = this._skSize + 32;
+ this._compressedUSize = this._k * this._du * N / 8;
+ this._compressedVSize = this._dv * N / 8;
+ }
+ /**
+ * Samples a vector of polynomials from a seed.
+ * @internal
+ * @param sigma - The seed.
+ * @param offset - The offset.
+ * @param size - The size.
+ * @returns The sampled vector of polynomials.
+ */
+ _sampleNoise1(sigma, offset, size) {
+ const r = new Array(size);
+ for (let i = 0; i < size; i++) {
+ r[i] = byteopsCbd(prf(this._eta1 * N / 4, sigma, offset), this._eta1);
+ offset++;
+ }
+ return r;
+ }
+}
+/**
+ * Performs the byte operations for the Cbd function.
+ *
+ * @param buf - The input buffer.
+ * @param eta - The value of eta.
+ * @returns An array of numbers representing the result of the byte operations.
+ */
+function byteopsCbd(buf, eta) {
+ let t, d;
+ let a, b;
+ const r = new Array(384).fill(0);
+ for (let i = 0; i < N / 4; i++) {
+ t = byteopsLoad24(buf.subarray(3 * i, buf.length));
+ d = t & 0x00249249;
+ d = d + ((t >> 1) & 0x00249249);
+ d = d + ((t >> 2) & 0x00249249);
+ for (let j = 0; j < 4; j++) {
+ a = int16((d >> (6 * j + 0)) & 0x7);
+ b = int16((d >> (6 * j + eta)) & 0x7);
+ r[4 * i + j] = a - b;
+ }
+ }
+ return r;
+}
diff --git a/npm/esm/src/kyber768.d.ts b/npm/esm/src/kyber768.d.ts
new file mode 100644
index 0000000..5fc8291
--- /dev/null
+++ b/npm/esm/src/kyber768.d.ts
@@ -0,0 +1,34 @@
+import { KyberBase } from "./kyberBase.js";
+/**
+ * Represents the MlKem768 class, which extends the KyberBase class.
+ *
+ * MlKem768 is a specific implementation of the Kyber key encapsulation mechanism.
+ *
+ * @remarks
+ *
+ * This class extends the KyberBase class and provides specific implementation for MlKem768.
+ *
+ * @example
+ *
+ * ```ts
+ * // import { MlKem768 } from "crystals-kyber-js"; // Node.js
+ * import { MlKem768 } from "http://deno.land/x/crystals_kyber/mod.ts"; // Deno
+ *
+ * const recipient = new MlKem768();
+ * const [pkR, skR] = await recipient.generateKeyPair();
+ *
+ * const sender = new MlKem768();
+ * const [ct, ssS] = await sender.encap(pkR);
+ *
+ * const ssR = await recipient.decap(ct, skR);
+ * // ssS === ssR
+ * ```
+ */
+export declare class MlKem768 extends KyberBase {
+ protected _k: number;
+ protected _du: number;
+ protected _dv: number;
+ protected _eta1: number;
+ protected _eta2: number;
+ constructor();
+}
diff --git a/npm/esm/src/kyber768.js b/npm/esm/src/kyber768.js
new file mode 100644
index 0000000..2aa3ceb
--- /dev/null
+++ b/npm/esm/src/kyber768.js
@@ -0,0 +1,71 @@
+/**
+ * This implementation is based on https://github.com/antontutoveanu/crystals-kyber-javascript,
+ * which was deveploped under the MIT licence below:
+ * https://github.com/antontutoveanu/crystals-kyber-javascript/blob/main/LICENSE
+ */
+import { N } from "./consts.js";
+import { KyberBase } from "./kyberBase.js";
+/**
+ * Represents the MlKem768 class, which extends the KyberBase class.
+ *
+ * MlKem768 is a specific implementation of the Kyber key encapsulation mechanism.
+ *
+ * @remarks
+ *
+ * This class extends the KyberBase class and provides specific implementation for MlKem768.
+ *
+ * @example
+ *
+ * ```ts
+ * // import { MlKem768 } from "crystals-kyber-js"; // Node.js
+ * import { MlKem768 } from "http://deno.land/x/crystals_kyber/mod.ts"; // Deno
+ *
+ * const recipient = new MlKem768();
+ * const [pkR, skR] = await recipient.generateKeyPair();
+ *
+ * const sender = new MlKem768();
+ * const [ct, ssS] = await sender.encap(pkR);
+ *
+ * const ssR = await recipient.decap(ct, skR);
+ * // ssS === ssR
+ * ```
+ */
+export class MlKem768 extends KyberBase {
+ constructor() {
+ super();
+ Object.defineProperty(this, "_k", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: 3
+ });
+ Object.defineProperty(this, "_du", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: 10
+ });
+ Object.defineProperty(this, "_dv", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: 4
+ });
+ Object.defineProperty(this, "_eta1", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: 2
+ });
+ Object.defineProperty(this, "_eta2", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: 2
+ });
+ this._skSize = 12 * this._k * N / 8;
+ this._pkSize = this._skSize + 32;
+ this._compressedUSize = this._k * this._du * N / 8;
+ this._compressedVSize = this._dv * N / 8;
+ }
+}
diff --git a/npm/esm/src/kyberBase.d.ts b/npm/esm/src/kyberBase.d.ts
new file mode 100644
index 0000000..2de91a1
--- /dev/null
+++ b/npm/esm/src/kyberBase.d.ts
@@ -0,0 +1,247 @@
+/**
+ * Represents the base class for the Kyber key encapsulation mechanism.
+ *
+ * This class provides the base implementation for the Kyber key encapsulation mechanism.
+ *
+ * @remarks
+ *
+ * This class is not intended to be used directly. Instead, use one of the subclasses:
+ *
+ * @example
+ *
+ * ```ts
+ * // import { KyberBase } from "crystals-kyber-js"; // Node.js
+ * import { KyberBase } from "http://deno.land/x/crystals_kyber/mod.ts"; // Deno
+ *
+ * class MlKem768 extends KyberBase {
+ * protected _k = 3;
+ * protected _du = 10;
+ * protected _dv = 4;
+ * protected _eta1 = 2;
+ * protected _eta2 = 2;
+ *
+ * constructor() {
+ * super();
+ * this._skSize = 12 * this._k * N / 8;
+ * this._pkSize = this._skSize + 32;
+ * this._compressedUSize = this._k * this._du * N / 8;
+ * this._compressedVSize = this._dv * N / 8;
+ * }
+ * }
+ *
+ * const kyber = new MlKem768();
+ * ```
+ */
+export declare class KyberBase {
+ private _api;
+ protected _k: number;
+ protected _du: number;
+ protected _dv: number;
+ protected _eta1: number;
+ protected _eta2: number;
+ protected _skSize: number;
+ protected _pkSize: number;
+ protected _compressedUSize: number;
+ protected _compressedVSize: number;
+ /**
+ * Creates a new instance of the KyberBase class.
+ */
+ constructor();
+ /**
+ * Generates a keypair [publicKey, privateKey].
+ *
+ * If an error occurred, throws {@link MlKemError}.
+ *
+ * @returns A kaypair [publicKey, privateKey].
+ * @throws {@link MlKemError}
+ *
+ * @example Generates a {@link MlKem768} keypair.
+ *
+ * ```ts
+ * // import { MlKem768 } from "crystals-kyber-js"; // Node.js
+ * import { MlKem768 } from "http://deno.land/x/crystals_kyber/mod.ts"; // Deno
+ *
+ * const kyber = new MlKem768();
+ * const [pk, sk] = await kyber.generateKeyPair();
+ * ```
+ */
+ generateKeyPair(): Promise<[Uint8Array, Uint8Array]>;
+ /**
+ * Derives a keypair [publicKey, privateKey] deterministically from a 64-octet seed.
+ *
+ * If an error occurred, throws {@link MlKemError}.
+ *
+ * @param seed A 64-octet seed for the deterministic key generation.
+ * @returns A kaypair [publicKey, privateKey].
+ * @throws {@link MlKemError}
+ *
+ * @example Derives a {@link MlKem768} keypair deterministically.
+ *
+ * ```ts
+ * // import { MlKem768 } from "crystals-kyber-js"; // Node.js
+ * import { MlKem768 } from "http://deno.land/x/crystals_kyber/mod.ts"; // Deno
+ *
+ * const kyber = new MlKem768();
+ * const seed = new Uint8Array(64);
+ * globalThis.crypto.getRandomValues(seed);
+ * const [pk, sk] = await kyber.deriveKeyPair(seed);
+ * ```
+ */
+ deriveKeyPair(seed: Uint8Array): Promise<[Uint8Array, Uint8Array]>;
+ /**
+ * Generates a shared secret from the encapsulated ciphertext and the private key.
+ *
+ * If an error occurred, throws {@link MlKemError}.
+ *
+ * @param pk A public key.
+ * @param seed An optional 32-octet seed for the deterministic shared secret generation.
+ * @returns A ciphertext (encapsulated public key) and a shared secret.
+ * @throws {@link MlKemError}
+ *
+ * @example The {@link MlKem768} encapsulation.
+ *
+ * ```ts
+ * // import { MlKem768 } from "crystals-kyber-js"; // Node.js
+ * import { MlKem768 } from "http://deno.land/x/crystals_kyber/mod.ts"; // Deno
+ *
+ * const kyber = new MlKem768();
+ * const [pk, sk] = await kyber.generateKeyPair();
+ * const [ct, ss] = await kyber.encap(pk);
+ * ```
+ */
+ encap(pk: Uint8Array, seed?: Uint8Array): Promise<[Uint8Array, Uint8Array]>;
+ /**
+ * Generates a ciphertext for the public key and a shared secret.
+ *
+ * If an error occurred, throws {@link MlKemError}.
+ *
+ * @param ct A ciphertext generated by {@link encap}.
+ * @param sk A private key.
+ * @returns A shared secret.
+ * @throws {@link MlKemError}
+ *
+ * @example The {@link MlKem768} decapsulation.
+ *
+ * ```ts
+ * // import { MlKem768 } from "crystals-kyber-js"; // Node.js
+ * import { MlKem768 } from "http://deno.land/x/crystals_kyber/mod.ts"; // Deno
+ *
+ * const kyber = new MlKem768();
+ * const [pk, sk] = await kyber.generateKeyPair();
+ * const [ct, ssS] = await kyber.encap(pk);
+ * const ssR = await kyber.decap(ct, sk);
+ * // ssS === ssR
+ * ```
+ */
+ decap(ct: Uint8Array, sk: Uint8Array): Promise;
+ /**
+ * Sets up the KyberBase instance by loading the necessary crypto library.
+ * If the crypto library is already loaded, this method does nothing.
+ * @returns {Promise} A promise that resolves when the setup is complete.
+ */
+ protected _setup(): Promise;
+ /**
+ * Returns a Uint8Array seed for cryptographic operations.
+ * If no seed is provided, a random seed of length 32 bytes is generated.
+ * If a seed is provided, it must be exactly 32 bytes in length.
+ *
+ * @param seed - Optional seed for cryptographic operations.
+ * @returns A Uint8Array seed.
+ * @throws Error if the provided seed is not 32 bytes in length.
+ */
+ private _getSeed;
+ /**
+ * Derives a key pair from a given seed.
+ *
+ * @param seed - The seed used for key derivation.
+ * @returns An array containing the public key and secret key.
+ */
+ private _deriveKeyPair;
+ /**
+ * Derives a CPA key pair using the provided CPA seed.
+ *
+ * @param cpaSeed - The CPA seed used for key derivation.
+ * @returns An array containing the public key and private key.
+ */
+ private _deriveCpaKeyPair;
+ /**
+ * K-PKE_Encrypt: Encapsulates a message using the Kyber encryption scheme.
+ *
+ * @param pk - The public key.
+ * @param msg - The message to be encapsulated.
+ * @param seed - The seed used for generating random values.
+ * @returns The encapsulated message as a Uint8Array.
+ */
+ private _encap;
+ /**
+ * Decapsulates the ciphertext using the provided secret key.
+ *
+ * @param ct - The ciphertext to be decapsulated.
+ * @param sk - The secret key used for decapsulation.
+ * @returns The decapsulated message as a Uint8Array.
+ */
+ private _decap;
+ /**
+ * Generates a sample matrix based on the provided seed and transposition flag.
+ *
+ * @param seed - The seed used for generating the matrix.
+ * @param transposed - A flag indicating whether the matrix should be transposed or not.
+ * @returns The generated sample matrix.
+ */
+ private _sampleMatrix;
+ /**
+ * Generates a 2D array of noise samples.
+ *
+ * @param sigma - The noise parameter.
+ * @param offset - The offset value.
+ * @param size - The size of the array.
+ * @returns The generated 2D array of noise samples.
+ */
+ protected _sampleNoise1(sigma: Uint8Array, offset: number, size: number): Array>;
+ /**
+ * Generates a 2-dimensional array of noise samples.
+ *
+ * @param sigma - The noise parameter.
+ * @param offset - The offset value.
+ * @param size - The size of the array.
+ * @returns The generated 2-dimensional array of noise samples.
+ */
+ protected _sampleNoise2(sigma: Uint8Array, offset: number, size: number): Array>;
+ /**
+ * Converts a Uint8Array to a 2D array of numbers representing a polynomial vector.
+ * Each element in the resulting array represents a polynomial.
+ * @param a The Uint8Array to convert.
+ * @returns The 2D array of numbers representing the polynomial vector.
+ */
+ private _polyvecFromBytes;
+ /**
+ * Compresses the given array of coefficients into a Uint8Array.
+ *
+ * @param r - The output Uint8Array.
+ * @param u - The array of coefficients.
+ * @returns The compressed Uint8Array.
+ */
+ protected _compressU(r: Uint8Array, u: Array>): Uint8Array;
+ /**
+ * Compresses the given array of numbers into a Uint8Array.
+ *
+ * @param r - The Uint8Array to store the compressed values.
+ * @param v - The array of numbers to compress.
+ * @returns The compressed Uint8Array.
+ */
+ protected _compressV(r: Uint8Array, v: Array): Uint8Array;
+ /**
+ * Decompresses a Uint8Array into a two-dimensional array of numbers.
+ *
+ * @param a The Uint8Array to decompress.
+ * @returns The decompressed two-dimensional array.
+ */
+ protected _decompressU(a: Uint8Array): Array>;
+ /**
+ * Decompresses a Uint8Array into an array of numbers.
+ *
+ * @param a - The Uint8Array to decompress.
+ * @returns An array of numbers.
+ */
+ protected _decompressV(a: Uint8Array): Array;
+}
diff --git a/npm/esm/src/kyberBase.js b/npm/esm/src/kyberBase.js
new file mode 100644
index 0000000..6e837e1
--- /dev/null
+++ b/npm/esm/src/kyberBase.js
@@ -0,0 +1,1036 @@
+/**
+ * This implementation is based on https://github.com/antontutoveanu/crystals-kyber-javascript,
+ * which was deveploped under the MIT licence below:
+ * https://github.com/antontutoveanu/crystals-kyber-javascript/blob/main/LICENSE
+ */
+import { sha3_256, sha3_512, shake128, shake256 } from "./deps.js";
+import { N, NTT_ZETAS, NTT_ZETAS_INV, Q, Q_INV } from "./consts.js";
+import { MlKemError } from "./errors.js";
+import { byte, byteopsLoad32, constantTimeCompare, equalUint8Array, int16, int32, loadCrypto, prf, uint16, uint32, } from "./utils.js";
+/**
+ * Represents the base class for the Kyber key encapsulation mechanism.
+ *
+ * This class provides the base implementation for the Kyber key encapsulation mechanism.
+ *
+ * @remarks
+ *
+ * This class is not intended to be used directly. Instead, use one of the subclasses:
+ *
+ * @example
+ *
+ * ```ts
+ * // import { KyberBase } from "crystals-kyber-js"; // Node.js
+ * import { KyberBase } from "http://deno.land/x/crystals_kyber/mod.ts"; // Deno
+ *
+ * class MlKem768 extends KyberBase {
+ * protected _k = 3;
+ * protected _du = 10;
+ * protected _dv = 4;
+ * protected _eta1 = 2;
+ * protected _eta2 = 2;
+ *
+ * constructor() {
+ * super();
+ * this._skSize = 12 * this._k * N / 8;
+ * this._pkSize = this._skSize + 32;
+ * this._compressedUSize = this._k * this._du * N / 8;
+ * this._compressedVSize = this._dv * N / 8;
+ * }
+ * }
+ *
+ * const kyber = new MlKem768();
+ * ```
+ */
+export class KyberBase {
+ /**
+ * Creates a new instance of the KyberBase class.
+ */
+ constructor() {
+ Object.defineProperty(this, "_api", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: undefined
+ });
+ Object.defineProperty(this, "_k", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: 0
+ });
+ Object.defineProperty(this, "_du", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: 0
+ });
+ Object.defineProperty(this, "_dv", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: 0
+ });
+ Object.defineProperty(this, "_eta1", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: 0
+ });
+ Object.defineProperty(this, "_eta2", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: 0
+ });
+ Object.defineProperty(this, "_skSize", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: 0
+ });
+ Object.defineProperty(this, "_pkSize", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: 0
+ });
+ Object.defineProperty(this, "_compressedUSize", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: 0
+ });
+ Object.defineProperty(this, "_compressedVSize", {
+ enumerable: true,
+ configurable: true,
+ writable: true,
+ value: 0
+ });
+ }
+ /**
+ * Generates a keypair [publicKey, privateKey].
+ *
+ * If an error occurred, throws {@link MlKemError}.
+ *
+ * @returns A kaypair [publicKey, privateKey].
+ * @throws {@link MlKemError}
+ *
+ * @example Generates a {@link MlKem768} keypair.
+ *
+ * ```ts
+ * // import { MlKem768 } from "crystals-kyber-js"; // Node.js
+ * import { MlKem768 } from "http://deno.land/x/crystals_kyber/mod.ts"; // Deno
+ *
+ * const kyber = new MlKem768();
+ * const [pk, sk] = await kyber.generateKeyPair();
+ * ```
+ */
+ async generateKeyPair() {
+ await this._setup();
+ try {
+ const rnd = new Uint8Array(64);
+ this._api.getRandomValues(rnd);
+ return this._deriveKeyPair(rnd);
+ }
+ catch (e) {
+ throw new MlKemError(e);
+ }
+ }
+ /**
+ * Derives a keypair [publicKey, privateKey] deterministically from a 64-octet seed.
+ *
+ * If an error occurred, throws {@link MlKemError}.
+ *
+ * @param seed A 64-octet seed for the deterministic key generation.
+ * @returns A kaypair [publicKey, privateKey].
+ * @throws {@link MlKemError}
+ *
+ * @example Derives a {@link MlKem768} keypair deterministically.
+ *
+ * ```ts
+ * // import { MlKem768 } from "crystals-kyber-js"; // Node.js
+ * import { MlKem768 } from "http://deno.land/x/crystals_kyber/mod.ts"; // Deno
+ *
+ * const kyber = new MlKem768();
+ * const seed = new Uint8Array(64);
+ * globalThis.crypto.getRandomValues(seed);
+ * const [pk, sk] = await kyber.deriveKeyPair(seed);
+ * ```
+ */
+ async deriveKeyPair(seed) {
+ await this._setup();
+ try {
+ if (seed.byteLength !== 64) {
+ throw new Error("seed must be 64 bytes in length");
+ }
+ return this._deriveKeyPair(seed);
+ }
+ catch (e) {
+ throw new MlKemError(e);
+ }
+ }
+ /**
+ * Generates a shared secret from the encapsulated ciphertext and the private key.
+ *
+ * If an error occurred, throws {@link MlKemError}.
+ *
+ * @param pk A public key.
+ * @param seed An optional 32-octet seed for the deterministic shared secret generation.
+ * @returns A ciphertext (encapsulated public key) and a shared secret.
+ * @throws {@link MlKemError}
+ *
+ * @example The {@link MlKem768} encapsulation.
+ *
+ * ```ts
+ * // import { MlKem768 } from "crystals-kyber-js"; // Node.js
+ * import { MlKem768 } from "http://deno.land/x/crystals_kyber/mod.ts"; // Deno
+ *
+ * const kyber = new MlKem768();
+ * const [pk, sk] = await kyber.generateKeyPair();
+ * const [ct, ss] = await kyber.encap(pk);
+ * ```
+ */
+ async encap(pk, seed) {
+ await this._setup();
+ try {
+ // validate key type; the modulo is checked in `_encap`.
+ if (pk.length !== 384 * this._k + 32) {
+ throw new Error("invalid encapsulation key");
+ }
+ const m = this._getSeed(seed);
+ const [k, r] = g(m, h(pk));
+ const ct = this._encap(pk, m, r);
+ return [ct, k];
+ }
+ catch (e) {
+ throw new MlKemError(e);
+ }
+ }
+ /**
+ * Generates a ciphertext for the public key and a shared secret.
+ *
+ * If an error occurred, throws {@link MlKemError}.
+ *
+ * @param ct A ciphertext generated by {@link encap}.
+ * @param sk A private key.
+ * @returns A shared secret.
+ * @throws {@link MlKemError}
+ *
+ * @example The {@link MlKem768} decapsulation.
+ *
+ * ```ts
+ * // import { MlKem768 } from "crystals-kyber-js"; // Node.js
+ * import { MlKem768 } from "http://deno.land/x/crystals_kyber/mod.ts"; // Deno
+ *
+ * const kyber = new MlKem768();
+ * const [pk, sk] = await kyber.generateKeyPair();
+ * const [ct, ssS] = await kyber.encap(pk);
+ * const ssR = await kyber.decap(ct, sk);
+ * // ssS === ssR
+ * ```
+ */
+ async decap(ct, sk) {
+ await this._setup();
+ try {
+ // ciphertext type check
+ if (ct.byteLength !== this._compressedUSize + this._compressedVSize) {
+ throw new Error("Invalid ct size");
+ }
+ // decapsulation key type check
+ if (sk.length !== 768 * this._k + 96) {
+ throw new Error("Invalid decapsulation key");
+ }
+ const sk2 = sk.subarray(0, this._skSize);
+ const pk = sk.subarray(this._skSize, this._skSize + this._pkSize);
+ const hpk = sk.subarray(this._skSize + this._pkSize, this._skSize + this._pkSize + 32);
+ const z = sk.subarray(this._skSize + this._pkSize + 32, this._skSize + this._pkSize + 64);
+ const m2 = this._decap(ct, sk2);
+ const [k2, r2] = g(m2, hpk);
+ const kBar = kdf(z, ct);
+ const ct2 = this._encap(pk, m2, r2);
+ return constantTimeCompare(ct, ct2) === 1 ? k2 : kBar;
+ }
+ catch (e) {
+ throw new MlKemError(e);
+ }
+ }
+ /**
+ * Sets up the KyberBase instance by loading the necessary crypto library.
+ * If the crypto library is already loaded, this method does nothing.
+ * @returns {Promise} A promise that resolves when the setup is complete.
+ */
+ async _setup() {
+ if (this._api !== undefined) {
+ return;
+ }
+ this._api = await loadCrypto();
+ }
+ /**
+ * Returns a Uint8Array seed for cryptographic operations.
+ * If no seed is provided, a random seed of length 32 bytes is generated.
+ * If a seed is provided, it must be exactly 32 bytes in length.
+ *
+ * @param seed - Optional seed for cryptographic operations.
+ * @returns A Uint8Array seed.
+ * @throws Error if the provided seed is not 32 bytes in length.
+ */
+ _getSeed(seed) {
+ if (seed == undefined) {
+ const s = new Uint8Array(32);
+ this._api.getRandomValues(s);
+ return s;
+ }
+ if (seed.byteLength !== 32) {
+ throw new Error("seed must be 32 bytes in length");
+ }
+ return seed;
+ }
+ /**
+ * Derives a key pair from a given seed.
+ *
+ * @param seed - The seed used for key derivation.
+ * @returns An array containing the public key and secret key.
+ */
+ _deriveKeyPair(seed) {
+ const cpaSeed = seed.subarray(0, 32);
+ const z = seed.subarray(32, 64);
+ const [pk, skBody] = this._deriveCpaKeyPair(cpaSeed);
+ const pkh = h(pk);
+ const sk = new Uint8Array(this._skSize + this._pkSize + 64);
+ sk.set(skBody, 0);
+ sk.set(pk, this._skSize);
+ sk.set(pkh, this._skSize + this._pkSize);
+ sk.set(z, this._skSize + this._pkSize + 32);
+ return [pk, sk];
+ }
+ // indcpaKeyGen generates public and private keys for the CPA-secure
+ // public-key encryption scheme underlying Kyber.
+ /**
+ * Derives a CPA key pair using the provided CPA seed.
+ *
+ * @param cpaSeed - The CPA seed used for key derivation.
+ * @returns An array containing the public key and private key.
+ */
+ _deriveCpaKeyPair(cpaSeed) {
+ const [publicSeed, noiseSeed] = g(cpaSeed);
+ const a = this._sampleMatrix(publicSeed, false);
+ const s = this._sampleNoise1(noiseSeed, 0, this._k);
+ const e = this._sampleNoise1(noiseSeed, this._k, this._k);
+ // perform number theoretic transform on secret s
+ for (let i = 0; i < this._k; i++) {
+ s[i] = ntt(s[i]);
+ s[i] = reduce(s[i]);
+ e[i] = ntt(e[i]);
+ }
+ // KEY COMPUTATION
+ // pk = A*s + e
+ const pk = new Array(this._k);
+ for (let i = 0; i < this._k; i++) {
+ pk[i] = polyToMont(multiply(a[i], s));
+ pk[i] = add(pk[i], e[i]);
+ pk[i] = reduce(pk[i]);
+ }
+ // PUBLIC KEY
+ // turn polynomials into byte arrays
+ const pubKey = new Uint8Array(this._pkSize);
+ for (let i = 0; i < this._k; i++) {
+ pubKey.set(polyToBytes(pk[i]), i * 384);
+ }
+ // append public seed
+ pubKey.set(publicSeed, this._skSize);
+ // PRIVATE KEY
+ // turn polynomials into byte arrays
+ const privKey = new Uint8Array(this._skSize);
+ for (let i = 0; i < this._k; i++) {
+ privKey.set(polyToBytes(s[i]), i * 384);
+ }
+ return [pubKey, privKey];
+ }
+ // _encap is the encapsulation function of the CPA-secure
+ // public-key encryption scheme underlying Kyber.
+ /**
+ * K-PKE_Encrypt: Encapsulates a message using the Kyber encryption scheme.
+ *
+ * @param pk - The public key.
+ * @param msg - The message to be encapsulated.
+ * @param seed - The seed used for generating random values.
+ * @returns The encapsulated message as a Uint8Array.
+ */
+ _encap(pk, msg, seed) {
+ const tHat = new Array(this._k);
+ const pkCheck = new Uint8Array(384 * this._k); // to validate the pk modulo (see input validation at NIST draft 6.2)
+ for (let i = 0; i < this._k; i++) {
+ tHat[i] = polyFromBytes(pk.subarray(i * 384, (i + 1) * 384));
+ pkCheck.set(polyToBytes(tHat[i]), i * 384);
+ }
+ if (!equalUint8Array(pk.subarray(0, pkCheck.length), pkCheck)) {
+ throw new Error("invalid encapsulation key");
+ }
+ const rho = pk.subarray(this._skSize);
+ const a = this._sampleMatrix(rho, true);
+ const r = this._sampleNoise1(seed, 0, this._k);
+ const e1 = this._sampleNoise2(seed, this._k, this._k);
+ const e2 = this._sampleNoise2(seed, this._k * 2, 1)[0];
+ // perform number theoretic transform on random vector r
+ for (let i = 0; i < this._k; i++) {
+ r[i] = ntt(r[i]);
+ r[i] = reduce(r[i]);
+ }
+ // u = A*r + e1
+ const u = new Array(this._k);
+ for (let i = 0; i < this._k; i++) {
+ u[i] = multiply(a[i], r);
+ u[i] = nttInverse(u[i]);
+ u[i] = add(u[i], e1[i]);
+ u[i] = reduce(u[i]);
+ }
+ // v = tHat*r + e2 + m
+ const m = polyFromMsg(msg);
+ let v = multiply(tHat, r);
+ v = nttInverse(v);
+ v = add(v, e2);
+ v = add(v, m);
+ v = reduce(v);
+ // compress
+ const ret = new Uint8Array(this._compressedUSize + this._compressedVSize);
+ this._compressU(ret.subarray(0, this._compressedUSize), u);
+ this._compressV(ret.subarray(this._compressedUSize), v);
+ return ret;
+ }
+ // indcpaDecrypt is the decryption function of the CPA-secure
+ // public-key encryption scheme underlying Kyber.
+ /**
+ * Decapsulates the ciphertext using the provided secret key.
+ *
+ * @param ct - The ciphertext to be decapsulated.
+ * @param sk - The secret key used for decapsulation.
+ * @returns The decapsulated message as a Uint8Array.
+ */
+ _decap(ct, sk) {
+ // extract ciphertext
+ const u = this._decompressU(ct.subarray(0, this._compressedUSize));
+ const v = this._decompressV(ct.subarray(this._compressedUSize));
+ const privateKeyPolyvec = this._polyvecFromBytes(sk);
+ for (let i = 0; i < this._k; i++) {
+ u[i] = ntt(u[i]);
+ }
+ let mp = multiply(privateKeyPolyvec, u);
+ mp = nttInverse(mp);
+ mp = subtract(v, mp);
+ mp = reduce(mp);
+ return polyToMsg(mp);
+ }
+ // generateMatrixA deterministically generates a matrix `A` (or the transpose of `A`)
+ // from a seed. Entries of the matrix are polynomials that look uniformly random.
+ // Performs rejection sampling on the output of an extendable-output function (XOF).
+ /**
+ * Generates a sample matrix based on the provided seed and transposition flag.
+ *
+ * @param seed - The seed used for generating the matrix.
+ * @param transposed - A flag indicating whether the matrix should be transposed or not.
+ * @returns The generated sample matrix.
+ */
+ _sampleMatrix(seed, transposed) {
+ const a = new Array(this._k);
+ const transpose = new Uint8Array(2);
+ for (let ctr = 0, i = 0; i < this._k; i++) {
+ a[i] = new Array(this._k);
+ for (let j = 0; j < this._k; j++) {
+ // set if transposed matrix or not
+ if (transposed) {
+ transpose[0] = i;
+ transpose[1] = j;
+ }
+ else {
+ transpose[0] = j;
+ transpose[1] = i;
+ }
+ const output = xof(seed, transpose);
+ // run rejection sampling on the output from above
+ const result = indcpaRejUniform(output.subarray(0, 504), 504, N);
+ a[i][j] = result[0]; // the result here is an NTT-representation
+ ctr = result[1]; // keeps track of index of output array from sampling function
+ while (ctr < N) { // if the polynomial hasnt been filled yet with mod q entries
+ const outputn = output.subarray(504, 672); // take last 168 bytes of byte array from xof
+ const result1 = indcpaRejUniform(outputn, 168, N - ctr); // run sampling function again
+ const missing = result1[0]; // here is additional mod q polynomial coefficients
+ const ctrn = result1[1]; // how many coefficients were accepted and are in the output
+ // starting at last position of output array from first sampling function until 256 is reached
+ for (let k = ctr; k < N; k++) {
+ a[i][j][k] = missing[k - ctr]; // fill rest of array with the additional coefficients until full
+ }
+ ctr = ctr + ctrn; // update index
+ }
+ }
+ }
+ return a;
+ }
+ /**
+ * Generates a 2D array of noise samples.
+ *
+ * @param sigma - The noise parameter.
+ * @param offset - The offset value.
+ * @param size - The size of the array.
+ * @returns The generated 2D array of noise samples.
+ */
+ _sampleNoise1(sigma, offset, size) {
+ const r = new Array(size);
+ for (let i = 0; i < size; i++) {
+ r[i] = byteopsCbd(prf(this._eta1 * N / 4, sigma, offset), this._eta1);
+ offset++;
+ }
+ return r;
+ }
+ /**
+ * Generates a 2-dimensional array of noise samples.
+ *
+ * @param sigma - The noise parameter.
+ * @param offset - The offset value.
+ * @param size - The size of the array.
+ * @returns The generated 2-dimensional array of noise samples.
+ */
+ _sampleNoise2(sigma, offset, size) {
+ const r = new Array(size);
+ for (let i = 0; i < size; i++) {
+ r[i] = byteopsCbd(prf(this._eta2 * N / 4, sigma, offset), this._eta2);
+ offset++;
+ }
+ return r;
+ }
+ // polyvecFromBytes deserializes a vector of polynomials.
+ /**
+ * Converts a Uint8Array to a 2D array of numbers representing a polynomial vector.
+ * Each element in the resulting array represents a polynomial.
+ * @param a The Uint8Array to convert.
+ * @returns The 2D array of numbers representing the polynomial vector.
+ */
+ _polyvecFromBytes(a) {
+ const r = new Array(this._k);
+ for (let i = 0; i < this._k; i++) {
+ r[i] = polyFromBytes(a.subarray(i * 384, (i + 1) * 384));
+ }
+ return r;
+ }
+ // compressU lossily compresses and serializes a vector of polynomials.
+ /**
+ * Compresses the given array of coefficients into a Uint8Array.
+ *
+ * @param r - The output Uint8Array.
+ * @param u - The array of coefficients.
+ * @returns The compressed Uint8Array.
+ */
+ _compressU(r, u) {
+ const t = new Array(4);
+ for (let rr = 0, i = 0; i < this._k; i++) {
+ for (let j = 0; j < N / 4; j++) {
+ for (let k = 0; k < 4; k++) {
+ // parse {0,...,3328} to {0,...,1023}
+ t[k] = (((u[i][4 * j + k] << 10) + Q / 2) / Q) &
+ 0b1111111111;
+ }
+ // converts 4 12-bit coefficients {0,...,3328} to 5 8-bit bytes {0,...,255}
+ // 48 bits down to 40 bits per block
+ r[rr++] = byte(t[0] >> 0);
+ r[rr++] = byte((t[0] >> 8) | (t[1] << 2));
+ r[rr++] = byte((t[1] >> 6) | (t[2] << 4));
+ r[rr++] = byte((t[2] >> 4) | (t[3] << 6));
+ r[rr++] = byte(t[3] >> 2);
+ }
+ }
+ return r;
+ }
+ // compressV lossily compresses and subsequently serializes a polynomial.
+ /**
+ * Compresses the given array of numbers into a Uint8Array.
+ *
+ * @param r - The Uint8Array to store the compressed values.
+ * @param v - The array of numbers to compress.
+ * @returns The compressed Uint8Array.
+ */
+ _compressV(r, v) {
+ // const r = new Uint8Array(128);
+ const t = new Uint8Array(8);
+ for (let rr = 0, i = 0; i < N / 8; i++) {
+ for (let j = 0; j < 8; j++) {
+ t[j] = byte(((v[8 * i + j] << 4) + Q / 2) / Q) & 0b1111;
+ }
+ r[rr++] = t[0] | (t[1] << 4);
+ r[rr++] = t[2] | (t[3] << 4);
+ r[rr++] = t[4] | (t[5] << 4);
+ r[rr++] = t[6] | (t[7] << 4);
+ }
+ return r;
+ }
+ // decompressU de-serializes and decompresses a vector of polynomials and
+ // represents the approximate inverse of compress1. Since compression is lossy,
+ // the results of decompression will may not match the original vector of polynomials.
+ /**
+ * Decompresses a Uint8Array into a two-dimensional array of numbers.
+ *
+ * @param a The Uint8Array to decompress.
+ * @returns The decompressed two-dimensional array.
+ */
+ _decompressU(a) {
+ const r = new Array(this._k);
+ for (let i = 0; i < this._k; i++) {
+ r[i] = new Array(384);
+ }
+ const t = new Array(4);
+ for (let aa = 0, i = 0; i < this._k; i++) {
+ for (let j = 0; j < N / 4; j++) {
+ t[0] = (uint16(a[aa + 0]) >> 0) | (uint16(a[aa + 1]) << 8);
+ t[1] = (uint16(a[aa + 1]) >> 2) | (uint16(a[aa + 2]) << 6);
+ t[2] = (uint16(a[aa + 2]) >> 4) | (uint16(a[aa + 3]) << 4);
+ t[3] = (uint16(a[aa + 3]) >> 6) | (uint16(a[aa + 4]) << 2);
+ aa = aa + 5;
+ for (let k = 0; k < 4; k++) {
+ r[i][4 * j + k] = int16((((uint32(t[k] & 0x3FF)) * (uint32(Q))) + 512) >> 10);
+ }
+ }
+ }
+ return r;
+ }
+ // decompressV de-serializes and subsequently decompresses a polynomial,
+ // representing the approximate inverse of compress2.
+ // Note that compression is lossy, and thus decompression will not match the
+ // original input.
+ /**
+ * Decompresses a Uint8Array into an array of numbers.
+ *
+ * @param a - The Uint8Array to decompress.
+ * @returns An array of numbers.
+ */
+ _decompressV(a) {
+ const r = new Array(384);
+ for (let aa = 0, i = 0; i < N / 2; i++, aa++) {
+ r[2 * i + 0] = int16(((uint16(a[aa] & 15) * uint16(Q)) + 8) >> 4);
+ r[2 * i + 1] = int16(((uint16(a[aa] >> 4) * uint16(Q)) + 8) >> 4);
+ }
+ return r;
+ }
+}
+/**
+ * Computes the hash of the input array `a` and an optional input array `b`.
+ * Returns an array containing two Uint8Arrays, representing the first 32 bytes and the next 32 bytes of the hash digest.
+ * @param a - The input array to be hashed.
+ * @param b - An optional input array to be hashed along with `a`.
+ * @returns An array containing two Uint8Arrays representing the hash digest.
+ */
+function g(a, b) {
+ const hash = sha3_512.create().update(a);
+ if (b !== undefined) {
+ hash.update(b);
+ }
+ const res = hash.digest();
+ return [res.subarray(0, 32), res.subarray(32, 64)];
+}
+/**
+ * Computes the SHA3-256 hash of the given message.
+ *
+ * @param msg - The input message as a Uint8Array.
+ * @returns The computed hash as a Uint8Array.
+ */
+function h(msg) {
+ return sha3_256.create().update(msg).digest();
+}
+/**
+ * Key Derivation Function (KDF) that takes an input array `a` and an optional input array `b`.
+ * It uses the SHAKE256 hash function to derive a 32-byte output.
+ *
+ * @param a - The input array.
+ * @param b - The optional input array.
+ * @returns The derived key as a Uint8Array.
+ */
+function kdf(a, b) {
+ const hash = shake256.create({ dkLen: 32 }).update(a);
+ if (b !== undefined) {
+ hash.update(b);
+ }
+ return hash.digest();
+}
+/**
+ * Computes the extendable-output function (XOF) using the SHAKE128 algorithm.
+ *
+ * @param seed - The seed value for the XOF.
+ * @param transpose - The transpose value for the XOF.
+ * @returns The computed XOF value as a Uint8Array.
+ */
+function xof(seed, transpose) {
+ return shake128.create({ dkLen: 672 }).update(seed).update(transpose)
+ .digest();
+}
+// polyToBytes serializes a polynomial into an array of bytes.
+/**
+ * Converts a polynomial represented by an array of numbers to a Uint8Array.
+ * Each coefficient of the polynomial is reduced modulo q.
+ *
+ * @param a - The array representing the polynomial.
+ * @returns The Uint8Array representation of the polynomial.
+ */
+function polyToBytes(a) {
+ let t0 = 0;
+ let t1 = 0;
+ const r = new Uint8Array(384);
+ const a2 = subtractQ(a); // Returns: a - q if a >= q, else a (each coefficient of the polynomial)
+ // for 0-127
+ for (let i = 0; i < N / 2; i++) {
+ // get two coefficient entries in the polynomial
+ t0 = uint16(a2[2 * i]);
+ t1 = uint16(a2[2 * i + 1]);
+ // convert the 2 coefficient into 3 bytes
+ r[3 * i + 0] = byte(t0 >> 0); // byte() does mod 256 of the input (output value 0-255)
+ r[3 * i + 1] = byte(t0 >> 8) | byte(t1 << 4);
+ r[3 * i + 2] = byte(t1 >> 4);
+ }
+ return r;
+}
+// polyFromBytes de-serialises an array of bytes into a polynomial,
+// and represents the inverse of polyToBytes.
+/**
+ * Converts a Uint8Array to an array of numbers representing a polynomial.
+ * Each element in the array represents a coefficient of the polynomial.
+ * The input array `a` should have a length of 384.
+ * The function performs bitwise operations to extract the coefficients from the input array.
+ * @param a The Uint8Array to convert to a polynomial.
+ * @returns An array of numbers representing the polynomial.
+ */
+function polyFromBytes(a) {
+ const r = new Array(384).fill(0);
+ for (let i = 0; i < N / 2; i++) {
+ r[2 * i] = int16(((uint16(a[3 * i + 0]) >> 0) | (uint16(a[3 * i + 1]) << 8)) & 0xFFF);
+ r[2 * i + 1] = int16(((uint16(a[3 * i + 1]) >> 4) | (uint16(a[3 * i + 2]) << 4)) & 0xFFF);
+ }
+ return r;
+}
+// polyToMsg converts a polynomial to a 32-byte message
+// and represents the inverse of polyFromMsg.
+/**
+ * Converts a polynomial to a message represented as a Uint8Array.
+ * @param a - The polynomial to convert.
+ * @returns The message as a Uint8Array.
+ */
+function polyToMsg(a) {
+ const msg = new Uint8Array(32);
+ let t;
+ const a2 = subtractQ(a);
+ for (let i = 0; i < N / 8; i++) {
+ msg[i] = 0;
+ for (let j = 0; j < 8; j++) {
+ t = (((uint16(a2[8 * i + j]) << 1) + uint16(Q / 2)) /
+ uint16(Q)) & 1;
+ msg[i] |= byte(t << j);
+ }
+ }
+ return msg;
+}
+// polyFromMsg converts a 32-byte message to a polynomial.
+/**
+ * Converts a Uint8Array message to an array of numbers representing a polynomial.
+ * Each element in the array is an int16 (0-65535).
+ *
+ * @param msg - The Uint8Array message to convert.
+ * @returns An array of numbers representing the polynomial.
+ */
+function polyFromMsg(msg) {
+ const r = new Array(384).fill(0); // each element is int16 (0-65535)
+ let mask; // int16
+ for (let i = 0; i < N / 8; i++) {
+ for (let j = 0; j < 8; j++) {
+ mask = -1 * int16((msg[i] >> j) & 1);
+ r[8 * i + j] = mask & int16((Q + 1) / 2);
+ }
+ }
+ return r;
+}
+// indcpaRejUniform runs rejection sampling on uniform random bytes
+// to generate uniform random integers modulo `Q`.
+/**
+ * Generates an array of random numbers from a given buffer, rejecting values greater than a specified threshold.
+ *
+ * @param buf - The input buffer containing random bytes.
+ * @param bufl - The length of the input buffer.
+ * @param len - The desired length of the output array.
+ * @returns An array of random numbers and the actual length of the output array.
+ */
+function indcpaRejUniform(buf, bufl, len) {
+ const r = new Array(384).fill(0);
+ let ctr = 0;
+ let val0, val1; // d1, d2 in kyber documentation
+ for (let pos = 0; ctr < len && pos + 3 <= bufl;) {
+ // compute d1 and d2
+ val0 = (uint16((buf[pos]) >> 0) | (uint16(buf[pos + 1]) << 8)) & 0xFFF;
+ val1 = (uint16((buf[pos + 1]) >> 4) | (uint16(buf[pos + 2]) << 4)) & 0xFFF;
+ // increment input buffer index by 3
+ pos = pos + 3;
+ // if d1 is less than 3329
+ if (val0 < Q) {
+ // assign to d1
+ r[ctr] = val0;
+ // increment position of output array
+ ctr = ctr + 1;
+ }
+ if (ctr < len && val1 < Q) {
+ r[ctr] = val1;
+ ctr = ctr + 1;
+ }
+ }
+ return [r, ctr];
+}
+// byteopsCbd computes a polynomial with coefficients distributed
+// according to a centered binomial distribution with parameter PARAMS_ETA,
+// given an array of uniformly random bytes.
+/**
+ * Converts a Uint8Array buffer to an array of numbers using the CBD operation.
+ * @param buf - The input Uint8Array buffer.
+ * @param eta - The value used in the CBD operation.
+ * @returns An array of numbers obtained from the CBD operation.
+ */
+function byteopsCbd(buf, eta) {
+ let t, d;
+ let a, b;
+ const r = new Array(384).fill(0);
+ for (let i = 0; i < N / 8; i++) {
+ t = byteopsLoad32(buf.subarray(4 * i, buf.length));
+ d = t & 0x55555555;
+ d = d + ((t >> 1) & 0x55555555);
+ for (let j = 0; j < 8; j++) {
+ a = int16((d >> (4 * j + 0)) & 0x3);
+ b = int16((d >> (4 * j + eta)) & 0x3);
+ r[8 * i + j] = a - b;
+ }
+ }
+ return r;
+}
+// ntt performs an inplace number-theoretic transform (NTT) in `Rq`.
+// The input is in standard order, the output is in bit-reversed order.
+/**
+ * Performs the Number Theoretic Transform (NTT) on an array of numbers.
+ *
+ * @param r - The input array of numbers.
+ * @returns The transformed array of numbers.
+ */
+function ntt(r) {
+ // 128, 64, 32, 16, 8, 4, 2
+ for (let j = 0, k = 1, l = 128; l >= 2; l >>= 1) {
+ // 0,
+ for (let start = 0; start < 256; start = j + l) {
+ const zeta = NTT_ZETAS[k];
+ k = k + 1;
+ // for each element in the subsections (128, 64, 32, 16, 8, 4, 2) starting at an offset
+ for (j = start; j < start + l; j++) {
+ // compute the modular multiplication of the zeta and each element in the subsection
+ const t = nttFqMul(zeta, r[j + l]); // t is mod q
+ // overwrite each element in the subsection as the opposite subsection element minus t
+ r[j + l] = r[j] - t;
+ // add t back again to the opposite subsection
+ r[j] = r[j] + t;
+ }
+ }
+ }
+ return r;
+}
+// nttFqMul performs multiplication followed by Montgomery reduction
+// and returns a 16-bit integer congruent to `a*b*R^{-1} mod Q`.
+/**
+ * Performs an NTT (Number Theoretic Transform) multiplication on two numbers in Fq.
+ * @param a The first number.
+ * @param b The second number.
+ * @returns The result of the NTT multiplication.
+ */
+function nttFqMul(a, b) {
+ return byteopsMontgomeryReduce(a * b);
+}
+// reduce applies Barrett reduction to all coefficients of a polynomial.
+/**
+ * Reduces each element in the given array using the barrett function.
+ *
+ * @param r - The array to be reduced.
+ * @returns The reduced array.
+ */
+function reduce(r) {
+ for (let i = 0; i < N; i++) {
+ r[i] = barrett(r[i]);
+ }
+ return r;
+}
+// barrett computes a Barrett reduction; given
+// a integer `a`, returns a integer congruent to
+// `a mod Q` in {0,...,Q}.
+/**
+ * Performs the Barrett reduction algorithm on the given number.
+ *
+ * @param a - The number to be reduced.
+ * @returns The result of the reduction.
+ */
+function barrett(a) {
+ const v = ((1 << 24) + Q / 2) / Q;
+ let t = v * a >> 24;
+ t = t * Q;
+ return a - t;
+}
+// byteopsMontgomeryReduce computes a Montgomery reduction; given
+// a 32-bit integer `a`, returns `a * R^-1 mod Q` where `R=2^16`.
+/**
+ * Performs Montgomery reduction on a given number.
+ * @param a - The number to be reduced.
+ * @returns The reduced number.
+ */
+function byteopsMontgomeryReduce(a) {
+ const u = int16(int32(a) * Q_INV);
+ let t = u * Q;
+ t = a - t;
+ t >>= 16;
+ return int16(t);
+}
+// polyToMont performs the in-place conversion of all coefficients
+// of a polynomial from the normal domain to the Montgomery domain.
+/**
+ * Converts a polynomial to the Montgomery domain.
+ *
+ * @param r - The polynomial to be converted.
+ * @returns The polynomial in the Montgomery domain.
+ */
+function polyToMont(r) {
+ // let f = int16(((uint64(1) << 32)) % uint64(Q));
+ const f = 1353; // if Q changes then this needs to be updated
+ for (let i = 0; i < N; i++) {
+ r[i] = byteopsMontgomeryReduce(int32(r[i]) * int32(f));
+ }
+ return r;
+}
+// pointwise-multiplies elements of polynomial-vectors
+// `a` and `b`, accumulates the results into `r`, and then multiplies by `2^-16`.
+/**
+ * Multiplies two matrices element-wise and returns the result.
+ * @param a - The first matrix.
+ * @param b - The second matrix.
+ * @returns The resulting matrix after element-wise multiplication.
+ */
+function multiply(a, b) {
+ let r = polyBaseMulMontgomery(a[0], b[0]);
+ let t;
+ for (let i = 1; i < a.length; i++) {
+ t = polyBaseMulMontgomery(a[i], b[i]);
+ r = add(r, t);
+ }
+ return reduce(r);
+}
+// polyBaseMulMontgomery performs the multiplication of two polynomials
+// in the number-theoretic transform (NTT) domain.
+/**
+ * Performs polynomial base multiplication in Montgomery domain.
+ * @param a - The first polynomial array.
+ * @param b - The second polynomial array.
+ * @returns The result of the polynomial base multiplication.
+ */
+function polyBaseMulMontgomery(a, b) {
+ let rx, ry;
+ for (let i = 0; i < N / 4; i++) {
+ rx = nttBaseMul(a[4 * i + 0], a[4 * i + 1], b[4 * i + 0], b[4 * i + 1], NTT_ZETAS[64 + i]);
+ ry = nttBaseMul(a[4 * i + 2], a[4 * i + 3], b[4 * i + 2], b[4 * i + 3], -NTT_ZETAS[64 + i]);
+ a[4 * i + 0] = rx[0];
+ a[4 * i + 1] = rx[1];
+ a[4 * i + 2] = ry[0];
+ a[4 * i + 3] = ry[1];
+ }
+ return a;
+}
+// nttBaseMul performs the multiplication of polynomials
+// in `Zq[X]/(X^2-zeta)`. Used for multiplication of elements
+// in `Rq` in the number-theoretic transformation domain.
+/**
+ * Performs NTT base multiplication.
+ *
+ * @param a0 - The first coefficient of the first polynomial.
+ * @param a1 - The second coefficient of the first polynomial.
+ * @param b0 - The first coefficient of the second polynomial.
+ * @param b1 - The second coefficient of the second polynomial.
+ * @param zeta - The zeta value used in the multiplication.
+ * @returns An array containing the result of the multiplication.
+ */
+function nttBaseMul(a0, a1, b0, b1, zeta) {
+ const r = new Array(2);
+ r[0] = nttFqMul(a1, b1);
+ r[0] = nttFqMul(r[0], zeta);
+ r[0] += nttFqMul(a0, b0);
+ r[1] = nttFqMul(a0, b1);
+ r[1] += nttFqMul(a1, b0);
+ return r;
+}
+// adds two polynomials.
+/**
+ * Adds two arrays element-wise.
+ * @param a - The first array.
+ * @param b - The second array.
+ * @returns The resulting array after element-wise addition.
+ */
+function add(a, b) {
+ const c = new Array(384);
+ for (let i = 0; i < N; i++) {
+ c[i] = a[i] + b[i];
+ }
+ return c;
+}
+// subtracts two polynomials.
+/**
+ * Subtracts the elements of array b from array a.
+ *
+ * @param a - The array from which to subtract.
+ * @param b - The array to subtract.
+ * @returns The resulting array after subtraction.
+ */
+function subtract(a, b) {
+ for (let i = 0; i < N; i++) {
+ a[i] -= b[i];
+ }
+ return a;
+}
+// nttInverse performs an inplace inverse number-theoretic transform (NTT)
+// in `Rq` and multiplication by Montgomery factor 2^16.
+// The input is in bit-reversed order, the output is in standard order.
+/**
+ * Performs the inverse Number Theoretic Transform (NTT) on the given array.
+ *
+ * @param r - The input array to perform the inverse NTT on.
+ * @returns The array after performing the inverse NTT.
+ */
+function nttInverse(r) {
+ let j = 0;
+ for (let k = 0, l = 2; l <= 128; l <<= 1) {
+ for (let start = 0; start < 256; start = j + l) {
+ const zeta = NTT_ZETAS_INV[k];
+ k = k + 1;
+ for (j = start; j < start + l; j++) {
+ const t = r[j];
+ r[j] = barrett(t + r[j + l]);
+ r[j + l] = t - r[j + l];
+ r[j + l] = nttFqMul(zeta, r[j + l]);
+ }
+ }
+ }
+ for (j = 0; j < 256; j++) {
+ r[j] = nttFqMul(r[j], NTT_ZETAS_INV[127]);
+ }
+ return r;
+}
+// subtractQ applies the conditional subtraction of q to each coefficient of a polynomial.
+// if a is 3329 then convert to 0
+// Returns: a - q if a >= q, else a
+/**
+ * Subtracts the value of Q from each element in the given array.
+ * The result should be a negative integer for each element.
+ * If the leftmost bit is 0 (positive number), the value of Q is added back.
+ *
+ * @param r - The array to subtract Q from.
+ * @returns The resulting array after the subtraction.
+ */
+function subtractQ(r) {
+ for (let i = 0; i < N; i++) {
+ r[i] -= Q; // should result in a negative integer
+ // push left most signed bit to right most position
+ // javascript does bitwise operations in signed 32 bit
+ // add q back again if left most bit was 0 (positive number)
+ r[i] += (r[i] >> 31) & Q;
+ }
+ return r;
+}
diff --git a/npm/esm/src/utils.d.ts b/npm/esm/src/utils.d.ts
new file mode 100644
index 0000000..7d54737
--- /dev/null
+++ b/npm/esm/src/utils.d.ts
@@ -0,0 +1,15 @@
+export declare function byte(n: number): number;
+export declare function int16(n: number): number;
+export declare function uint16(n: number): number;
+export declare function int32(n: number): number;
+export declare function uint32(n: number): number;
+/**
+ * compares two arrays
+ * @returns 1 if they are the same or 0 if not
+ */
+export declare function constantTimeCompare(x: Uint8Array, y: Uint8Array): number;
+export declare function equalUint8Array(x: Uint8Array, y: Uint8Array): boolean;
+export declare function loadCrypto(): Promise;
+export declare function prf(len: number, seed: Uint8Array, nonce: number): Uint8Array;
+export declare function byteopsLoad24(x: Uint8Array): number;
+export declare function byteopsLoad32(x: Uint8Array): number;
diff --git a/npm/esm/src/utils.js b/npm/esm/src/utils.js
new file mode 100644
index 0000000..ddb2343
--- /dev/null
+++ b/npm/esm/src/utils.js
@@ -0,0 +1,113 @@
+import * as dntShim from "../_dnt.shims.js";
+import { shake256 } from "./deps.js";
+export function byte(n) {
+ return n % 256;
+}
+export function int16(n) {
+ const end = -32768;
+ const start = 32767;
+ if (n >= end && n <= start) {
+ return n;
+ }
+ if (n < end) {
+ n = n + 32769;
+ n = n % 65536;
+ return start + n;
+ }
+ // if (n > start) {
+ n = n - 32768;
+ n = n % 65536;
+ return end + n;
+}
+export function uint16(n) {
+ return n % 65536;
+}
+export function int32(n) {
+ const end = -2147483648;
+ const start = 2147483647;
+ if (n >= end && n <= start) {
+ return n;
+ }
+ if (n < end) {
+ n = n + 2147483649;
+ n = n % 4294967296;
+ return start + n;
+ }
+ // if (n > start) {
+ n = n - 2147483648;
+ n = n % 4294967296;
+ return end + n;
+}
+// any bit operations to be done in uint32 must have >>> 0
+// javascript calculates bitwise in SIGNED 32 bit so you need to convert
+export function uint32(n) {
+ return n % 4294967296;
+}
+/**
+ * compares two arrays
+ * @returns 1 if they are the same or 0 if not
+ */
+export function constantTimeCompare(x, y) {
+ // check array lengths
+ if (x.length != y.length) {
+ return 0;
+ }
+ const v = new Uint8Array([0]);
+ for (let i = 0; i < x.length; i++) {
+ v[0] |= x[i] ^ y[i];
+ }
+ // constantTimeByteEq
+ const z = new Uint8Array([0]);
+ z[0] = ~(v[0] ^ z[0]);
+ z[0] &= z[0] >> 4;
+ z[0] &= z[0] >> 2;
+ z[0] &= z[0] >> 1;
+ return z[0];
+}
+export function equalUint8Array(x, y) {
+ if (x.length != y.length) {
+ return false;
+ }
+ for (let i = 0; i < x.length; i++) {
+ if (x[i] !== y[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+export async function loadCrypto() {
+ if (dntShim.dntGlobalThis !== undefined && globalThis.crypto !== undefined) {
+ // Browsers, Node.js >= v19, Cloudflare Workers, Bun, etc.
+ return globalThis.crypto;
+ }
+ // Node.js <= v18
+ try {
+ // @ts-ignore: to ignore "crypto"
+ const { webcrypto } = await import("crypto"); // node:crypto
+ return webcrypto;
+ }
+ catch (_e) {
+ throw new Error("failed to load Crypto");
+ }
+}
+// prf provides a pseudo-random function (PRF) which returns
+// a byte array of length `l`, using the provided key and nonce
+// to instantiate the PRF's underlying hash function.
+export function prf(len, seed, nonce) {
+ return shake256.create({ dkLen: len }).update(seed).update(new Uint8Array([nonce])).digest();
+}
+// byteopsLoad24 returns a 32-bit unsigned integer loaded from byte x.
+export function byteopsLoad24(x) {
+ let r = uint32(x[0]);
+ r |= uint32(x[1]) << 8;
+ r |= uint32(x[2]) << 16;
+ return r;
+}
+// byteopsLoad32 returns a 32-bit unsigned integer loaded from byte x.
+export function byteopsLoad32(x) {
+ let r = uint32(x[0]);
+ r |= uint32(x[1]) << 8;
+ r |= uint32(x[2]) << 16;
+ r |= uint32(x[3]) << 24;
+ return uint32(r);
+}
diff --git a/npm/esm/test/kyber.test.d.ts b/npm/esm/test/kyber.test.d.ts
new file mode 100644
index 0000000..cb0ff5c
--- /dev/null
+++ b/npm/esm/test/kyber.test.d.ts
@@ -0,0 +1 @@
+export {};
diff --git a/npm/esm/test/kyber.test.js b/npm/esm/test/kyber.test.js
new file mode 100644
index 0000000..7188a3e
--- /dev/null
+++ b/npm/esm/test/kyber.test.js
@@ -0,0 +1,61 @@
+import * as dntShim from "../_dnt.test_shims.js";
+import { describe, it } from "../deps/deno.land/std@0.213.0/testing/bdd.js";
+import { assertEquals, assertRejects, } from "../deps/deno.land/std@0.216.0/assert/mod.js";
+import { MlKem1024, MlKem512, MlKem768, MlKemError } from "../mod.js";
+import { loadCrypto } from "../src/utils.js";
+import { parseKAT, testVectorPath } from "./utils.js";
+import { hexToBytes } from "./utils.js";
+[MlKem512, MlKem768, MlKem1024].forEach((KyberClass) => describe(KyberClass.name, () => {
+ const size = KyberClass.name.substring(5);
+ describe("KAT vectors", () => {
+ it("should match expected values", async () => {
+ const kyber = new KyberClass();
+ const katData = await dntShim.Deno.readTextFile(`${testVectorPath()}/kat/kat_MLKEM_${size}.rsp`);
+ const { ct, sk, ss } = parseKAT(katData);
+ console.log(`test vector count: ${sk.length}`);
+ for (let i = 0; i < sk.length; i++) {
+ const res = await kyber.decap(ct[i], sk[i]);
+ assertEquals(res, ss[i]);
+ }
+ });
+ });
+ describe("A sample code in README.", () => {
+ it("should work normally", async () => {
+ const recipient = new KyberClass();
+ const [pkR, skR] = await recipient.generateKeyPair();
+ const sender = new KyberClass();
+ const [ct, ssS] = await sender.encap(pkR);
+ const ssR = await recipient.decap(ct, skR);
+ assertEquals(ssS, ssR);
+ });
+ it("should work normally with deriveKeyPair", async () => {
+ const recipient = new KyberClass();
+ const api = await loadCrypto();
+ const seed = new Uint8Array(64);
+ api.getRandomValues(seed);
+ const [pkR, skR] = await recipient.deriveKeyPair(seed);
+ const [pkR2, skR2] = await recipient.deriveKeyPair(seed);
+ assertEquals(pkR, pkR2);
+ assertEquals(skR, skR2);
+ const sender = new KyberClass();
+ const [ct, ssS] = await sender.encap(pkR);
+ const ssR = await recipient.decap(ct, skR);
+ assertEquals(ssS, ssR);
+ });
+ });
+ describe("Advanced testing", () => {
+ it("Invalid encapsulation keys", async () => {
+ const sender = new KyberClass();
+ const testData = await dntShim.Deno.readTextFile(`${testVectorPath()}/modulus/ML-KEM-${size}.txt`);
+ const invalidPk = hexToBytes(testData);
+ await assertRejects(() => sender.encap(invalidPk), MlKemError, "invalid encapsulation key");
+ });
+ it("'Unlucky' vectors that require an unusually large number of XOF reads", async () => {
+ const kyber = new KyberClass();
+ const testData = await dntShim.Deno.readTextFile(`${testVectorPath()}/unluckysample/ML-KEM-${size}.txt`);
+ const { c: [ct], dk: [sk], K: [ss] } = parseKAT(testData);
+ const res = await kyber.decap(ct, sk);
+ assertEquals(res, ss);
+ });
+ });
+}));
diff --git a/npm/esm/test/utils.d.ts b/npm/esm/test/utils.d.ts
new file mode 100644
index 0000000..8368240
--- /dev/null
+++ b/npm/esm/test/utils.d.ts
@@ -0,0 +1,7 @@
+export declare function testVectorPath(): string;
+export declare function hexToBytes(v: string): Uint8Array;
+export declare function bytesToHex(v: Uint8Array): string;
+export declare function hexToDec(hexString: string): number;
+export declare function parseKAT(data: string): {
+ [label: string]: Uint8Array[];
+};
diff --git a/npm/esm/test/utils.js b/npm/esm/test/utils.js
new file mode 100644
index 0000000..7a2031d
--- /dev/null
+++ b/npm/esm/test/utils.js
@@ -0,0 +1,42 @@
+const isDeno = () => typeof Deno !== "undefined";
+export function testVectorPath() {
+ if (isDeno()) {
+ return "./test/vectors";
+ }
+ return "../../test/vectors";
+}
+export function hexToBytes(v) {
+ if (v.length === 0) {
+ return new Uint8Array([]);
+ }
+ const res = v.match(/[\da-f]{2}/gi);
+ if (res == null) {
+ throw new Error("Not hex string.");
+ }
+ return new Uint8Array(res.map(function (h) {
+ return parseInt(h, 16);
+ }));
+}
+export function bytesToHex(v) {
+ return [...v].map((x) => x.toString(16).padStart(2, "0")).join("");
+}
+export function hexToDec(hexString) {
+ return parseInt(hexString, 16);
+}
+export function parseKAT(data) {
+ const textByLine = data.trim().split("\n");
+ const parsed = {};
+ for (let i = 0; i < textByLine.length; i++) {
+ const [label, hexValue] = textByLine[i].split(" = ");
+ if (label === "count")
+ continue;
+ const value = hexToBytes(hexValue);
+ if (parsed[label]) {
+ parsed[label].push(value);
+ }
+ else {
+ parsed[label] = [value];
+ }
+ }
+ return parsed;
+}
diff --git a/npm/package-lock.json b/npm/package-lock.json
new file mode 100644
index 0000000..0a441cf
--- /dev/null
+++ b/npm/package-lock.json
@@ -0,0 +1,183 @@
+{
+ "name": "crystals-kyber-js",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "crystals-kyber-js",
+ "license": "MIT",
+ "dependencies": {
+ "@openpgp/noble-hashes": "1.3.3"
+ },
+ "devDependencies": {
+ "@deno/shim-deno": "~0.17.0",
+ "@types/node": "^20.9.0",
+ "picocolors": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/@deno/shim-deno": {
+ "version": "0.17.0",
+ "resolved": "https://registry.npmjs.org/@deno/shim-deno/-/shim-deno-0.17.0.tgz",
+ "integrity": "sha512-+FzsP65eehAgTQdzt1izLEV17ePCZqHxDQqRDbpRc1yJVYtDI2MvbRq5DvOj90uRt6zKn9qtWpEueDqG1QORhQ==",
+ "dev": true,
+ "dependencies": {
+ "@deno/shim-deno-test": "^0.5.0",
+ "which": "^4.0.0"
+ }
+ },
+ "node_modules/@deno/shim-deno-test": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/@deno/shim-deno-test/-/shim-deno-test-0.5.0.tgz",
+ "integrity": "sha512-4nMhecpGlPi0cSzT67L+Tm+GOJqvuk8gqHBziqcUQOarnuIax1z96/gJHCSIz2Z0zhxE6Rzwb3IZXPtFh51j+w==",
+ "dev": true
+ },
+ "node_modules/@openpgp/noble-hashes": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@openpgp/noble-hashes/-/noble-hashes-1.3.3.tgz",
+ "integrity": "sha512-CPDNePrQTQrL5Fxd/K3B53Gty4xbNVxnMSUdDmYjW5tTpRqOlme0INYTnnQqoE/XUdIlq5fByOMDuDWR5JpXZw==",
+ "dependencies": {
+ "@types/bn.js": "^4.11.6",
+ "bn.js": "^4.11.8"
+ },
+ "engines": {
+ "node": ">= 16"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/@types/bn.js": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz",
+ "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/node": {
+ "version": "20.11.20",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.20.tgz",
+ "integrity": "sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==",
+ "dependencies": {
+ "undici-types": "~5.26.4"
+ }
+ },
+ "node_modules/bn.js": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
+ },
+ "node_modules/isexe": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz",
+ "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "dev": true
+ },
+ "node_modules/undici-types": {
+ "version": "5.26.5",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
+ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
+ },
+ "node_modules/which": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz",
+ "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^3.1.1"
+ },
+ "bin": {
+ "node-which": "bin/which.js"
+ },
+ "engines": {
+ "node": "^16.13.0 || >=18.0.0"
+ }
+ }
+ },
+ "dependencies": {
+ "@deno/shim-deno": {
+ "version": "0.17.0",
+ "resolved": "https://registry.npmjs.org/@deno/shim-deno/-/shim-deno-0.17.0.tgz",
+ "integrity": "sha512-+FzsP65eehAgTQdzt1izLEV17ePCZqHxDQqRDbpRc1yJVYtDI2MvbRq5DvOj90uRt6zKn9qtWpEueDqG1QORhQ==",
+ "dev": true,
+ "requires": {
+ "@deno/shim-deno-test": "^0.5.0",
+ "which": "^4.0.0"
+ }
+ },
+ "@deno/shim-deno-test": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/@deno/shim-deno-test/-/shim-deno-test-0.5.0.tgz",
+ "integrity": "sha512-4nMhecpGlPi0cSzT67L+Tm+GOJqvuk8gqHBziqcUQOarnuIax1z96/gJHCSIz2Z0zhxE6Rzwb3IZXPtFh51j+w==",
+ "dev": true
+ },
+ "@openpgp/noble-hashes": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@openpgp/noble-hashes/-/noble-hashes-1.3.3.tgz",
+ "integrity": "sha512-CPDNePrQTQrL5Fxd/K3B53Gty4xbNVxnMSUdDmYjW5tTpRqOlme0INYTnnQqoE/XUdIlq5fByOMDuDWR5JpXZw==",
+ "requires": {
+ "@types/bn.js": "^4.11.6",
+ "bn.js": "^4.11.8"
+ }
+ },
+ "@types/bn.js": {
+ "version": "4.11.6",
+ "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz",
+ "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==",
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/node": {
+ "version": "20.11.20",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.20.tgz",
+ "integrity": "sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==",
+ "requires": {
+ "undici-types": "~5.26.4"
+ }
+ },
+ "bn.js": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA=="
+ },
+ "isexe": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz",
+ "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==",
+ "dev": true
+ },
+ "picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "dev": true
+ },
+ "undici-types": {
+ "version": "5.26.5",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
+ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
+ },
+ "which": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz",
+ "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==",
+ "dev": true,
+ "requires": {
+ "isexe": "^3.1.1"
+ }
+ }
+ }
+}
diff --git a/npm/package.json b/npm/package.json
new file mode 100644
index 0000000..0b29f10
--- /dev/null
+++ b/npm/package.json
@@ -0,0 +1,47 @@
+{
+ "name": "crystals-kyber-js",
+ "description": "A CRYSTALS-KYBER implementation written in TypeScript for various JavaScript runtimes",
+ "keywords": [
+ "crystals-kyber",
+ "kyber",
+ "kem",
+ "security",
+ "encryption",
+ "pqc",
+ "post-quantum"
+ ],
+ "author": "Ajitomi Daisuke",
+ "homepage": "https://github.com/dajiaji/crystals-kyber-js#readme",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/dajiaji/crystals-kyber-js.git"
+ },
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/dajiaji/crystals-kyber-js/issues"
+ },
+ "main": "./script/mod.js",
+ "module": "./esm/mod.js",
+ "types": "./esm/mod.d.ts",
+ "exports": {
+ ".": {
+ "import": "./esm/mod.js"
+ }
+ },
+ "scripts": {
+ "test": "node test_runner.js"
+ },
+ "sideEffects": false,
+ "engines": {
+ "node": ">=16.0.0"
+ },
+ "dependencies": {
+ "@openpgp/noble-hashes": "1.3.3"
+ },
+ "devDependencies": {
+ "@types/node": "^20.9.0",
+ "picocolors": "^1.0.0",
+ "@deno/shim-deno": "~0.17.0"
+ },
+ "_generatedBy": "dnt@0.39.0"
+}
\ No newline at end of file
diff --git a/npm/src/_dnt.shims.ts b/npm/src/_dnt.shims.ts
new file mode 100644
index 0000000..21614f4
--- /dev/null
+++ b/npm/src/_dnt.shims.ts
@@ -0,0 +1,60 @@
+const dntGlobals = {
+};
+export const dntGlobalThis = createMergeProxy(globalThis, dntGlobals);
+
+function createMergeProxy(
+ baseObj: T,
+ extObj: U,
+): Omit & U {
+ return new Proxy(baseObj, {
+ get(_target, prop, _receiver) {
+ if (prop in extObj) {
+ return (extObj as any)[prop];
+ } else {
+ return (baseObj as any)[prop];
+ }
+ },
+ set(_target, prop, value) {
+ if (prop in extObj) {
+ delete (extObj as any)[prop];
+ }
+ (baseObj as any)[prop] = value;
+ return true;
+ },
+ deleteProperty(_target, prop) {
+ let success = false;
+ if (prop in extObj) {
+ delete (extObj as any)[prop];
+ success = true;
+ }
+ if (prop in baseObj) {
+ delete (baseObj as any)[prop];
+ success = true;
+ }
+ return success;
+ },
+ ownKeys(_target) {
+ const baseKeys = Reflect.ownKeys(baseObj);
+ const extKeys = Reflect.ownKeys(extObj);
+ const extKeysSet = new Set(extKeys);
+ return [...baseKeys.filter((k) => !extKeysSet.has(k)), ...extKeys];
+ },
+ defineProperty(_target, prop, desc) {
+ if (prop in extObj) {
+ delete (extObj as any)[prop];
+ }
+ Reflect.defineProperty(baseObj, prop, desc);
+ return true;
+ },
+ getOwnPropertyDescriptor(_target, prop) {
+ if (prop in extObj) {
+ return Reflect.getOwnPropertyDescriptor(extObj, prop);
+ } else {
+ return Reflect.getOwnPropertyDescriptor(baseObj, prop);
+ }
+ },
+ has(_target, prop) {
+ return prop in extObj || prop in baseObj;
+ },
+ }) as any;
+}
diff --git a/npm/src/_dnt.test_shims.ts b/npm/src/_dnt.test_shims.ts
new file mode 100644
index 0000000..4f4afe5
--- /dev/null
+++ b/npm/src/_dnt.test_shims.ts
@@ -0,0 +1,64 @@
+import { Deno } from "@deno/shim-deno";
+export { Deno } from "@deno/shim-deno";
+
+const dntGlobals = {
+ Deno,
+};
+export const dntGlobalThis = createMergeProxy(globalThis, dntGlobals);
+
+function createMergeProxy(
+ baseObj: T,
+ extObj: U,
+): Omit & U {
+ return new Proxy(baseObj, {
+ get(_target, prop, _receiver) {
+ if (prop in extObj) {
+ return (extObj as any)[prop];
+ } else {
+ return (baseObj as any)[prop];
+ }
+ },
+ set(_target, prop, value) {
+ if (prop in extObj) {
+ delete (extObj as any)[prop];
+ }
+ (baseObj as any)[prop] = value;
+ return true;
+ },
+ deleteProperty(_target, prop) {
+ let success = false;
+ if (prop in extObj) {
+ delete (extObj as any)[prop];
+ success = true;
+ }
+ if (prop in baseObj) {
+ delete (baseObj as any)[prop];
+ success = true;
+ }
+ return success;
+ },
+ ownKeys(_target) {
+ const baseKeys = Reflect.ownKeys(baseObj);
+ const extKeys = Reflect.ownKeys(extObj);
+ const extKeysSet = new Set(extKeys);
+ return [...baseKeys.filter((k) => !extKeysSet.has(k)), ...extKeys];
+ },
+ defineProperty(_target, prop, desc) {
+ if (prop in extObj) {
+ delete (extObj as any)[prop];
+ }
+ Reflect.defineProperty(baseObj, prop, desc);
+ return true;
+ },
+ getOwnPropertyDescriptor(_target, prop) {
+ if (prop in extObj) {
+ return Reflect.getOwnPropertyDescriptor(extObj, prop);
+ } else {
+ return Reflect.getOwnPropertyDescriptor(baseObj, prop);
+ }
+ },
+ has(_target, prop) {
+ return prop in extObj || prop in baseObj;
+ },
+ }) as any;
+}
diff --git a/npm/src/deps/deno.land/std@0.213.0/testing/_test_suite.ts b/npm/src/deps/deno.land/std@0.213.0/testing/_test_suite.ts
new file mode 100644
index 0000000..5f177a0
--- /dev/null
+++ b/npm/src/deps/deno.land/std@0.213.0/testing/_test_suite.ts
@@ -0,0 +1,363 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+/** The options for creating a test suite with the describe function. */
+import * as dntShim from "../../../../_dnt.test_shims.js";
+
+export interface DescribeDefinition extends Omit {
+ fn?: () => void;
+ /**
+ * The `describe` function returns a `TestSuite` representing the group of tests.
+ * If `describe` is called within another `describe` calls `fn`, the suite will default to that parent `describe` calls returned `TestSuite`.
+ * If `describe` is not called within another `describe` calls `fn`, the suite will default to the `TestSuite` representing the global group of tests.
+ */
+ suite?: TestSuite;
+ /** Run some shared setup before all of the tests in the suite. */
+ beforeAll?:
+ | ((this: T) => void | Promise)
+ | ((this: T) => void | Promise)[];
+ /** Run some shared teardown after all of the tests in the suite. */
+ afterAll?:
+ | ((this: T) => void | Promise)
+ | ((this: T) => void | Promise)[];
+ /** Run some shared setup before each test in the suite. */
+ beforeEach?:
+ | ((this: T) => void | Promise)
+ | ((this: T) => void | Promise)[];
+ /** Run some shared teardown after each test in the suite. */
+ afterEach?:
+ | ((this: T) => void | Promise)
+ | ((this: T) => void | Promise)[];
+}
+
+/** The options for creating an individual test case with the it function. */
+export interface ItDefinition extends Omit {
+ fn: (this: T, t: dntShim.Deno.TestContext) => void | Promise;
+ /**
+ * The `describe` function returns a `TestSuite` representing the group of tests.
+ * If `it` is called within a `describe` calls `fn`, the suite will default to that parent `describe` calls returned `TestSuite`.
+ * If `it` is not called within a `describe` calls `fn`, the suite will default to the `TestSuite` representing the global group of tests.
+ */
+ suite?: TestSuite;
+}
+
+/** The names of all the different types of hooks. */
+export type HookNames = "beforeAll" | "afterAll" | "beforeEach" | "afterEach";
+
+/** Optional test definition keys. */
+const optionalTestDefinitionKeys: (keyof dntShim.Deno.TestDefinition)[] = [
+ "only",
+ "permissions",
+ "ignore",
+ "sanitizeExit",
+ "sanitizeOps",
+ "sanitizeResources",
+];
+
+/** Optional test step definition keys. */
+const optionalTestStepDefinitionKeys: (keyof dntShim.Deno.TestStepDefinition)[] = [
+ "ignore",
+ "sanitizeExit",
+ "sanitizeOps",
+ "sanitizeResources",
+];
+
+/**
+ * A group of tests.
+ */
+export interface TestSuite {
+ symbol: symbol;
+}
+
+/**
+ * An internal representation of a group of tests.
+ */
+export class TestSuiteInternal implements TestSuite {
+ symbol: symbol;
+ protected describe: DescribeDefinition;
+ protected steps: (TestSuiteInternal | ItDefinition)[];
+ protected hasOnlyStep: boolean;
+
+ constructor(describe: DescribeDefinition) {
+ this.describe = describe;
+ this.steps = [];
+ this.hasOnlyStep = false;
+
+ const { suite } = describe;
+ if (suite && !TestSuiteInternal.suites.has(suite.symbol)) {
+ throw new Error("suite does not represent a registered test suite");
+ }
+ const testSuite = suite
+ ? TestSuiteInternal.suites.get(suite.symbol)
+ : TestSuiteInternal.current;
+ this.symbol = Symbol();
+ TestSuiteInternal.suites.set(this.symbol, this);
+
+ const { fn } = describe;
+ if (fn) {
+ const temp = TestSuiteInternal.current;
+ TestSuiteInternal.current = this;
+ try {
+ fn();
+ } finally {
+ TestSuiteInternal.current = temp;
+ }
+ }
+
+ if (testSuite) {
+ TestSuiteInternal.addStep(testSuite, this);
+ } else {
+ const {
+ name,
+ ignore,
+ permissions,
+ sanitizeExit,
+ sanitizeOps,
+ sanitizeResources,
+ } = describe;
+ let { only } = describe;
+ if (!ignore && this.hasOnlyStep) {
+ only = true;
+ }
+ TestSuiteInternal.registerTest({
+ name,
+ ignore,
+ only,
+ permissions,
+ sanitizeExit,
+ sanitizeOps,
+ sanitizeResources,
+ fn: async (t) => {
+ TestSuiteInternal.runningCount++;
+ try {
+ const context = {} as T;
+ const { beforeAll } = this.describe;
+ if (typeof beforeAll === "function") {
+ await beforeAll.call(context);
+ } else if (beforeAll) {
+ for (const hook of beforeAll) {
+ await hook.call(context);
+ }
+ }
+ try {
+ TestSuiteInternal.active.push(this.symbol);
+ await TestSuiteInternal.run(this, context, t);
+ } finally {
+ TestSuiteInternal.active.pop();
+ const { afterAll } = this.describe;
+ if (typeof afterAll === "function") {
+ await afterAll.call(context);
+ } else if (afterAll) {
+ for (const hook of afterAll) {
+ await hook.call(context);
+ }
+ }
+ }
+ } finally {
+ TestSuiteInternal.runningCount--;
+ }
+ },
+ });
+ }
+ }
+
+ /** Stores how many test suites are executing. */
+ static runningCount = 0;
+
+ /** If a test has been registered yet. Block adding global hooks if a test has been registered. */
+ static started = false;
+
+ /** A map of all test suites by symbol. */
+ // deno-lint-ignore no-explicit-any
+ static suites = new Map>();
+
+ /** The current test suite being registered. */
+ // deno-lint-ignore no-explicit-any
+ static current: TestSuiteInternal | null = null;
+
+ /** The stack of tests that are actively running. */
+ static active: symbol[] = [];
+
+ /** This is used internally for testing this module. */
+ static reset() {
+ TestSuiteInternal.runningCount = 0;
+ TestSuiteInternal.started = false;
+ TestSuiteInternal.current = null;
+ TestSuiteInternal.active = [];
+ }
+
+ /** This is used internally to register tests. */
+ static registerTest(options: dntShim.Deno.TestDefinition) {
+ options = { ...options };
+ optionalTestDefinitionKeys.forEach((key) => {
+ if (typeof options[key] === "undefined") delete options[key];
+ });
+ dntShim.Deno.test(options);
+ }
+
+ /** Updates all steps within top level suite to have ignore set to true if only is not set to true on step. */
+ static addingOnlyStep(suite: TestSuiteInternal) {
+ if (!suite.hasOnlyStep) {
+ for (let i = 0; i < suite.steps.length; i++) {
+ const step = suite.steps[i]!;
+ if (!(step instanceof TestSuiteInternal) && !step.only) {
+ suite.steps.splice(i--, 1);
+ }
+ }
+ suite.hasOnlyStep = true;
+ }
+
+ const parentSuite = suite.describe.suite;
+ const parentTestSuite = parentSuite &&
+ TestSuiteInternal.suites.get(parentSuite.symbol);
+ if (parentTestSuite) {
+ TestSuiteInternal.addingOnlyStep(parentTestSuite);
+ }
+ }
+
+ /** This is used internally to add steps to a test suite. */
+ static addStep(
+ suite: TestSuiteInternal,
+ step: TestSuiteInternal | ItDefinition,
+ ) {
+ if (!suite.hasOnlyStep) {
+ if (step instanceof TestSuiteInternal) {
+ if (step.hasOnlyStep || step.describe.only) {
+ TestSuiteInternal.addingOnlyStep(suite);
+ }
+ } else {
+ if (step.only) TestSuiteInternal.addingOnlyStep(suite);
+ }
+ }
+
+ if (
+ !(suite.hasOnlyStep && !(step instanceof TestSuiteInternal) && !step.only)
+ ) {
+ suite.steps.push(step);
+ }
+ }
+
+ /** This is used internally to add hooks to a test suite. */
+ static setHook(
+ suite: TestSuiteInternal,
+ name: HookNames,
+ fn: (this: T) => void | Promise,
+ ) {
+ if (suite.describe[name]) {
+ if (typeof suite.describe[name] === "function") {
+ suite.describe[name] = [
+ suite.describe[name] as ((this: T) => void | Promise),
+ ];
+ }
+ (suite.describe[name] as ((this: T) => void | Promise)[]).push(fn);
+ } else {
+ suite.describe[name] = fn;
+ }
+ }
+
+ /** This is used internally to run all steps for a test suite. */
+ static async run(
+ suite: TestSuiteInternal,
+ context: T,
+ t: dntShim.Deno.TestContext,
+ ) {
+ const hasOnly = suite.hasOnlyStep || suite.describe.only || false;
+ for (const step of suite.steps) {
+ if (
+ hasOnly && step instanceof TestSuiteInternal &&
+ !(step.hasOnlyStep || step.describe.only || false)
+ ) {
+ continue;
+ }
+
+ const {
+ name,
+ fn,
+ ignore,
+ permissions,
+ sanitizeExit,
+ sanitizeOps,
+ sanitizeResources,
+ } = step instanceof TestSuiteInternal ? step.describe : step;
+
+ const options: dntShim.Deno.TestStepDefinition = {
+ name,
+ ignore,
+ sanitizeExit,
+ sanitizeOps,
+ sanitizeResources,
+ fn: async (t) => {
+ if (permissions) {
+ throw new Error(
+ "permissions option not available for nested tests",
+ );
+ }
+ context = { ...context };
+ if (step instanceof TestSuiteInternal) {
+ const { beforeAll } = step.describe;
+ if (typeof beforeAll === "function") {
+ await beforeAll.call(context);
+ } else if (beforeAll) {
+ for (const hook of beforeAll) {
+ await hook.call(context);
+ }
+ }
+ try {
+ TestSuiteInternal.active.push(step.symbol);
+ await TestSuiteInternal.run(step, context, t);
+ } finally {
+ TestSuiteInternal.active.pop();
+ const { afterAll } = step.describe;
+ if (typeof afterAll === "function") {
+ await afterAll.call(context);
+ } else if (afterAll) {
+ for (const hook of afterAll) {
+ await hook.call(context);
+ }
+ }
+ }
+ } else {
+ await TestSuiteInternal.runTest(t, fn!, context);
+ }
+ },
+ };
+ optionalTestStepDefinitionKeys.forEach((key) => {
+ if (typeof options[key] === "undefined") delete options[key];
+ });
+ await t.step(options);
+ }
+ }
+
+ static async runTest(
+ t: dntShim.Deno.TestContext,
+ fn: (this: T, t: dntShim.Deno.TestContext) => void | Promise,
+ context: T,
+ activeIndex = 0,
+ ) {
+ const suite = TestSuiteInternal.active[activeIndex];
+ const testSuite = suite && TestSuiteInternal.suites.get(suite);
+ if (testSuite) {
+ if (activeIndex === 0) context = { ...context };
+ const { beforeEach } = testSuite.describe;
+ if (typeof beforeEach === "function") {
+ await beforeEach.call(context);
+ } else if (beforeEach) {
+ for (const hook of beforeEach) {
+ await hook.call(context);
+ }
+ }
+ try {
+ await TestSuiteInternal.runTest(t, fn, context, activeIndex + 1);
+ } finally {
+ const { afterEach } = testSuite.describe;
+ if (typeof afterEach === "function") {
+ await afterEach.call(context);
+ } else if (afterEach) {
+ for (const hook of afterEach) {
+ await hook.call(context);
+ }
+ }
+ }
+ } else {
+ await fn.call(context, t);
+ }
+ }
+}
diff --git a/npm/src/deps/deno.land/std@0.213.0/testing/bdd.ts b/npm/src/deps/deno.land/std@0.213.0/testing/bdd.ts
new file mode 100644
index 0000000..6635c28
--- /dev/null
+++ b/npm/src/deps/deno.land/std@0.213.0/testing/bdd.ts
@@ -0,0 +1,821 @@
+// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
+
+/** A [BDD](https://en.wikipedia.org/wiki/Behavior-driven_development) interface
+ * to `Deno.test()` API.
+ *
+ * With the `bdd.ts` module you can write your tests in a familiar format for
+ * grouping tests and adding setup/teardown hooks used by other JavaScript testing
+ * frameworks like Jasmine, Jest, and Mocha.
+ *
+ * The `describe` function creates a block that groups together several related
+ * tests. The `it` function registers an individual test case.
+ *
+ * ## Hooks
+ *
+ * There are 4 types of hooks available for test suites. A test suite can have
+ * multiples of each type of hook, they will be called in the order that they are
+ * registered. The `afterEach` and `afterAll` hooks will be called whether or not
+ * the test case passes. The *All hooks will be called once for the whole group
+ * while the *Each hooks will be called for each individual test case.
+ *
+ * - `beforeAll`: Runs before all of the tests in the test suite.
+ * - `afterAll`: Runs after all of the tests in the test suite finish.
+ * - `beforeEach`: Runs before each of the individual test cases in the test suite.
+ * - `afterEach`: Runs after each of the individual test cases in the test suite.
+ *
+ * If a hook is registered at the top level, a global test suite will be registered
+ * and all tests will belong to it. Hooks registered at the top level must be
+ * registered before any individual test cases or test suites.
+ *
+ * ## Focusing tests
+ *
+ * If you would like to run only specific test cases, you can do so by calling
+ * `it.only` instead of `it`. If you would like to run only specific test suites,
+ * you can do so by calling `describe.only` instead of `describe`.
+ *
+ * There is one limitation to this when using the flat test grouping style. When
+ * `describe` is called without being nested, it registers the test with
+ * `Deno.test`. If a child test case or suite is registered with `it.only` or
+ * `describe.only`, it will be scoped to the top test suite instead of the file. To
+ * make them the only tests that run in the file, you would need to register the
+ * top test suite with `describe.only` too.
+ *
+ * ## Ignoring tests
+ *
+ * If you would like to not run specific individual test cases, you can do so by
+ * calling `it.ignore` instead of `it`. If you would like to not run specific test
+ * suites, you can do so by calling `describe.ignore` instead of `describe`.
+ *
+ * ## Sanitization options
+ *
+ * Like `Deno.TestDefinition`, the `DescribeDefinition` and `ItDefinition` have
+ * sanitization options. They work in the same way.
+ *
+ * - `sanitizeExit`: Ensure the test case does not prematurely cause the process to
+ * exit, for example via a call to Deno.exit. Defaults to true.
+ * - `sanitizeOps`: Check that the number of async completed ops after the test is
+ * the same as number of dispatched ops. Defaults to true.
+ * - `sanitizeResources`: Ensure the test case does not "leak" resources - ie. the
+ * resource table after the test has exactly the same contents as before the
+ * test. Defaults to true.
+ *
+ * ## Permissions option
+ *
+ * Like `Deno.TestDefinition`, the `DescribeDefinition` and `ItDefinition` have a
+ * `permissions` option. They specify the permissions that should be used to run an
+ * individual test case or test suite. Set this to `"inherit"` to keep the calling
+ * thread's permissions. Set this to `"none"` to revoke all permissions.
+ *
+ * This setting defaults to `"inherit"`.
+ *
+ * There is currently one limitation to this, you cannot use the permissions option
+ * on an individual test case or test suite that belongs to another test suite.
+ * That's because internally those tests are registered with `t.step` which does
+ * not support the permissions option.
+ *
+ * ## Comparing to Deno\.test
+ *
+ * The default way of writing tests is using `Deno.test` and `t.step`. The
+ * `describe` and `it` functions have similar call signatures to `Deno.test`,
+ * making it easy to switch between the default style and the behavior-driven
+ * development style of writing tests. Internally, `describe` and `it` are
+ * registering tests with `Deno.test` and `t.step`.
+ *
+ * Below is an example of a test file using `Deno.test` and `t.step`. In the
+ * following sections there are examples of how the same test could be written with
+ * `describe` and `it` using nested test grouping, flat test grouping, or a mix of
+ * both styles.
+ *
+ * ```ts
+ * import {
+ * assertEquals,
+ * assertStrictEquals,
+ * assertThrows,
+ * } from "https://deno.land/std@$STD_VERSION/assert/mod.ts";
+ *
+ * class User {
+ * static users: Map = new Map();
+ * age?: number;
+ *
+ * constructor(public name: string) {
+ * if (User.users.has(name)) {
+ * throw new Deno.errors.AlreadyExists(`User ${name} already exists`);
+ * }
+ * User.users.set(name, this);
+ * }
+ *
+ * getAge(): number {
+ * if (!this.age) {
+ * throw new Error("Age unknown");
+ * }
+ * return this.age;
+ * }
+ *
+ * setAge(age: number) {
+ * this.age = age;
+ * }
+ * }
+ *
+ * Deno.test("User.users initially empty", () => {
+ * assertEquals(User.users.size, 0);
+ * });
+ *
+ * Deno.test("User constructor", () => {
+ * try {
+ * const user = new User("Kyle");
+ * assertEquals(user.name, "Kyle");
+ * assertStrictEquals(User.users.get("Kyle"), user);
+ * } finally {
+ * User.users.clear();
+ * }
+ * });
+ *
+ * Deno.test("User age", async (t) => {
+ * const user = new User("Kyle");
+ *
+ * await t.step("getAge", () => {
+ * assertThrows(() => user.getAge(), Error, "Age unknown");
+ * user.age = 18;
+ * assertEquals(user.getAge(), 18);
+ * });
+ *
+ * await t.step("setAge", () => {
+ * user.setAge(18);
+ * assertEquals(user.getAge(), 18);
+ * });
+ * });
+ * ```
+ *
+ * ### Nested test grouping
+ *
+ * Tests created within the callback of a `describe` function call will belong to
+ * the new test suite it creates. The hooks can be created within it or be added to
+ * the options argument for describe.
+ *
+ * ```ts
+ * import {
+ * assertEquals,
+ * assertStrictEquals,
+ * assertThrows,
+ * } from "https://deno.land/std@$STD_VERSION/assert/mod.ts";
+ * import {
+ * afterEach,
+ * beforeEach,
+ * describe,
+ * it,
+ * } from "https://deno.land/std@$STD_VERSION/testing/bdd.ts";
+ *
+ * class User {
+ * static users: Map = new Map();
+ * age?: number;
+ *
+ * constructor(public name: string) {
+ * if (User.users.has(name)) {
+ * throw new Deno.errors.AlreadyExists(`User ${name} already exists`);
+ * }
+ * User.users.set(name, this);
+ * }
+ *
+ * getAge(): number {
+ * if (!this.age) {
+ * throw new Error("Age unknown");
+ * }
+ * return this.age;
+ * }
+ *
+ * setAge(age: number) {
+ * this.age = age;
+ * }
+ * }
+ *
+ * describe("User", () => {
+ * it("users initially empty", () => {
+ * assertEquals(User.users.size, 0);
+ * });
+ *
+ * it("constructor", () => {
+ * try {
+ * const user = new User("Kyle");
+ * assertEquals(user.name, "Kyle");
+ * assertStrictEquals(User.users.get("Kyle"), user);
+ * } finally {
+ * User.users.clear();
+ * }
+ * });
+ *
+ * describe("age", () => {
+ * let user: User;
+ *
+ * beforeEach(() => {
+ * user = new User("Kyle");
+ * });
+ *
+ * afterEach(() => {
+ * User.users.clear();
+ * });
+ *
+ * it("getAge", function () {
+ * assertThrows(() => user.getAge(), Error, "Age unknown");
+ * user.age = 18;
+ * assertEquals(user.getAge(), 18);
+ * });
+ *
+ * it("setAge", function () {
+ * user.setAge(18);
+ * assertEquals(user.getAge(), 18);
+ * });
+ * });
+ * });
+ * ```
+ *
+ * ### Flat test grouping
+ *
+ * The `describe` function returns a unique symbol that can be used to reference
+ * the test suite for adding tests to it without having to create them within a
+ * callback. The gives you the ability to have test grouping without any extra
+ * indentation in front of the grouped tests.
+ *
+ * ```ts
+ * import {
+ * assertEquals,
+ * assertStrictEquals,
+ * assertThrows,
+ * } from "https://deno.land/std@$STD_VERSION/assert/mod.ts";
+ * import {
+ * describe,
+ * it,
+ * } from "https://deno.land/std@$STD_VERSION/testing/bdd.ts";
+ *
+ * class User {
+ * static users: Map = new Map();
+ * age?: number;
+ *
+ * constructor(public name: string) {
+ * if (User.users.has(name)) {
+ * throw new Deno.errors.AlreadyExists(`User ${name} already exists`);
+ * }
+ * User.users.set(name, this);
+ * }
+ *
+ * getAge(): number {
+ * if (!this.age) {
+ * throw new Error("Age unknown");
+ * }
+ * return this.age;
+ * }
+ *
+ * setAge(age: number) {
+ * this.age = age;
+ * }
+ * }
+ *
+ * const userTests = describe("User");
+ *
+ * it(userTests, "users initially empty", () => {
+ * assertEquals(User.users.size, 0);
+ * });
+ *
+ * it(userTests, "constructor", () => {
+ * try {
+ * const user = new User("Kyle");
+ * assertEquals(user.name, "Kyle");
+ * assertStrictEquals(User.users.get("Kyle"), user);
+ * } finally {
+ * User.users.clear();
+ * }
+ * });
+ *
+ * const ageTests = describe({
+ * name: "age",
+ * suite: userTests,
+ * beforeEach(this: { user: User }) {
+ * this.user = new User("Kyle");
+ * },
+ * afterEach() {
+ * User.users.clear();
+ * },
+ * });
+ *
+ * it(ageTests, "getAge", function () {
+ * const { user } = this;
+ * assertThrows(() => user.getAge(), Error, "Age unknown");
+ * user.age = 18;
+ * assertEquals(user.getAge(), 18);
+ * });
+ *
+ * it(ageTests, "setAge", function () {
+ * const { user } = this;
+ * user.setAge(18);
+ * assertEquals(user.getAge(), 18);
+ * });
+ * ```
+ *
+ * ### Mixed test grouping
+ *
+ * Both nested test grouping and flat test grouping can be used together. This can
+ * be useful if you'd like to create deep groupings without all the extra
+ * indentation in front of each line.
+ *
+ * ```ts
+ * import {
+ * assertEquals,
+ * assertStrictEquals,
+ * assertThrows,
+ * } from "https://deno.land/std@$STD_VERSION/assert/mod.ts";
+ * import {
+ * describe,
+ * it,
+ * } from "https://deno.land/std@$STD_VERSION/testing/bdd.ts";
+ *
+ * class User {
+ * static users: Map = new Map();
+ * age?: number;
+ *
+ * constructor(public name: string) {
+ * if (User.users.has(name)) {
+ * throw new Deno.errors.AlreadyExists(`User ${name} already exists`);
+ * }
+ * User.users.set(name, this);
+ * }
+ *
+ * getAge(): number {
+ * if (!this.age) {
+ * throw new Error("Age unknown");
+ * }
+ * return this.age;
+ * }
+ *
+ * setAge(age: number) {
+ * this.age = age;
+ * }
+ * }
+ *
+ * describe("User", () => {
+ * it("users initially empty", () => {
+ * assertEquals(User.users.size, 0);
+ * });
+ *
+ * it("constructor", () => {
+ * try {
+ * const user = new User("Kyle");
+ * assertEquals(user.name, "Kyle");
+ * assertStrictEquals(User.users.get("Kyle"), user);
+ * } finally {
+ * User.users.clear();
+ * }
+ * });
+ *
+ * const ageTests = describe({
+ * name: "age",
+ * beforeEach(this: { user: User }) {
+ * this.user = new User("Kyle");
+ * },
+ * afterEach() {
+ * User.users.clear();
+ * },
+ * });
+ *
+ * it(ageTests, "getAge", function () {
+ * const { user } = this;
+ * assertThrows(() => user.getAge(), Error, "Age unknown");
+ * user.age = 18;
+ * assertEquals(user.getAge(), 18);
+ * });
+ *
+ * it(ageTests, "setAge", function () {
+ * const { user } = this;
+ * user.setAge(18);
+ * assertEquals(user.getAge(), 18);
+ * });
+ * });
+ * ```
+ *
+ * @module
+ */
+import * as dntShim from "../../../../_dnt.test_shims.js";
+
+
+import {
+ DescribeDefinition,
+ HookNames,
+ ItDefinition,
+ TestSuite,
+ TestSuiteInternal,
+} from "./_test_suite.js";
+export type { DescribeDefinition, ItDefinition, TestSuite };
+
+/** The arguments for an ItFunction. */
+export type ItArgs =
+ | [options: ItDefinition]
+ | [
+ name: string,
+ options: Omit, "name">,
+ ]
+ | [
+ name: string,
+ fn: (this: T, t: dntShim.Deno.TestContext) => void | Promise,
+ ]
+ | [fn: (this: T, t: dntShim.Deno.TestContext) => void | Promise]
+ | [
+ name: string,
+ options: Omit, "fn" | "name">,
+ fn: (this: T, t: dntShim.Deno.TestContext) => void | Promise,
+ ]
+ | [
+ options: Omit, "fn">,
+ fn: (this: T, t: dntShim.Deno.TestContext) => void | Promise,
+ ]
+ | [
+ options: Omit, "fn" | "name">,
+ fn: (this: T, t: dntShim.Deno.TestContext) => void | Promise,
+ ]
+ | [
+ suite: TestSuite,
+ name: string,
+ options: Omit, "name" | "suite">,
+ ]
+ | [
+ suite: TestSuite,
+ name: string,
+ fn: (this: T, t: dntShim.Deno.TestContext) => void | Promise,
+ ]
+ | [
+ suite: TestSuite,
+ fn: (this: T, t: dntShim.Deno.TestContext) => void | Promise,
+ ]
+ | [
+ suite: TestSuite,
+ name: string,
+ options: Omit, "fn" | "name" | "suite">,
+ fn: (this: T, t: dntShim.Deno.TestContext) => void | Promise,
+ ]
+ | [
+ suite: TestSuite,
+ options: Omit, "fn" | "suite">,
+ fn: (this: T, t: dntShim.Deno.TestContext) => void | Promise